/ src / core / splitRules.ts
splitRules.ts
  1  import type {
  2    RepoDriverId,
  3    NftDriverId,
  4    ImmutableSplitsDriverId,
  5    AddressDriverId,
  6    RepoDeadlineDriverId,
  7  } from './types';
  8  
  9  const SPLIT_RULES = Object.freeze([
 10    // Project Rules
 11    {
 12      senderAccountType: 'project',
 13      receiverAccountType: 'address',
 14      relationshipType: 'project_maintainer',
 15    },
 16    {
 17      senderAccountType: 'project',
 18      receiverAccountType: 'project',
 19      relationshipType: 'project_dependency',
 20    },
 21    {
 22      senderAccountType: 'project',
 23      receiverAccountType: 'address',
 24      relationshipType: 'project_dependency',
 25    },
 26    {
 27      senderAccountType: 'project',
 28      receiverAccountType: 'drip_list',
 29      relationshipType: 'project_dependency',
 30    },
 31    {
 32      senderAccountType: 'project',
 33      receiverAccountType: 'linked_identity',
 34      relationshipType: 'project_dependency',
 35    },
 36  
 37    // Drip List Rules
 38    {
 39      senderAccountType: 'drip_list',
 40      receiverAccountType: 'address',
 41      relationshipType: 'drip_list_receiver',
 42    },
 43    {
 44      senderAccountType: 'drip_list',
 45      receiverAccountType: 'drip_list',
 46      relationshipType: 'drip_list_receiver',
 47    },
 48    {
 49      senderAccountType: 'drip_list',
 50      receiverAccountType: 'project',
 51      relationshipType: 'drip_list_receiver',
 52    },
 53    {
 54      senderAccountType: 'drip_list',
 55      receiverAccountType: 'linked_identity',
 56      relationshipType: 'drip_list_receiver',
 57    },
 58  
 59    // Ecosystem Main Account Rules
 60    {
 61      senderAccountType: 'ecosystem_main_account',
 62      receiverAccountType: 'project',
 63      relationshipType: 'ecosystem_receiver',
 64    },
 65    {
 66      senderAccountType: 'ecosystem_main_account',
 67      receiverAccountType: 'linked_identity',
 68      relationshipType: 'ecosystem_receiver',
 69    },
 70    {
 71      senderAccountType: 'ecosystem_main_account',
 72      receiverAccountType: 'sub_list',
 73      relationshipType: 'sub_list_link',
 74    },
 75  
 76    // Sub List Rules
 77    {
 78      senderAccountType: 'sub_list',
 79      receiverAccountType: 'address',
 80      relationshipType: 'sub_list_receiver',
 81    },
 82    {
 83      senderAccountType: 'sub_list',
 84      receiverAccountType: 'drip_list',
 85      relationshipType: 'sub_list_receiver',
 86    },
 87    {
 88      senderAccountType: 'sub_list',
 89      receiverAccountType: 'project',
 90      relationshipType: 'sub_list_receiver',
 91    },
 92    {
 93      senderAccountType: 'sub_list',
 94      receiverAccountType: 'sub_list',
 95      relationshipType: 'sub_list_link',
 96    },
 97    {
 98      senderAccountType: 'sub_list',
 99      receiverAccountType: 'linked_identity',
100      relationshipType: 'sub_list_receiver',
101    },
102  
103    // Linked Identity Rules
104    {
105      senderAccountType: 'linked_identity',
106      receiverAccountType: 'address',
107      relationshipType: 'identity_owner',
108    },
109  ] as const);
110  
111  type EntityIdMap = {
112    project: RepoDriverId;
113    drip_list: NftDriverId;
114    ecosystem_main_account: NftDriverId;
115    sub_list: ImmutableSplitsDriverId;
116    deadline: RepoDeadlineDriverId;
117    address: AddressDriverId;
118    linked_identity: RepoDriverId;
119  };
120  
121  export type RelationshipType = (typeof SPLIT_RULES)[number]['relationshipType'];
122  export type AccountType =
123    | (typeof SPLIT_RULES)[number]['senderAccountType']
124    | (typeof SPLIT_RULES)[number]['receiverAccountType'];
125  
126  type SplitRuleFromRaw<R> = R extends {
127    senderAccountType: infer S extends keyof EntityIdMap;
128    receiverAccountType: infer T extends keyof EntityIdMap;
129    relationshipType: string;
130  }
131    ? {
132        senderAccountType: S;
133        senderAccountId: EntityIdMap[S];
134        receiverAccountType: T;
135        receiverAccountId: EntityIdMap[T];
136        relationshipType: R['relationshipType'];
137      }
138    : never;
139  
140  export type SplitReceiverShape = SplitRuleFromRaw<
141    (typeof SPLIT_RULES)[number]
142  > & {
143    weight: number;
144    blockTimestamp: Date;
145    splitsToRepoDriverSubAccount?: boolean;
146  };
147  
148  export const ACCOUNT_TYPES = Array.from(
149    new Set(
150      SPLIT_RULES.flatMap((rule) => [
151        rule.senderAccountType,
152        rule.receiverAccountType,
153      ]),
154    ),
155  );
156  
157  export const RELATIONSHIP_TYPES = Array.from(
158    new Set(SPLIT_RULES.map((rule) => rule.relationshipType)),
159  ) as (typeof SPLIT_RULES)[number]['relationshipType'][];
160  
161  export const ACCOUNT_TYPE_TO_METADATA_RECEIVER_TYPE: Record<
162    AccountType,
163    string
164  > = {
165    project: 'repoDriver',
166    drip_list: 'dripList',
167    ecosystem_main_account: 'ecosystem',
168    sub_list: 'subList',
169    address: 'address',
170    linked_identity: 'linkedIdentity',
171  };
172  
173  export const METADATA_RECEIVER_TYPE_TO_ACCOUNT_TYPE = Object.fromEntries(
174    Object.entries(ACCOUNT_TYPE_TO_METADATA_RECEIVER_TYPE).map(([key, value]) => [
175      value,
176      key,
177    ]),
178  ) as Record<string, AccountType>;