diff --git a/src/getNetwork.ts b/src/getNetwork.ts index 71391a5..3d349e6 100644 --- a/src/getNetwork.ts +++ b/src/getNetwork.ts @@ -11,7 +11,7 @@ export default function getNetwork(chain: ChainId): Network { symbol: 'ETH', contracts: { drips: '0xd0Dd053392db676D57317CD4fe96Fc2cCf42D0b4', - repoSubAccountDriver: '0x0000000000000000000000000000000000000000', + repoSubAccountDriver: '0xc219395880fa72e3ad9180b8878e0d39d144130b', }, }; case 11155111: @@ -21,7 +21,7 @@ export default function getNetwork(chain: ChainId): Network { symbol: 'SepoliaETH', contracts: { drips: '0x74A32a38D945b9527524900429b083547DeB9bF4', - repoSubAccountDriver: '0x0000000000000000000000000000000000000000', + repoSubAccountDriver: '0x317400fd9dfdad78d53a34455d89beb8f03f90ee', }, }; case 314: @@ -31,7 +31,7 @@ export default function getNetwork(chain: ChainId): Network { symbol: 'FIL', contracts: { drips: '0xd320F59F109c618b19707ea5C5F068020eA333B3', - repoSubAccountDriver: '0x0000000000000000000000000000000000000000', + repoSubAccountDriver: '0x925a69f6d07ee4c753df139bcc2a946e1d1ee92a', }, }; case 1088: @@ -41,7 +41,7 @@ export default function getNetwork(chain: ChainId): Network { symbol: 'METIS', contracts: { drips: '0xd320F59F109c618b19707ea5C5F068020eA333B3', - repoSubAccountDriver: '0x0000000000000000000000000000000000000000', + repoSubAccountDriver: '0x925a69f6d07ee4c753df139bcc2a946e1d1ee92a', }, }; case 10: @@ -51,7 +51,7 @@ export default function getNetwork(chain: ChainId): Network { symbol: 'ETH', contracts: { drips: '0xd320F59F109c618b19707ea5C5F068020eA333B3', - repoSubAccountDriver: '0x0000000000000000000000000000000000000000', + repoSubAccountDriver: '0x925a69f6d07ee4c753df139bcc2a946e1d1ee92a', }, }; case 31337: diff --git a/src/index.ts b/src/index.ts index a51efea..3db2562 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,6 +15,7 @@ import { } from './types'; import {notifyDiscord} from './notifyDiscord'; import {getAllProjectsAndSubProjectSortedByCreationDate} from './queries/getAllProjectsSortedByCreationDate'; +import {getAllOrcidAccountsWithSplits} from './queries/getAllOrcidAccountsWithSplits'; const MAX_CYCLES = 1000; const SCRIPT_ITERATIONS = 3; @@ -81,10 +82,12 @@ async function main(): Promise { const dripListsResult = await processDripLists(db, tokens); const projectsResult = await processProjects(db, tokens); + const orcidResult = await processOrcidAccounts(db, tokens); allWriteOperations.push( ...dripListsResult.writeOperations, ...projectsResult.writeOperations, + ...orcidResult.writeOperations, ); console.log( @@ -155,11 +158,7 @@ async function processDripLists( continue; // Skip to the next drip list } - const splitsReceivers = await getCurrentSplitsReceivers( - db, - dripListId, - 'dripList', - ); + const splitsReceivers = await getCurrentSplitsReceivers(db, dripListId); for (const token of tokens) { const result = await processToken( @@ -192,11 +191,7 @@ async function processProjects( continue; // Skip to the next project } - const splitsReceivers = await getCurrentSplitsReceivers( - db, - projectId, - 'project', - ); + const splitsReceivers = await getCurrentSplitsReceivers(db, projectId); const weightsAreCorrect = await checkTotalWeight( splitsReceivers, @@ -231,11 +226,63 @@ async function processProjects( return {writeOperations}; } +async function processOrcidAccounts( + db: Client, + tokens: OxString[], +): Promise { + console.log('\nProcessing ORCID accounts...'); + const writeOperations: WriteOperation[] = []; + + const orcidRows = await getAllOrcidAccountsWithSplits(db); + + console.log(`Found ${orcidRows.length} ORCID accounts to process`); + + for (const row of orcidRows) { + const accountIdStr = row.accountId.toString(); + + if (appSettings.accountIdsToSkip.includes(accountIdStr)) { + console.log( + `Skipping ORCID Account ${accountIdStr} as per ACCOUNT_IDS_TO_SKIP.`, + ); + continue; + } + + // Validate that ORCID account splits 100% to owner + if (row.receiverAccountId !== row.ownerAccountId || row.weight !== 1_000_000) { + const message = `ORCID Validation Error: Account ${accountIdStr} doesn't split 100% to owner. Expected receiver: ${row.ownerAccountId}, got: ${row.receiverAccountId}. Expected weight: 1000000, got: ${row.weight}`; + console.warn(message); + await notifyDiscord(`⚠️ ${message}`); + continue; + } + + // Create splits receiver configuration (100% to owner) + const splitsReceivers: SplitsReceiver[] = [ + { + accountId: row.receiverAccountId, + weight: row.weight, + }, + ]; + + for (const token of tokens) { + const result = await processToken( + row.accountId, + token, + splitsReceivers, + 'orcidAccount', + ); + writeOperations.push(...result.writeOperations); + } + } + + console.log('Completed processing ORCID accounts'); + return {writeOperations}; +} + async function processToken( accountId: bigint, token: string, splitsReceivers: SplitsReceiver[], - type: 'dripList' | 'project', + type: 'dripList' | 'project' | 'orcidAccount', ): Promise { const writeOperations: WriteOperation[] = []; const entityDescription = `${type} ${accountId}`; @@ -284,7 +331,7 @@ async function processToken( } } -const splittable = await dripsReadContract({ + const splittable = await dripsReadContract({ functionName: 'splittable', args: [accountId, token as OxString], }); diff --git a/src/queries/getAllDripListsSortedByCreationDate.ts b/src/queries/getAllDripListsSortedByCreationDate.ts index 6a23291..baf55e5 100644 --- a/src/queries/getAllDripListsSortedByCreationDate.ts +++ b/src/queries/getAllDripListsSortedByCreationDate.ts @@ -10,6 +10,11 @@ export async function getAllDripListsSortedByCreationDate(db: Client) { id: bigint; createdAt: Date; }>({ - text: `SELECT * FROM ${dbSchema}."drip_lists" ORDER BY "created_at" DESC`, + text: ` + SELECT + dl.account_id as "id", + dl.created_at as "createdAt" + FROM ${dbSchema}."drip_lists" dl + ORDER BY "created_at" DESC`, }); } diff --git a/src/queries/getAllOrcidAccountsWithSplits.ts b/src/queries/getAllOrcidAccountsWithSplits.ts new file mode 100644 index 0000000..f5c1120 --- /dev/null +++ b/src/queries/getAllOrcidAccountsWithSplits.ts @@ -0,0 +1,49 @@ +import {Client} from 'pg'; +import appSettings from '../appSettings'; +import type {OxString} from '../types'; + +const { + network: {name: dbSchema}, +} = appSettings; + +export type OrcidAccountRow = { + accountId: bigint; + ownerAddress: OxString; + ownerAccountId: bigint; + isLinked: boolean; + identityType: string; + receiverAccountId: bigint; + weight: number; +}; + +export async function getAllOrcidAccountsWithSplits( + db: Client, +): Promise { + const query = ` + SELECT + li.account_id as "accountId", + li.owner_address as "ownerAddress", + li.owner_account_id as "ownerAccountId", + li.is_linked as "isLinked", + li.identity_type as "identityType", + sr.receiver_account_id as "receiverAccountId", + sr.weight as "weight" + FROM ${dbSchema}.linked_identities li + INNER JOIN ${dbSchema}.splits_receivers sr ON li.account_id = sr.sender_account_id + WHERE li.identity_type = 'orcid' + AND li.is_linked = true + ORDER BY li.account_id + `; + + const result = await db.query(query); + + return result.rows.map(row => ({ + accountId: BigInt(row.accountId), + ownerAddress: row.ownerAddress as OxString, + ownerAccountId: BigInt(row.ownerAccountId), + isLinked: row.isLinked, + identityType: row.identityType, + receiverAccountId: BigInt(row.receiverAccountId), + weight: row.weight, + })); +} diff --git a/src/queries/getAllProjectsSortedByCreationDate.ts b/src/queries/getAllProjectsSortedByCreationDate.ts index e3a31eb..ebc3278 100644 --- a/src/queries/getAllProjectsSortedByCreationDate.ts +++ b/src/queries/getAllProjectsSortedByCreationDate.ts @@ -15,7 +15,12 @@ export async function getAllProjectsAndSubProjectSortedByCreationDate( id: bigint; createdAt: Date; }>({ - text: `SELECT * FROM ${dbSchema}.projects WHERE "verification_status" = 'claimed' ORDER BY "created_at" DESC`, + text: ` + SELECT + p."account_id" as "id", + p."created_at" as "createdAt" + FROM ${dbSchema}.projects p + WHERE "verification_status" = 'claimed' ORDER BY "created_at" DESC`, }) ).rows; diff --git a/src/queries/getCurrentSplitsReceivers.ts b/src/queries/getCurrentSplitsReceivers.ts index b7b32ff..5b94443 100644 --- a/src/queries/getCurrentSplitsReceivers.ts +++ b/src/queries/getCurrentSplitsReceivers.ts @@ -8,28 +8,25 @@ const { } = appSettings; type SplitRow = { - fundeeAccountId?: string; - fundeeDripListId?: string; - fundeeProjectId?: string; - weight: bigint; + receiver_account_id: string; + weight: number; }; export default async function getCurrentSplitsReceivers( db: Client, accountId: string, - type: 'dripList' | 'project', ): Promise { const {rows: splits} = await db.query({ - text: `SELECT * FROM "${dbSchema}"."splits_receivers" WHERE sender_account_id = $1`, + text: `SELECT receiver_account_id, weight FROM "${dbSchema}"."splits_receivers" WHERE sender_account_id = $1`, values: [accountId], }); - const splitsReceivers = sortSplitsReceivers([ - ...splits.map(({fundeeProjectId, weight}) => ({ - accountId: BigInt(fundeeProjectId!), - weight: Number(weight), + const splitsReceivers = sortSplitsReceivers( + splits.map(row => ({ + accountId: BigInt(row.receiver_account_id), + weight: row.weight, })), - ]); + ); return splitsReceivers; }