From 9255b80a34095f5fc848ac78f7af99de81bddde5 Mon Sep 17 00:00:00 2001 From: Koinzell Date: Wed, 21 Jun 2023 15:34:22 -0500 Subject: [PATCH 1/8] add optimism goerli configuration --- config/example.env | 4 +++- config/test.env | 2 ++ src/provider.ts | 18 ++++++++++++++++++ src/resolvers/donationResolver.test.ts | 2 +- src/server/adminJs/tabs/tokenTab.ts | 1 + 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/config/example.env b/config/example.env index 2f5a9f3cc..512476665 100644 --- a/config/example.env +++ b/config/example.env @@ -28,6 +28,8 @@ XDAI_NODE_HTTP_URL=https://xxxxxx.xdai.quiknode.pro/ ETHERSCAN_MAINNET_API_URL=https://api.etherscan.io/api ETHERSCAN_ROPSTEN_API_URL=https://api-ropsten.etherscan.io/api ETHERSCAN_GOERLI_API_URL=https://api-goerli.etherscan.io/api +OPTIMISM_GOERLI_SCAN_API_URL=https://api.polygonscan.com/api +OPTIMISM_GOERLI_SCAN_API_KEY=0000000000000000000000000000000000 POLYGON_SCAN_API_URL=https://api.polygonscan.com/api POLYGON_SCAN_API_KEY=0000000000000000000000000000000000 OPTIMISTIC_SCAN_API_URL=https://api-optimistic.etherscan.io/api @@ -181,7 +183,7 @@ DONATION_VERIFICAITON_EXPIRATION_HOURS=24 # Default: unnamed SERVICE_NAME=example OPTIMISM_NODE_HTTP_URL=https://optimism-mainnet.public.blastapi.io/ - +OPTIMISM_GOERLI_NODE_HTTP_URL= ####################################### INSTANT BOOSTING ################################# # OPTIONAL - default: false diff --git a/config/test.env b/config/test.env index 75a9454ea..b56f051ac 100644 --- a/config/test.env +++ b/config/test.env @@ -169,5 +169,7 @@ DONATION_VERIFICAITON_EXPIRATION_HOURS=24 # We need it for monoswap POLYGON_MAINNET_NODE_HTTP_URL=https://polygon-rpc.com OPTIMISM_NODE_HTTP_URL=https://optimism-mainnet.public.blastapi.io +OPTIMISM_GOERLI_NODE_HTTP_URL=https://optimism-goerli.public.blastapi.io + GITCOIN_ADAPTER=mock \ No newline at end of file diff --git a/src/provider.ts b/src/provider.ts index d6fc9e621..a7d1e7209 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -12,6 +12,7 @@ export const NETWORK_IDS = { XDAI: 100, POLYGON: 137, OPTIMISTIC: 10, + OPTIMISM_GOERLI: 420, BSC: 56, CELO: 42220, CELO_ALFAJORES: 44787, @@ -27,6 +28,7 @@ export const NETWORKS_IDS_TO_NAME = { 42220: 'CELO', 44787: 'CELO_ALFAJORES', 10: 'OPTIMISTIC', + 420: 'OPTIMISM_GOERLI', }; const NETWORK_NAMES = { @@ -37,6 +39,7 @@ const NETWORK_NAMES = { GOERLI: 'goerli', POLYGON: 'polygon-mainnet', OPTIMISTIC: 'optimistic-mainnet', + OPTIMISM_GOERLI: 'optimism-goerli-testnet', CELO: 'Celo', CELO_ALFAJORES: 'Celo Alfajores', }; @@ -49,6 +52,7 @@ const NETWORK_NATIVE_TOKENS = { GOERLI: 'ETH', POLYGON: 'MATIC', OPTIMISTIC: 'ETH', + OPTIMISM_GOERLI: 'ETH', CELO: 'CELO', CELO_ALFAJORES: 'CELO', }; @@ -89,6 +93,11 @@ const networkNativeTokensList = [ networkId: NETWORK_IDS.OPTIMISTIC, nativeToken: NETWORK_NATIVE_TOKENS.OPTIMISTIC, }, + { + networkName: NETWORK_NAMES.OPTIMISM_GOERLI, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + nativeToken: NETWORK_NATIVE_TOKENS.OPTIMISM_GOERLI, + }, { networkName: NETWORK_NAMES.CELO, networkId: NETWORK_IDS.CELO, @@ -142,6 +151,11 @@ export function getProvider(networkId: number) { `https://celo-alfajores.infura.io/v3/${INFURA_ID}`; break; + case NETWORK_IDS.OPTIMISM_GOERLI: + url = config.get('OPTIMISM_GOERLI_NODE_HTTP_URL') as string; + `https://optimism-goerli.public.blastapi.io/v3/${INFURA_ID}`; + break; + default: { // Use infura const connectionInfo = ethers.providers.InfuraProvider.getUrl( @@ -203,6 +217,10 @@ export function getBlockExplorerApiUrl(networkId: number): string { apiUrl = config.get('OPTIMISTIC_SCAN_API_URL'); apiKey = config.get('OPTIMISTIC_SCAN_API_KEY'); break; + case NETWORK_IDS.OPTIMISM_GOERLI: + apiUrl = config.get('OPTIMISTIC_SCAN_API_URL'); + apiKey = config.get('OPTIMISTIC_SCAN_API_KEY'); + break; default: throw new Error(i18n.__(translationErrorMessagesKeys.INVALID_NETWORK_ID)); } diff --git a/src/resolvers/donationResolver.test.ts b/src/resolvers/donationResolver.test.ts index c962cfe2c..a5942e9f0 100644 --- a/src/resolvers/donationResolver.test.ts +++ b/src/resolvers/donationResolver.test.ts @@ -1731,7 +1731,7 @@ function createDonationTestCases() { ); assert.equal( saveDonationResponse.data.errors[0].message, - '"transactionNetworkId" must be one of [1, 3, 5, 100, 137, 10, 56, 42220, 44787]', + '"transactionNetworkId" must be one of [1, 3, 5, 100, 137, 10, 56, 42220, 44787, 420]', ); }); it('should throw exception when currency is not valid when currency contain characters', async () => { diff --git a/src/server/adminJs/tabs/tokenTab.ts b/src/server/adminJs/tabs/tokenTab.ts index 90f2050a4..b847e5347 100644 --- a/src/server/adminJs/tabs/tokenTab.ts +++ b/src/server/adminJs/tabs/tokenTab.ts @@ -184,6 +184,7 @@ export const generateTokenTab = async () => { { value: NETWORK_IDS.GOERLI, label: 'GOERLI' }, { value: NETWORK_IDS.POLYGON, label: 'POLYGON' }, { value: NETWORK_IDS.OPTIMISTIC, label: 'OPTIMISTIC' }, + { value: NETWORK_IDS.OPTIMISM_GOERLI, label: 'OPTIMISM GOERLI' }, { value: NETWORK_IDS.CELO, label: 'CELO' }, { value: NETWORK_IDS.CELO_ALFAJORES, From 8201bd0ca1e27e826094db5029263af4a9f3c7b1 Mon Sep 17 00:00:00 2001 From: Koinzell Date: Wed, 21 Jun 2023 17:28:36 -0500 Subject: [PATCH 2/8] add optimism goerli tokens --- .../1687383705794-AddOptimismGoerliTokens.ts | 57 +++++++++++++++++++ migration/data/seedTokens.ts | 30 ++++++++++ src/resolvers/donationResolver.ts | 20 +++++-- .../validators/graphqlQueryValidators.ts | 1 + 4 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 migration/1687383705794-AddOptimismGoerliTokens.ts diff --git a/migration/1687383705794-AddOptimismGoerliTokens.ts b/migration/1687383705794-AddOptimismGoerliTokens.ts new file mode 100644 index 000000000..e22b4c185 --- /dev/null +++ b/migration/1687383705794-AddOptimismGoerliTokens.ts @@ -0,0 +1,57 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; +import { Token } from '../src/entities/token'; +import seedTokens from './data/seedTokens'; +import { NETWORK_IDS } from '../src/provider'; + +export class AddOptimismGoerliTokens1687383705794 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.manager.save( + Token, + seedTokens + .filter(token => token.networkId === NETWORK_IDS.OPTIMISM_GOERLI) + .map(t => { + t.address = t.address?.toLowerCase(); + return t; + }), + ); + const tokens = await queryRunner.query(` + SELECT * FROM token + WHERE "networkId" = ${NETWORK_IDS.OPTIMISM_GOERLI} + `); + const givethOrganization = ( + await queryRunner.query(`SELECT * FROM organization + WHERE label='giveth'`) + )[0]; + const traceOrganization = ( + await queryRunner.query(`SELECT * FROM organization + WHERE label='trace'`) + )[0]; + + for (const token of tokens) { + await queryRunner.query(`INSERT INTO organization_tokens_token ("tokenId","organizationId") VALUES + (${token.id}, ${givethOrganization.id}), + (${token.id}, ${traceOrganization.id}) + ;`); + } + } + + public async down(queryRunner: QueryRunner): Promise { + const tokens = await queryRunner.query(` + SELECT * FROM token + WHERE "networkId" = ${NETWORK_IDS.OPTIMISM_GOERLI} + `); + await queryRunner.query( + `DELETE FROM organization_tokens_token WHERE "tokenId" IN (${tokens + .map(token => token.id) + .join(',')})`, + ); + await queryRunner.query( + ` + DELETE from token + WHERE "networkId" = ${NETWORK_IDS.OPTIMISM_GOERLI} + `, + ); + } +} diff --git a/migration/data/seedTokens.ts b/migration/data/seedTokens.ts index 2c7d58197..4ff1dc521 100644 --- a/migration/data/seedTokens.ts +++ b/migration/data/seedTokens.ts @@ -1045,6 +1045,36 @@ const seedTokens: ITokenData[] = [ networkId: NETWORK_IDS.POLYGON, }, + // OPTIMISM Goerli tokens + { + name: 'OPTIMISM Goerli native token', + symbol: 'ETH', + address: '0x0000000000000000000000000000000000000000', + decimals: 18, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + }, + { + name: 'OPTIMISM Goerli OP token', + symbol: 'OP', + address: '0x4200000000000000000000000000000000000042', + decimals: 18, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + }, + { + name: 'Wrapped Ether', + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006', + decimals: 18, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + }, + { + name: 'Dai', + symbol: 'DAI', + address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + decimals: 18, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + }, + // OPTIMISTIC tokens { name: 'OPTIMISTIC native token', diff --git a/src/resolvers/donationResolver.ts b/src/resolvers/donationResolver.ts index 6f6bb1487..b610e8921 100644 --- a/src/resolvers/donationResolver.ts +++ b/src/resolvers/donationResolver.ts @@ -588,11 +588,21 @@ export class DonationResolver { createDonationQueryValidator, ); - const priceChainId = - transactionNetworkId === NETWORK_IDS.ROPSTEN || - transactionNetworkId === NETWORK_IDS.GOERLI - ? NETWORK_IDS.MAIN_NET - : transactionNetworkId; + let priceChainId: number; + switch (transactionNetworkId) { + case NETWORK_IDS.ROPSTEN: + priceChainId = NETWORK_IDS.MAIN_NET; + break; + case NETWORK_IDS.GOERLI: + priceChainId = NETWORK_IDS.MAIN_NET; + break; + case NETWORK_IDS.OPTIMISM_GOERLI: + priceChainId = NETWORK_IDS.OPTIMISTIC; + break; + default: + priceChainId = transactionNetworkId; + break; + } const project = await findProjectById(projectId); diff --git a/src/utils/validators/graphqlQueryValidators.ts b/src/utils/validators/graphqlQueryValidators.ts index e5f602f8c..982ababa8 100644 --- a/src/utils/validators/graphqlQueryValidators.ts +++ b/src/utils/validators/graphqlQueryValidators.ts @@ -163,6 +163,7 @@ const managingFundsValidator = Joi.object({ NETWORK_IDS.CELO, NETWORK_IDS.CELO_ALFAJORES, NETWORK_IDS.OPTIMISTIC, + NETWORK_IDS.OPTIMISM_GOERLI, NETWORK_IDS.XDAI, ), }), From 710a5c95e999d9aa80868204b398e642cef3f6d1 Mon Sep 17 00:00:00 2001 From: Koinzell Date: Wed, 21 Jun 2023 22:49:38 -0500 Subject: [PATCH 3/8] update tests and env vars for optimism goerli --- config/example.env | 2 -- src/provider.ts | 3 +- src/resolvers/donationResolver.test.ts | 2 +- src/services/donationService.test.ts | 44 ++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/config/example.env b/config/example.env index 512476665..ae6a24599 100644 --- a/config/example.env +++ b/config/example.env @@ -28,8 +28,6 @@ XDAI_NODE_HTTP_URL=https://xxxxxx.xdai.quiknode.pro/ ETHERSCAN_MAINNET_API_URL=https://api.etherscan.io/api ETHERSCAN_ROPSTEN_API_URL=https://api-ropsten.etherscan.io/api ETHERSCAN_GOERLI_API_URL=https://api-goerli.etherscan.io/api -OPTIMISM_GOERLI_SCAN_API_URL=https://api.polygonscan.com/api -OPTIMISM_GOERLI_SCAN_API_KEY=0000000000000000000000000000000000 POLYGON_SCAN_API_URL=https://api.polygonscan.com/api POLYGON_SCAN_API_KEY=0000000000000000000000000000000000 OPTIMISTIC_SCAN_API_URL=https://api-optimistic.etherscan.io/api diff --git a/src/provider.ts b/src/provider.ts index a7d1e7209..c8b5afe62 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -152,8 +152,7 @@ export function getProvider(networkId: number) { break; case NETWORK_IDS.OPTIMISM_GOERLI: - url = config.get('OPTIMISM_GOERLI_NODE_HTTP_URL') as string; - `https://optimism-goerli.public.blastapi.io/v3/${INFURA_ID}`; + url = `https://optimism-goerli.public.blastapi.io/v3/${INFURA_ID}`; break; default: { diff --git a/src/resolvers/donationResolver.test.ts b/src/resolvers/donationResolver.test.ts index a5942e9f0..1b97c87b9 100644 --- a/src/resolvers/donationResolver.test.ts +++ b/src/resolvers/donationResolver.test.ts @@ -1731,7 +1731,7 @@ function createDonationTestCases() { ); assert.equal( saveDonationResponse.data.errors[0].message, - '"transactionNetworkId" must be one of [1, 3, 5, 100, 137, 10, 56, 42220, 44787, 420]', + '"transactionNetworkId" must be one of [1, 3, 5, 100, 137, 10, 420, 56, 42220, 44787]', ); }); it('should throw exception when currency is not valid when currency contain characters', async () => { diff --git a/src/services/donationService.test.ts b/src/services/donationService.test.ts index d314a82dc..6a573e875 100644 --- a/src/services/donationService.test.ts +++ b/src/services/donationService.test.ts @@ -196,6 +196,50 @@ function syncDonationStatusWithBlockchainNetworkTestCases() { assert.isTrue(updateDonation.segmentNotified); assert.equal(updateDonation.status, DONATION_STATUS.VERIFIED); }); + // it('should verify a Optimis Goerli donation', async () => { + // // https://goerli-optimism.etherscan.io/tx/0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3 + // const amount = 0.011; + + // const transactionInfo = { + // txHash: + // '0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3', + // currency: 'ETH', + // networkId: NETWORK_IDS.OPTIMISM_GOERLI, + // fromAddress: '0x317bbc1927be411cd05615d2ffdf8d320c6c4052', + // toAddress: '0x00d18ca9782be1caef611017c2fbc1a39779a57c', + // amount, + // timestamp: 1679484540, + // }; + // const user = await saveUserDirectlyToDb(transactionInfo.fromAddress); + // const project = await saveProjectDirectlyToDb({ + // ...createProjectData(), + // walletAddress: transactionInfo.toAddress, + // }); + // const donation = await saveDonationDirectlyToDb( + // { + // amount: transactionInfo.amount, + // transactionNetworkId: transactionInfo.networkId, + // transactionId: transactionInfo.txHash, + // currency: transactionInfo.currency, + // fromWalletAddress: transactionInfo.fromAddress, + // toWalletAddress: transactionInfo.toAddress, + // valueUsd: 1.79, + // anonymous: false, + // createdAt: new Date(transactionInfo.timestamp), + // status: DONATION_STATUS.PENDING, + // }, + // user.id, + // project.id, + // ); + // const updateDonation = await syncDonationStatusWithBlockchainNetwork({ + // donationId: donation.id, + // }); + // assert.isOk(updateDonation); + // assert.equal(updateDonation.id, donation.id); + // assert.equal(updateDonation.status, DONATION_STATUS.VERIFIED); + // assert.isTrue(updateDonation.segmentNotified); + // }); + it('should verify a Optimistic donation', async () => { // https://optimistic.etherscan.io/tx/0xc645bd4ebcb1cb249be4b3e4dad46075c973fd30649a39f27f5328ded15074e7 From 5a420d82dedbbb8408c760d2f83740bd42a9aa1f Mon Sep 17 00:00:00 2001 From: Koinzell Date: Wed, 21 Jun 2023 23:13:40 -0500 Subject: [PATCH 4/8] add test to verify optimism goerli donation --- src/services/donationService.test.ts | 44 ---------------------------- 1 file changed, 44 deletions(-) diff --git a/src/services/donationService.test.ts b/src/services/donationService.test.ts index 6a573e875..d314a82dc 100644 --- a/src/services/donationService.test.ts +++ b/src/services/donationService.test.ts @@ -196,50 +196,6 @@ function syncDonationStatusWithBlockchainNetworkTestCases() { assert.isTrue(updateDonation.segmentNotified); assert.equal(updateDonation.status, DONATION_STATUS.VERIFIED); }); - // it('should verify a Optimis Goerli donation', async () => { - // // https://goerli-optimism.etherscan.io/tx/0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3 - // const amount = 0.011; - - // const transactionInfo = { - // txHash: - // '0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3', - // currency: 'ETH', - // networkId: NETWORK_IDS.OPTIMISM_GOERLI, - // fromAddress: '0x317bbc1927be411cd05615d2ffdf8d320c6c4052', - // toAddress: '0x00d18ca9782be1caef611017c2fbc1a39779a57c', - // amount, - // timestamp: 1679484540, - // }; - // const user = await saveUserDirectlyToDb(transactionInfo.fromAddress); - // const project = await saveProjectDirectlyToDb({ - // ...createProjectData(), - // walletAddress: transactionInfo.toAddress, - // }); - // const donation = await saveDonationDirectlyToDb( - // { - // amount: transactionInfo.amount, - // transactionNetworkId: transactionInfo.networkId, - // transactionId: transactionInfo.txHash, - // currency: transactionInfo.currency, - // fromWalletAddress: transactionInfo.fromAddress, - // toWalletAddress: transactionInfo.toAddress, - // valueUsd: 1.79, - // anonymous: false, - // createdAt: new Date(transactionInfo.timestamp), - // status: DONATION_STATUS.PENDING, - // }, - // user.id, - // project.id, - // ); - // const updateDonation = await syncDonationStatusWithBlockchainNetwork({ - // donationId: donation.id, - // }); - // assert.isOk(updateDonation); - // assert.equal(updateDonation.id, donation.id); - // assert.equal(updateDonation.status, DONATION_STATUS.VERIFIED); - // assert.isTrue(updateDonation.segmentNotified); - // }); - it('should verify a Optimistic donation', async () => { // https://optimistic.etherscan.io/tx/0xc645bd4ebcb1cb249be4b3e4dad46075c973fd30649a39f27f5328ded15074e7 From 182de73e9e8c24f1c2396ef9974ed7ca4c94fbfd Mon Sep 17 00:00:00 2001 From: Koinzell Date: Fri, 23 Jun 2023 13:01:11 -0500 Subject: [PATCH 5/8] add goerli optimism test for transaction details --- src/services/transactionService.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/services/transactionService.test.ts b/src/services/transactionService.test.ts index d83337553..fc6034223 100644 --- a/src/services/transactionService.test.ts +++ b/src/services/transactionService.test.ts @@ -468,6 +468,25 @@ function getTransactionDetailTestCases() { assert.equal(transactionInfo.amount, amount); }); + it('should return transaction detail for normal transfer on optimism-goerli', async () => { + // https://goerli-optimism.etherscan.io/tx/0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3 + + const amount = 0.011; + const transactionInfo = await getTransactionInfoFromNetwork({ + txHash: + '0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3', + symbol: 'ETH', + networkId: NETWORK_IDS.POLYGON, + fromAddress: '0x317bbc1927be411cd05615d2ffdf8d320c6c4052', + toAddress: '0x00d18ca9782be1caef611017c2fbc1a39779a57c', + amount, + timestamp: 167740007, + }); + assert.isOk(transactionInfo); + assert.equal(transactionInfo.currency, 'ETH'); + assert.equal(transactionInfo.amount, amount); + }); + it('should return transaction detail for normal transfer on CELO', async () => { // https://celoscan.io/tx/0xa2a282cf6a7dec8b166aa52ac3d00fcd15a370d414615e29a168cfbb592e3637 From d5933ed4fd7406f1cc8c95d135bb674d0d7c4936 Mon Sep 17 00:00:00 2001 From: Koinzell Date: Fri, 23 Jun 2023 13:21:58 -0500 Subject: [PATCH 6/8] add optimism goerli tokens for test envs --- src/provider.ts | 2 +- src/services/transactionService.test.ts | 2 +- test/pre-test-scripts.ts | 11 +++++++++++ test/testUtils.ts | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/provider.ts b/src/provider.ts index c8b5afe62..9018b00d8 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -152,7 +152,7 @@ export function getProvider(networkId: number) { break; case NETWORK_IDS.OPTIMISM_GOERLI: - url = `https://optimism-goerli.public.blastapi.io/v3/${INFURA_ID}`; + url = `https://optimism-goerli.infura.io/v3/${INFURA_ID}`; break; default: { diff --git a/src/services/transactionService.test.ts b/src/services/transactionService.test.ts index fc6034223..bcdf1f72f 100644 --- a/src/services/transactionService.test.ts +++ b/src/services/transactionService.test.ts @@ -476,7 +476,7 @@ function getTransactionDetailTestCases() { txHash: '0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3', symbol: 'ETH', - networkId: NETWORK_IDS.POLYGON, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, fromAddress: '0x317bbc1927be411cd05615d2ffdf8d320c6c4052', toAddress: '0x00d18ca9782be1caef611017c2fbc1a39779a57c', amount, diff --git a/test/pre-test-scripts.ts b/test/pre-test-scripts.ts index 164322903..2385d13d6 100644 --- a/test/pre-test-scripts.ts +++ b/test/pre-test-scripts.ts @@ -156,6 +156,17 @@ async function seedTokens() { } await Token.create(tokenData as Token).save(); } + for (const token of SEED_DATA.TOKENS.optimism_goerli) { + const tokenData = { + ...token, + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + isGivbackEligible: true, + }; + if (token.symbol === 'OP') { + (tokenData as any).order = 2; + } + await Token.create(tokenData as Token).save(); + } } async function seedOrganizations() { diff --git a/test/testUtils.ts b/test/testUtils.ts index 198dba439..82ac9bb8c 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -1275,6 +1275,20 @@ export const SEED_DATA = { decimals: 18, }, ], + optimism_goerli: [ + { + name: 'OPTIMISM native token', + symbol: 'ETH', + address: '0x0000000000000000000000000000000000000000', + decimals: 18, + }, + { + name: 'OPTIMISM OP token', + symbol: 'OP', + address: '0x4200000000000000000000000000000000000042', + decimals: 18, + }, + ], goerli: [ { name: 'Ethereum native token', From 1d73216490a2000a34893a924302634241baa624 Mon Sep 17 00:00:00 2001 From: Koinzell Date: Fri, 23 Jun 2023 15:39:36 -0500 Subject: [PATCH 7/8] add optimism goerli donation sync tests --- src/services/donationService.test.ts | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/services/donationService.test.ts b/src/services/donationService.test.ts index d314a82dc..ad9f81a3d 100644 --- a/src/services/donationService.test.ts +++ b/src/services/donationService.test.ts @@ -241,6 +241,50 @@ function syncDonationStatusWithBlockchainNetworkTestCases() { assert.isTrue(updateDonation.segmentNotified); }); + it('should verify a Optimism Goerli donation', async () => { + // https://goerli-optimism.etherscan.io/tx/0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3 + const amount = 0.011; + + const transactionInfo = { + txHash: + '0x95acfc3a5d1adbc9a4584d6bf92e9dfde48087fe54c2b750b067be718215ffc3', + currency: 'ETH', + networkId: NETWORK_IDS.OPTIMISM_GOERLI, + fromAddress: '0x317bbc1927be411cd05615d2ffdf8d320c6c4052', + toAddress: '0x00d18ca9782be1caef611017c2fbc1a39779a57c', + amount, + timestamp: 1679484540, + }; + const user = await saveUserDirectlyToDb(transactionInfo.fromAddress); + const project = await saveProjectDirectlyToDb({ + ...createProjectData(), + walletAddress: transactionInfo.toAddress, + }); + const donation = await saveDonationDirectlyToDb( + { + amount: transactionInfo.amount, + transactionNetworkId: transactionInfo.networkId, + transactionId: transactionInfo.txHash, + currency: transactionInfo.currency, + fromWalletAddress: transactionInfo.fromAddress, + toWalletAddress: transactionInfo.toAddress, + valueUsd: 20.73, + anonymous: false, + createdAt: new Date(transactionInfo.timestamp), + status: DONATION_STATUS.PENDING, + }, + user.id, + project.id, + ); + const updateDonation = await syncDonationStatusWithBlockchainNetwork({ + donationId: donation.id, + }); + assert.isOk(updateDonation); + assert.equal(updateDonation.id, donation.id); + assert.equal(updateDonation.status, DONATION_STATUS.VERIFIED); + assert.isTrue(updateDonation.segmentNotified); + }); + it('should verify a mainnet donation', async () => { // https://etherscan.io/tx/0x37765af1a7924fb6ee22c83668e55719c9ecb1b79928bd4b208c42dfff44da3a const transactionInfo = { From 70c40771a1769ec44d06f2f9ebbfa07ff44cef3f Mon Sep 17 00:00:00 2001 From: Koinzell Date: Sun, 25 Jun 2023 13:07:10 -0500 Subject: [PATCH 8/8] prevent adding testnet optimism-goerli tokens in production --- migration/1687383705794-AddOptimismGoerliTokens.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/migration/1687383705794-AddOptimismGoerliTokens.ts b/migration/1687383705794-AddOptimismGoerliTokens.ts index e22b4c185..846f5171b 100644 --- a/migration/1687383705794-AddOptimismGoerliTokens.ts +++ b/migration/1687383705794-AddOptimismGoerliTokens.ts @@ -2,11 +2,18 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; import { Token } from '../src/entities/token'; import seedTokens from './data/seedTokens'; import { NETWORK_IDS } from '../src/provider'; +import config from '../src/config'; export class AddOptimismGoerliTokens1687383705794 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { + const environment = config.get('ENVIRONMENT') as string; + if (environment === 'production') { + // We dont add optimism-goerli tokens in production ENV + return; + } + await queryRunner.manager.save( Token, seedTokens @@ -38,6 +45,12 @@ export class AddOptimismGoerliTokens1687383705794 } public async down(queryRunner: QueryRunner): Promise { + const environment = config.get('ENVIRONMENT') as string; + if (environment === 'production') { + // We dont add optimism-goerli tokens in production ENV + return; + } + const tokens = await queryRunner.query(` SELECT * FROM token WHERE "networkId" = ${NETWORK_IDS.OPTIMISM_GOERLI}