From 6c7c4c23bc3eb09cff69334ed900353da1bff813 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Tue, 21 May 2024 09:18:12 +0200 Subject: [PATCH 1/4] feat: weekly job to retrieve the current list of ckErc20 --- package-lock.json | 17 +++++---- package.json | 2 +- scripts/build.tokens.ckerc20.mjs | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100755 scripts/build.tokens.ckerc20.mjs diff --git a/package-lock.json b/package-lock.json index d4cfdd5bd2..53350bcdc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@dfinity/auth-client": "^1.3.0", "@dfinity/candid": "^1.3.0", "@dfinity/ckbtc": "^2.3.3", - "@dfinity/cketh": "^3.0.1", + "@dfinity/cketh": "^3.0.1-next-2024-05-21.1", "@dfinity/gix-components": "^4.2.0-next-2024-05-06.2", "@dfinity/ic-management": "^4.0.0", "@dfinity/ledger-icp": "^2.2.4", @@ -660,14 +660,15 @@ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, "node_modules/@dfinity/cketh": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@dfinity/cketh/-/cketh-3.0.1.tgz", - "integrity": "sha512-fk7uAxZQSn1ZTCKsFRlJbrcD1ax6iqxlwgJ5WH/6rk5lsUvM8RRajQ78FIfc6QTjDB6CCNc24Qpm/rjjtHbrSA==", + "version": "3.0.1-next-2024-05-21.1", + "resolved": "https://registry.npmjs.org/@dfinity/cketh/-/cketh-3.0.1-next-2024-05-21.1.tgz", + "integrity": "sha512-Hgxzy80FcR1D2LUmi/mB0xl0B/jdWF8M6Kl7ES/2LuTIRRvcBiRV+v9uiamu3zwMVlG9ESYiOHaKcz6QCpPb2A==", + "license": "Apache-2.0", "peerDependencies": { - "@dfinity/agent": "^1.3.0", - "@dfinity/candid": "^1.3.0", - "@dfinity/principal": "^1.3.0", - "@dfinity/utils": "^2.3.0" + "@dfinity/agent": "*", + "@dfinity/candid": "*", + "@dfinity/principal": "*", + "@dfinity/utils": "*" } }, "node_modules/@dfinity/gix-components": { diff --git a/package.json b/package.json index a8eb9f7f08..95bc5df8b0 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@dfinity/auth-client": "^1.3.0", "@dfinity/candid": "^1.3.0", "@dfinity/ckbtc": "^2.3.3", - "@dfinity/cketh": "^3.0.1", + "@dfinity/cketh": "^3.0.1-next-2024-05-21.1", "@dfinity/gix-components": "^4.2.0-next-2024-05-06.2", "@dfinity/ic-management": "^4.0.0", "@dfinity/ledger-icp": "^2.2.4", diff --git a/scripts/build.tokens.ckerc20.mjs b/scripts/build.tokens.ckerc20.mjs new file mode 100755 index 0000000000..94dc27c2d1 --- /dev/null +++ b/scripts/build.tokens.ckerc20.mjs @@ -0,0 +1,63 @@ +#!/usr/bin/env node + +import { AnonymousIdentity } from '@dfinity/agent'; +import { CkETHOrchestratorCanister } from '@dfinity/cketh'; +import { Principal } from '@dfinity/principal'; +import { createAgent, fromNullable, isNullish } from '@dfinity/utils'; + +const orchestratorInfo = async ({ orchestratorId: canisterId }) => { + const agent = await createAgent({ + identity: new AnonymousIdentity(), + host: 'https://icp-api.io' + }); + + const { getOrchestratorInfo } = CkETHOrchestratorCanister.create({ + agent, + canisterId + }); + + return getOrchestratorInfo({ certified: true }); +}; + +const buildOrchestratorInfo = async (orchestratorId) => { + const { managed_canisters } = await orchestratorInfo({ orchestratorId }); + + const mapManagedCanisters = ({ ledger, index, ckerc20_token_symbol }) => { + const ledgerCanister = fromNullable(ledger); + const indexCanister = fromNullable(index); + + if (isNullish(ledgerCanister) || isNullish(indexCanister)) { + return undefined; + } + + const { canister_id: ledgerCanisterId } = + 'Created' in ledgerCanister ? ledgerCanister.Created : ledgerCanister.Installed; + const { canister_id: indexCanisterId } = + 'Created' in indexCanister ? indexCanister.Created : indexCanister.Installed; + + return { + ledgerCanisterId: ledgerCanisterId.toText(), + indexCanisterId: indexCanisterId.toText(), + ckerc20_token_symbol + }; + }; + + return managed_canisters.map(mapManagedCanisters); +}; + +const ORCHESTRATOR_STAGING_ID = Principal.fromText('2s5qh-7aaaa-aaaar-qadya-cai'); +const ORCHESTRATOR_PRODUCTION_ID = Principal.fromText('vxkom-oyaaa-aaaar-qafda-cai'); + +const findCkErc20 = async () => { + const [staging, production] = await Promise.all( + [ORCHESTRATOR_STAGING_ID, ORCHESTRATOR_PRODUCTION_ID].map(buildOrchestratorInfo) + ); + + console.log(staging, production); +}; + +try { + await findCkErc20(); +} catch (err) { + console.error(err); +} From e2ea13237366efcef6bcf73e0fbd2c8a84f5da07 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Tue, 21 May 2024 10:00:18 +0200 Subject: [PATCH 2/4] build: update next after pr merged --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53350bcdc4..4e027efd92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@dfinity/auth-client": "^1.3.0", "@dfinity/candid": "^1.3.0", "@dfinity/ckbtc": "^2.3.3", - "@dfinity/cketh": "^3.0.1-next-2024-05-21.1", + "@dfinity/cketh": "^3.0.1-next-2024-05-21.2", "@dfinity/gix-components": "^4.2.0-next-2024-05-06.2", "@dfinity/ic-management": "^4.0.0", "@dfinity/ledger-icp": "^2.2.4", @@ -660,9 +660,9 @@ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, "node_modules/@dfinity/cketh": { - "version": "3.0.1-next-2024-05-21.1", - "resolved": "https://registry.npmjs.org/@dfinity/cketh/-/cketh-3.0.1-next-2024-05-21.1.tgz", - "integrity": "sha512-Hgxzy80FcR1D2LUmi/mB0xl0B/jdWF8M6Kl7ES/2LuTIRRvcBiRV+v9uiamu3zwMVlG9ESYiOHaKcz6QCpPb2A==", + "version": "3.0.1-next-2024-05-21.2", + "resolved": "https://registry.npmjs.org/@dfinity/cketh/-/cketh-3.0.1-next-2024-05-21.2.tgz", + "integrity": "sha512-WeZK8KJzb/08k/TNKB/eDMCqDg0jPYfcVfSJnyn/9BjUDQG7q9PeBshflYygyEd7bngV6E9uS4D+MhxbT1Omew==", "license": "Apache-2.0", "peerDependencies": { "@dfinity/agent": "*", diff --git a/package.json b/package.json index 95bc5df8b0..91e43b3c9b 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@dfinity/auth-client": "^1.3.0", "@dfinity/candid": "^1.3.0", "@dfinity/ckbtc": "^2.3.3", - "@dfinity/cketh": "^3.0.1-next-2024-05-21.1", + "@dfinity/cketh": "^3.0.1-next-2024-05-21.2", "@dfinity/gix-components": "^4.2.0-next-2024-05-06.2", "@dfinity/ic-management": "^4.0.0", "@dfinity/ledger-icp": "^2.2.4", From 4c785ef896b173e1ea517fa763d7c9b9b2e70467 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Tue, 21 May 2024 13:42:16 +0200 Subject: [PATCH 3/4] feat: generate tokens.ckerc20.json --- .prettierignore | 3 +- scripts/build.tokens.ckerc20.mjs | 44 ++++++++++++++++++++---- src/frontend/src/env/tokens.ckerc20.json | 1 + 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/frontend/src/env/tokens.ckerc20.json diff --git a/.prettierignore b/.prettierignore index d921c227a8..fb4b014739 100644 --- a/.prettierignore +++ b/.prettierignore @@ -16,4 +16,5 @@ yarn.lock .dfx -src/frontend/src/env/tokens.sns.json \ No newline at end of file +src/frontend/src/env/tokens.sns.json +src/frontend/src/env/tokens.ckerc20.json \ No newline at end of file diff --git a/scripts/build.tokens.ckerc20.mjs b/scripts/build.tokens.ckerc20.mjs index 94dc27c2d1..0904e7fa51 100755 --- a/scripts/build.tokens.ckerc20.mjs +++ b/scripts/build.tokens.ckerc20.mjs @@ -3,7 +3,9 @@ import { AnonymousIdentity } from '@dfinity/agent'; import { CkETHOrchestratorCanister } from '@dfinity/cketh'; import { Principal } from '@dfinity/principal'; -import { createAgent, fromNullable, isNullish } from '@dfinity/utils'; +import { createAgent, fromNullable, isNullish, jsonReplacer } from '@dfinity/utils'; +import { writeFileSync } from 'node:fs'; +import { join } from 'node:path'; const orchestratorInfo = async ({ orchestratorId: canisterId }) => { const agent = await createAgent({ @@ -22,7 +24,7 @@ const orchestratorInfo = async ({ orchestratorId: canisterId }) => { const buildOrchestratorInfo = async (orchestratorId) => { const { managed_canisters } = await orchestratorInfo({ orchestratorId }); - const mapManagedCanisters = ({ ledger, index, ckerc20_token_symbol }) => { + const mapManagedCanisters = (acc, { ledger, index, ckerc20_token_symbol }) => { const ledgerCanister = fromNullable(ledger); const indexCanister = fromNullable(index); @@ -36,24 +38,52 @@ const buildOrchestratorInfo = async (orchestratorId) => { 'Created' in indexCanister ? indexCanister.Created : indexCanister.Installed; return { - ledgerCanisterId: ledgerCanisterId.toText(), - indexCanisterId: indexCanisterId.toText(), - ckerc20_token_symbol + ...acc, + [ckerc20_token_symbol]: [ + ...(acc[ckerc20_token_symbol] ?? []), + { + ledgerCanisterId: ledgerCanisterId.toText(), + indexCanisterId: indexCanisterId.toText() + } + ] }; }; - return managed_canisters.map(mapManagedCanisters); + const tokens = managed_canisters.reduce(mapManagedCanisters, {}); + + const assertUniqueTokenSymbol = Object.values(tokens).find((value) => value.length > 1); + + if (assertUniqueTokenSymbol !== undefined) { + throw new Error( + `More than one pair of ledger and index canisters were used for the token symbol ${assertUniqueTokenSymbol}.` + ); + } + + return Object.entries(tokens).reduce( + (acc, [key, value]) => ({ + ...acc, + [key]: value[0] + }), + {} + ); }; const ORCHESTRATOR_STAGING_ID = Principal.fromText('2s5qh-7aaaa-aaaar-qadya-cai'); const ORCHESTRATOR_PRODUCTION_ID = Principal.fromText('vxkom-oyaaa-aaaar-qafda-cai'); +const DATA_FOLDER = join(process.cwd(), 'src', 'frontend', 'src', 'env'); + const findCkErc20 = async () => { const [staging, production] = await Promise.all( [ORCHESTRATOR_STAGING_ID, ORCHESTRATOR_PRODUCTION_ID].map(buildOrchestratorInfo) ); - console.log(staging, production); + const tokens = { + production, + staging + }; + + writeFileSync(join(DATA_FOLDER, 'tokens.ckerc20.json'), JSON.stringify(tokens, jsonReplacer)); }; try { diff --git a/src/frontend/src/env/tokens.ckerc20.json b/src/frontend/src/env/tokens.ckerc20.json new file mode 100644 index 0000000000..f54e502800 --- /dev/null +++ b/src/frontend/src/env/tokens.ckerc20.json @@ -0,0 +1 @@ +{"production":{},"staging":{"ckSepoliaUSDC":{"ledgerCanisterId":"yfumr-cyaaa-aaaar-qaela-cai","indexCanisterId":"ycvkf-paaaa-aaaar-qaelq-cai"}}} \ No newline at end of file From 461fc4f099fb07595263a086fd2bb95e8f47ba36 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Tue, 21 May 2024 14:20:38 +0200 Subject: [PATCH 4/4] fix: return acc instead of undefined to continue reduce --- scripts/build.tokens.ckerc20.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build.tokens.ckerc20.mjs b/scripts/build.tokens.ckerc20.mjs index 0904e7fa51..4bb0220f5c 100755 --- a/scripts/build.tokens.ckerc20.mjs +++ b/scripts/build.tokens.ckerc20.mjs @@ -28,8 +28,9 @@ const buildOrchestratorInfo = async (orchestratorId) => { const ledgerCanister = fromNullable(ledger); const indexCanister = fromNullable(index); + // Skip tokens without Ledger or Index (by definition, this can happen). if (isNullish(ledgerCanister) || isNullish(indexCanister)) { - return undefined; + return acc; } const { canister_id: ledgerCanisterId } =