diff --git a/packages/currency/src/aggregators/goerli.json b/packages/currency/src/aggregators/goerli.json new file mode 100644 index 0000000000..93d71cbd2c --- /dev/null +++ b/packages/currency/src/aggregators/goerli.json @@ -0,0 +1,8 @@ +{ + "0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc": { + "0x775eb53d00dd0acd3ec1696472105d579b9b386b": 1 + }, + "0x775eb53d00dd0acd3ec1696472105d579b9b386b": { + "0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc": 1 + } +} diff --git a/packages/currency/src/erc20/networks/goerli.ts b/packages/currency/src/erc20/networks/goerli.ts new file mode 100644 index 0000000000..d890fe3c30 --- /dev/null +++ b/packages/currency/src/erc20/networks/goerli.ts @@ -0,0 +1,17 @@ +import { TokenMap } from './types'; + +// List of the supported goerli ERC20 tokens +export const supportedGoerliERC20: TokenMap = { + // Request Test token, used for testing on goerli. + '0x7af963cF6D228E564e2A0aA0DdBF06210B38615D': { + decimals: 18, + name: 'Goerli Test Token', + symbol: 'TST', + }, + // Faucet Token on goerli network. Easy to use on tests. + '0xBA62BCfcAaFc6622853cca2BE6Ac7d845BC0f2Dc': { + decimals: 18, + name: 'Faucet Token', + symbol: 'FAU-goerli', + }, +}; diff --git a/packages/payment-detection/src/erc20/address-based.ts b/packages/payment-detection/src/erc20/address-based.ts index 5bd11e632e..4664b3164f 100644 --- a/packages/payment-detection/src/erc20/address-based.ts +++ b/packages/payment-detection/src/erc20/address-based.ts @@ -8,7 +8,7 @@ import { BalanceError } from '../balance-error'; import Erc20InfoRetriever from './address-based-info-retriever'; import { PaymentDetectorBase } from '../payment-detector-base'; -const supportedNetworks = ['mainnet', 'rinkeby', 'private']; +const supportedNetworks = ['mainnet', 'rinkeby', 'goerli', 'private']; /** * Handle payment networks with ERC20 based address extension diff --git a/packages/payment-detection/test/any/any-to-erc20-proxy-contract.test.ts b/packages/payment-detection/test/any/any-to-erc20-proxy-contract.test.ts index 1be024d556..f770a74156 100644 --- a/packages/payment-detection/test/any/any-to-erc20-proxy-contract.test.ts +++ b/packages/payment-detection/test/any/any-to-erc20-proxy-contract.test.ts @@ -31,7 +31,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { }, extensions: { anyToErc20Proxy: { - supportedNetworks: ['mainnet', 'rinkeby', 'private'], + supportedNetworks: ['mainnet', 'rinkeby', 'goerli', 'private'], createAddPaymentAddressAction, createAddRefundAddressAction, createCreationAction, @@ -56,35 +56,61 @@ describe('api/any/conversion-fee-proxy-contract', () => { jest.clearAllMocks(); }); - it('can createExtensionsDataForCreation', async () => { - await anyToErc20Proxy.createExtensionsDataForCreation({ - paymentAddress: 'ethereum address', - salt: 'ea3bc7caf64110ca', - acceptedTokens: ['ethereum address2'], - network: 'rinkeby', - maxRateTimespan: 1000, + const testSuite = (network: string) => { + it(`can createExtensionsDataForCreation on ${network}`, async () => { + await anyToErc20Proxy.createExtensionsDataForCreation({ + paymentAddress: 'ethereum address', + salt: 'ea3bc7caf64110ca', + acceptedTokens: ['ethereum address2'], + network: network, + maxRateTimespan: 1000, + }); + + expect(createCreationAction).toHaveBeenCalledWith({ + feeAddress: undefined, + feeAmount: undefined, + paymentAddress: 'ethereum address', + refundAddress: undefined, + salt: 'ea3bc7caf64110ca', + acceptedTokens: ['ethereum address2'], + network: network, + maxRateTimespan: 1000, + }); }); - expect(createCreationAction).toHaveBeenCalledWith({ - feeAddress: undefined, - feeAmount: undefined, - paymentAddress: 'ethereum address', - refundAddress: undefined, - salt: 'ea3bc7caf64110ca', - acceptedTokens: ['ethereum address2'], - network: 'rinkeby', - maxRateTimespan: 1000, + it(`can createExtensionsDataForCreation with fee amount and address ${network}`, async () => { + await anyToErc20Proxy.createExtensionsDataForCreation({ + feeAddress: 'fee address', + feeAmount: '2000', + paymentAddress: 'ethereum address', + salt: 'ea3bc7caf64110ca', + acceptedTokens: ['ethereum address2'], + network: network, + }); + + expect(createCreationAction).toHaveBeenCalledWith({ + feeAddress: 'fee address', + feeAmount: '2000', + paymentAddress: 'ethereum address', + refundAddress: undefined, + salt: 'ea3bc7caf64110ca', + acceptedTokens: ['ethereum address2'], + network: network, + }); }); - }); + }; + + testSuite('rinkeby'); + testSuite('goerli'); - it('can createExtensionsDataForCreation with fee amount and address', async () => { + it('can createExtensionsDataForCreation with fee amount and address (Goerli)', async () => { await anyToErc20Proxy.createExtensionsDataForCreation({ feeAddress: 'fee address', feeAmount: '2000', paymentAddress: 'ethereum address', salt: 'ea3bc7caf64110ca', acceptedTokens: ['ethereum address2'], - network: 'rinkeby', + network: 'goerli', }); expect(createCreationAction).toHaveBeenCalledWith({ @@ -94,7 +120,7 @@ describe('api/any/conversion-fee-proxy-contract', () => { refundAddress: undefined, salt: 'ea3bc7caf64110ca', acceptedTokens: ['ethereum address2'], - network: 'rinkeby', + network: 'goerli', }); }); diff --git a/packages/payment-detection/test/erc20/address-based.test.ts b/packages/payment-detection/test/erc20/address-based.test.ts index f75629d334..93fa533021 100644 --- a/packages/payment-detection/test/erc20/address-based.test.ts +++ b/packages/payment-detection/test/erc20/address-based.test.ts @@ -126,7 +126,7 @@ describe('api/erc20/address-based', () => { error: { code: PaymentTypes.BALANCE_ERROR_CODE.NETWORK_NOT_SUPPORTED, message: - 'Payment network wrong not supported by ERC20 payment detection. Supported networks: mainnet, rinkeby, private', + 'Payment network wrong not supported by ERC20 payment detection. Supported networks: mainnet, rinkeby, goerli, private', }, events: [], }); diff --git a/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts b/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts index f7504c9b8d..c0d924c21d 100644 --- a/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts +++ b/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts @@ -23,7 +23,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { }, extensions: { feeProxyContractErc20: { - supportedNetworks: ['mainnet', 'private', 'rinkeby'], + supportedNetworks: ['mainnet', 'private', 'rinkeby', 'goerli'], createAddPaymentAddressAction, createAddRefundAddressAction, createCreationAction, @@ -283,7 +283,7 @@ describe('api/erc20/fee-proxy-contract', () => { ).toBe('7'); }); - it('should have gasFee & gasUsed in the payment eventl', async () => { + it('should have gasFee & gasUsed in the payment event', async () => { const mockRequest: RequestLogicTypes.IRequest = { creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { diff --git a/packages/payment-detection/test/erc20/proxy-contract.test.ts b/packages/payment-detection/test/erc20/proxy-contract.test.ts index 5d89bb7977..f814c0ae58 100644 --- a/packages/payment-detection/test/erc20/proxy-contract.test.ts +++ b/packages/payment-detection/test/erc20/proxy-contract.test.ts @@ -25,7 +25,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { }, extensions: { proxyContractErc20: { - supportedNetworks: ['mainnet', 'rinkeby'], + supportedNetworks: ['mainnet', 'rinkeby', 'goerli'], createAddPaymentAddressAction, createAddRefundAddressAction, createCreationAction, @@ -160,7 +160,7 @@ describe('api/erc20/proxy-contract', () => { error: { code: PaymentTypes.BALANCE_ERROR_CODE.NETWORK_NOT_SUPPORTED, message: - 'Payment network WRONG not supported by pn-erc20-proxy-contract payment detection. Supported networks: mainnet, rinkeby', + 'Payment network WRONG not supported by pn-erc20-proxy-contract payment detection. Supported networks: mainnet, rinkeby, goerli', }, events: [], }); diff --git a/packages/payment-detection/test/erc777/mocks.ts b/packages/payment-detection/test/erc777/mocks.ts index 69565f307f..8cfdc6eb5c 100644 --- a/packages/payment-detection/test/erc777/mocks.ts +++ b/packages/payment-detection/test/erc777/mocks.ts @@ -76,7 +76,7 @@ const mockFlows = [ }, { transactionHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be', - blockNumber: '9945543', + blockNumber: 9945543, timestamp: '1641495767', sender: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7', flowRate: '0', diff --git a/packages/payment-detection/test/erc777/superfluid-retriever.test.ts b/packages/payment-detection/test/erc777/superfluid-retriever.test.ts index 9ea56eb5e9..3d70f16569 100644 --- a/packages/payment-detection/test/erc777/superfluid-retriever.test.ts +++ b/packages/payment-detection/test/erc777/superfluid-retriever.test.ts @@ -7,106 +7,108 @@ import { mockSuperfluidSubgraph } from './mocks'; jest.mock('graphql-request'); const graphql = mocked(GraphQLClient.prototype); +const fDAIxTokenRinkeby = '0x745861aed1eee363b4aaa5f1994be40b1e05ff90'; +const fUSDCxTokenRinkeby = '0x0f1d7c55a2b133e000ea10eec03c774e0d6796e8'; +const fDAIxTokenGoerli = '0x2bf02814ea0b2b155ed47b7cede18caa752940e6'; +const fUSDCxTokenGoerli = '0x2bf02814ea0b2b155ed47b7cede18caa752940e6'; -describe('api/erc777/superfluid-info-retriever', () => { - describe('on untagged requests', () => { - it('should get payment events from SuperFluid via subgraph with 1 request', async () => { - const paymentData = { - reference: '0xbeefaccc470c7dbd54de69', - txHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be', - from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7', - to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594', - network: 'rinkeby', - salt: '0ee84db293a752c6', - amount: '92592592592592000', - requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1', - block: 9945543, - token: '0x745861aed1eee363b4aaa5f1994be40b1e05ff90', //fDAIx - }; - graphql.request.mockResolvedValue(mockSuperfluidSubgraph[0]); +const testSuite = (network: string, fDAIxToken: string) => { + describe('api/erc777/superfluid-info-retriever', () => { + describe('on untagged requests', () => { + it(`should get payment events from SuperFluid via subgraph with 1 request on ${network}`, async () => { + const paymentData = { + reference: '0xbeefaccc470c7dbd54de69', + txHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be', + from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7', + to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594', + network: network, + salt: '0ee84db293a752c6', + amount: '92592592592592000', + requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1', + block: 9945543, + token: fDAIxToken, + }; + graphql.request.mockResolvedValue(mockSuperfluidSubgraph[0]); - const paymentReference = PaymentReferenceCalculator.calculate( - paymentData.requestId, - paymentData.salt, - paymentData.to, - ); - const subgraphReference = `0xbeefac${paymentReference}`; - expect(subgraphReference).toEqual(paymentData.reference); + const paymentReference = PaymentReferenceCalculator.calculate( + paymentData.requestId, + paymentData.salt, + paymentData.to, + ); + const subgraphReference = `0xbeefac${paymentReference}`; + expect(subgraphReference).toEqual(paymentData.reference); - const graphRetriever = new SuperFluidInfoRetriever( - paymentReference, - paymentData.token, - paymentData.to, - PaymentTypes.EVENTS_NAMES.PAYMENT, - paymentData.network, - ); - const transferEvents = await graphRetriever.getTransferEvents(); - expect(transferEvents).toHaveLength(5); - expect(transferEvents[0].amount).toEqual(paymentData.amount); - expect(transferEvents[0].name).toEqual('payment'); - expect(transferEvents[0].parameters?.to).toEqual(paymentData.to); - expect(transferEvents[1].amount).toEqual('34722222222222000'); - expect(transferEvents[2].amount).toEqual('40509259259259000'); - expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash); - expect(transferEvents[0].parameters?.block).toEqual(paymentData.block); + const graphRetriever = new SuperFluidInfoRetriever( + paymentReference, + paymentData.token, + paymentData.to, + PaymentTypes.EVENTS_NAMES.PAYMENT, + paymentData.network, + ); + const transferEvents = await graphRetriever.getTransferEvents(); + expect(transferEvents).toHaveLength(5); + expect(transferEvents[0].amount).toEqual(paymentData.amount); + expect(transferEvents[0].name).toEqual('payment'); + expect(transferEvents[0].parameters?.to).toEqual(paymentData.to); + expect(transferEvents[1].amount).toEqual('34722222222222000'); + expect(transferEvents[2].amount).toEqual('40509259259259000'); + expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash); + expect(transferEvents[0].parameters?.block).toEqual(paymentData.block); + }); }); - }); - describe('on 2 nested requests', () => { - it('should get payment event from SuperFluid via subgraph with 2 requests', async () => { - const paymentData = { - reference: '0xbeefac9474ad7670909da5', - from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7', - to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594', - network: 'rinkeby', - salt: '0ee84db293a752c6', - amount: '320833333333331260', - // = (1642693617 - 1642692777 = 840 sec) x (385802469135800 - 3858024691358 = 381944444444442 Wei DAIx / sec) - requestId: '0288792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2', - token: '0x745861aed1eee363b4aaa5f1994be40b1e05ff90', //fDAIx - block: 10024811, - txHash: '0x0fefa02d90be46eb51a82f02b7a787084c35a895bd833a7c9f0560e315bb4061', - }; - graphql.request.mockResolvedValue(mockSuperfluidSubgraph[1]); + describe('on 2 nested requests', () => { + it(`should get payment event from SuperFluid via subgraph with 2 requests on ${network}`, async () => { + const paymentData = { + reference: '0xbeefac9474ad7670909da5', + from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7', + to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594', + network: network, + salt: '0ee84db293a752c6', + amount: '320833333333331260', + // = (1642693617 - 1642692777 = 840 sec) x (385802469135800 - 3858024691358 = 381944444444442 Wei DAIx / sec) + requestId: '0288792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2', + token: fDAIxToken, + }; + graphql.request.mockResolvedValue(mockSuperfluidSubgraph[1]); - const paymentReference = PaymentReferenceCalculator.calculate( - paymentData.requestId, - paymentData.salt, - paymentData.to, - ); - const subgraphReference = `0xbeefac${paymentReference}`; - expect(subgraphReference).toEqual(paymentData.reference); - const graphRetriever = new SuperFluidInfoRetriever( - paymentReference, - paymentData.token, - paymentData.to, - PaymentTypes.EVENTS_NAMES.PAYMENT, - paymentData.network, - ); - const transferEvents = await graphRetriever.getTransferEvents(); - expect(transferEvents).toHaveLength(1); - expect(transferEvents[0].amount).toEqual(paymentData.amount); - expect(transferEvents[0].name).toEqual('payment'); - expect(transferEvents[0].parameters?.to).toEqual(paymentData.to); - expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash); - expect(transferEvents[0].parameters?.block).toEqual(paymentData.block); + const paymentReference = PaymentReferenceCalculator.calculate( + paymentData.requestId, + paymentData.salt, + paymentData.to, + ); + const subgraphReference = `0xbeefac${paymentReference}`; + expect(subgraphReference).toEqual(paymentData.reference); + const graphRetriever = new SuperFluidInfoRetriever( + paymentReference, + paymentData.token, + paymentData.to, + PaymentTypes.EVENTS_NAMES.PAYMENT, + paymentData.network, + ); + const transferEvents = await graphRetriever.getTransferEvents(); + expect(transferEvents).toHaveLength(1); + expect(transferEvents[0].amount).toEqual(paymentData.amount); + expect(transferEvents[0].name).toEqual('payment'); + expect(transferEvents[0].parameters?.to).toEqual(paymentData.to); + }); }); }); +}; +const testSuite2 = (network: string, fUSDCxToken: string) => { describe('on ongoing request', () => { - it('should get payment event from SuperFluid via subgraph with ongoing request', async () => { + it(`should get payment event from SuperFluid via subgraph with ongoing request on ${network}`, async () => { const paymentData = { reference: '0xbeefac0e87b43bf1e99c82', from: '0x165a26628ac843e97f657e648b004226fbb7f7c5', to: '0xe7e6431f08db273d915b49888f0c67ef61802e05', - network: 'rinkeby', + network: network, salt: '0ee84db293a752c6', amount: '1', requestId: '0688792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2', - token: '0x0f1d7c55a2b133e000ea10eec03c774e0d6796e8', //fUSDCx + token: fUSDCxToken, timestamp: 1643041225, - block: 10047970, - txHash: '0xdb44f35aa1490d2ddc8bbe7b82e0e3a370f3bf171a55da7a8a5886996e9c468d', }; graphql.request.mockResolvedValue(mockSuperfluidSubgraph[2]); @@ -131,8 +133,12 @@ describe('api/erc777/superfluid-info-retriever', () => { expect(transferEvents[0].amount).toEqual(timestamp.toString()); expect(transferEvents[0].name).toEqual('payment'); expect(transferEvents[0].parameters?.to).toEqual(paymentData.to); - expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash); - expect(transferEvents[0].parameters?.block).toEqual(paymentData.block); }); }); -}); +}; + +testSuite('rinkeby', fDAIxTokenRinkeby); +testSuite('goerli', fDAIxTokenGoerli); + +testSuite2('rinkeby', fUSDCxTokenRinkeby); +testSuite2('goerli', fUSDCxTokenGoerli); diff --git a/packages/payment-detection/test/eth/info-retriever.test.ts b/packages/payment-detection/test/eth/info-retriever.test.ts index 0a314c0c79..de5f76798b 100644 --- a/packages/payment-detection/test/eth/info-retriever.test.ts +++ b/packages/payment-detection/test/eth/info-retriever.test.ts @@ -46,11 +46,12 @@ describe('api/eth/info-retriever', () => { }); describe('Multichain', () => { - // TODO temporary disable xDAI, CELO and Sokol + // TODO temporary disable xDAI, CELO, Sokol, and Goerli // FIXME: API-based checks should run nightly and be mocked for CI [ 'mainnet', 'rinkeby', + // 'goerli', // 'xdai', // 'sokol', 'fuse', diff --git a/packages/payment-detection/test/eth/input-data.test.ts b/packages/payment-detection/test/eth/input-data.test.ts index 3be6bfd6db..054c189c16 100644 --- a/packages/payment-detection/test/eth/input-data.test.ts +++ b/packages/payment-detection/test/eth/input-data.test.ts @@ -23,7 +23,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { createAddPaymentAddressAction, createAddRefundAddressAction, createCreationAction, - supportedNetworks: ['mainnet', 'rinkeby'], + supportedNetworks: ['mainnet', 'rinkeby', 'goerli'], // inherited from declarative createAddPaymentInstructionAction, createAddRefundInstructionAction, @@ -160,7 +160,7 @@ describe('api/eth/input-data', () => { error: { code: PaymentTypes.BALANCE_ERROR_CODE.NETWORK_NOT_SUPPORTED, message: - /Payment network wrong not supported by ETH payment detection\. Supported networks: mainnet, rinkeby, private.*/, + /Payment network wrong not supported by ETH payment detection\. Supported networks: mainnet, rinkeby, goerli, private.*/, }, events: [], }); diff --git a/packages/payment-detection/test/provider.test.ts b/packages/payment-detection/test/provider.test.ts index 1a9fdaf5ff..c7aed7ef33 100644 --- a/packages/payment-detection/test/provider.test.ts +++ b/packages/payment-detection/test/provider.test.ts @@ -13,12 +13,23 @@ describe('getDefaultProvider', () => { expect(provider).toBeInstanceOf(providers.InfuraProvider); await expect(provider.getNetwork()).resolves.toMatchObject({ chainId: 1 }); }); + const testSuite = (network: string, chainId: number) => { + it(`Can take a standard network ${network}`, async () => { + const provider = getDefaultProvider(network); - it('Can take a standard network', async () => { - const provider = getDefaultProvider('rinkeby'); + expect(provider).toBeInstanceOf(providers.InfuraProvider); + await expect(provider.getNetwork()).resolves.toMatchObject({ chainId: chainId }); + }); + }; + + testSuite('rinkeby', 4); + testSuite('goerli', 5); + + it('Can take a standard network (Goerli)', async () => { + const provider = getDefaultProvider('goerli'); expect(provider).toBeInstanceOf(providers.InfuraProvider); - await expect(provider.getNetwork()).resolves.toMatchObject({ chainId: 4 }); + await expect(provider.getNetwork()).resolves.toMatchObject({ chainId: 5 }); }); it('Can take a private network', async () => { @@ -71,12 +82,16 @@ describe('getDefaultProvider', () => { ); }); - it('Can override the api key for a standard provider', async () => { - initPaymentDetectionApiKeys({ - infura: 'foo-bar', - }); + expect((getDefaultProvider('goerli') as providers.JsonRpcProvider).connection.url).toMatch( + /https:\/\/goerli\.infura.*/, + ); +}); - const provider = getDefaultProvider() as providers.InfuraProvider; - expect(provider.connection.url).toEqual('https://mainnet.infura.io/v3/foo-bar'); +it('Can override the api key for a standard provider', async () => { + initPaymentDetectionApiKeys({ + infura: 'foo-bar', }); + + const provider = getDefaultProvider() as providers.InfuraProvider; + expect(provider.connection.url).toEqual('https://mainnet.infura.io/v3/foo-bar'); }); diff --git a/packages/payment-processor/src/payment/utils.ts b/packages/payment-processor/src/payment/utils.ts index 355665d174..a0dc0b72df 100644 --- a/packages/payment-processor/src/payment/utils.ts +++ b/packages/payment-processor/src/payment/utils.ts @@ -30,7 +30,7 @@ export function getProvider(): providers.Web3Provider { /** * Utility to get a network provider, depending on the request's currency network. - * Will throw an error if the network isn't mainnet or rinkeby + * Will throw an error if the network isn't mainnet, rinkeby, or goerli * * @param request */ diff --git a/packages/payment-processor/test/payment/utils.test.ts b/packages/payment-processor/test/payment/utils.test.ts index 7f06a01d1e..16edf997d5 100644 --- a/packages/payment-processor/test/payment/utils.test.ts +++ b/packages/payment-processor/test/payment/utils.test.ts @@ -108,6 +108,15 @@ describe('getNetworkProvider', () => { expect(getNetworkProvider(request)).toBeInstanceOf(providers.Provider); }); + it('returns a provider for goerli', () => { + const request: any = { + currencyInfo: { + network: 'goerli', + }, + }; + expect(getNetworkProvider(request)).toBeInstanceOf(providers.Provider); + }); + it('fails for other network', () => { const request: any = { currencyInfo: { diff --git a/packages/smart-contracts/scripts-create2/compute-one-address.ts b/packages/smart-contracts/scripts-create2/compute-one-address.ts index 7e8c4809a7..f2803616ed 100644 --- a/packages/smart-contracts/scripts-create2/compute-one-address.ts +++ b/packages/smart-contracts/scripts-create2/compute-one-address.ts @@ -52,7 +52,7 @@ export const computeCreate2DeploymentAddressesFromList = async ( switch (contract) { case 'EthereumProxy': case 'EthereumFeeProxy': - case 'ETHConversionProxy': + case 'EthConversionProxy': case 'ERC20FeeProxy': case 'Erc20ConversionProxy': case 'ERC20EscrowToPay': diff --git a/packages/smart-contracts/scripts-create2/constructor-args.ts b/packages/smart-contracts/scripts-create2/constructor-args.ts index db9d4952e6..58217038c8 100644 --- a/packages/smart-contracts/scripts-create2/constructor-args.ts +++ b/packages/smart-contracts/scripts-create2/constructor-args.ts @@ -22,7 +22,6 @@ export const getConstructorArgs = (contract: string, network?: string): string[] '0x0000000000000000000000000000000000000000', '0x39e19aa5b69466dfdc313c7cda37cb2a599015cd', ]; - // TODO setupETHConversionProxy } case 'ERC20SwapToConversion': { return [getAdminWalletAddress(contract)]; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts index 28d1c974d9..b0c0cbfee8 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts @@ -8,7 +8,7 @@ import { updateChainlinkConversionPath, updatePaymentErc20FeeProxy } from './adm * @param contractAddress address of the BatchPayments Proxy * @param hre Hardhat runtime environment */ -export const setupEthConversionProxy = async ( +export const setupETHConversionProxy = async ( contractAddress: string, hre: HardhatRuntimeEnvironmentExtended, ): Promise => { diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~0bd61713... refactor: contract setup compression fix (#888) b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~0bd61713... refactor: contract setup compression fix (#888) new file mode 100644 index 0000000000..28d1c974d9 --- /dev/null +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~0bd61713... refactor: contract setup compression fix (#888) @@ -0,0 +1,47 @@ +import { batchPaymentsArtifact } from '../../src/lib'; +import { HardhatRuntimeEnvironmentExtended } from '../types'; +import utils from '@requestnetwork/utils'; +import { updateChainlinkConversionPath, updatePaymentErc20FeeProxy } from './adminTasks'; + +/** + * Updates the values of the batch fees of the BatchPayments contract, if needed + * @param contractAddress address of the BatchPayments Proxy + * @param hre Hardhat runtime environment + */ +export const setupEthConversionProxy = async ( + contractAddress: string, + hre: HardhatRuntimeEnvironmentExtended, +): Promise => { + // Setup contract parameters + const EthConversionProxyContract = new hre.ethers.Contract( + contractAddress, + batchPaymentsArtifact.getContractAbi(), + ); + await Promise.all( + hre.config.xdeploy.networks.map(async (network) => { + let provider; + if (network === 'celo') { + provider = utils.getCeloProvider(); + } else { + provider = utils.getDefaultProvider(network); + } + const wallet = new hre.ethers.Wallet(hre.config.xdeploy.signer, provider); + const signer = wallet.connect(provider); + const EthConversionProxyConnected = await EthConversionProxyContract.connect(signer); + const adminNonce = await signer.getTransactionCount(); + const gasPrice = await provider.getGasPrice(); + + // start from the adminNonce, increase gasPrice if needed + await Promise.all([ + updatePaymentErc20FeeProxy(EthConversionProxyConnected, network, adminNonce, gasPrice), + updateChainlinkConversionPath( + EthConversionProxyConnected, + network, + adminNonce + 1, + gasPrice, + ), + ]); + }), + ); + console.log('Setup for EthConversionProxy successful'); +}; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~e693ba13... refactor: contract setup compression fix (#888) b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~e693ba13... refactor: contract setup compression fix (#888) new file mode 100644 index 0000000000..28d1c974d9 --- /dev/null +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts~e693ba13... refactor: contract setup compression fix (#888) @@ -0,0 +1,47 @@ +import { batchPaymentsArtifact } from '../../src/lib'; +import { HardhatRuntimeEnvironmentExtended } from '../types'; +import utils from '@requestnetwork/utils'; +import { updateChainlinkConversionPath, updatePaymentErc20FeeProxy } from './adminTasks'; + +/** + * Updates the values of the batch fees of the BatchPayments contract, if needed + * @param contractAddress address of the BatchPayments Proxy + * @param hre Hardhat runtime environment + */ +export const setupEthConversionProxy = async ( + contractAddress: string, + hre: HardhatRuntimeEnvironmentExtended, +): Promise => { + // Setup contract parameters + const EthConversionProxyContract = new hre.ethers.Contract( + contractAddress, + batchPaymentsArtifact.getContractAbi(), + ); + await Promise.all( + hre.config.xdeploy.networks.map(async (network) => { + let provider; + if (network === 'celo') { + provider = utils.getCeloProvider(); + } else { + provider = utils.getDefaultProvider(network); + } + const wallet = new hre.ethers.Wallet(hre.config.xdeploy.signer, provider); + const signer = wallet.connect(provider); + const EthConversionProxyConnected = await EthConversionProxyContract.connect(signer); + const adminNonce = await signer.getTransactionCount(); + const gasPrice = await provider.getGasPrice(); + + // start from the adminNonce, increase gasPrice if needed + await Promise.all([ + updatePaymentErc20FeeProxy(EthConversionProxyConnected, network, adminNonce, gasPrice), + updateChainlinkConversionPath( + EthConversionProxyConnected, + network, + adminNonce + 1, + gasPrice, + ), + ]); + }), + ); + console.log('Setup for EthConversionProxy successful'); +}; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts index 88f85e030b..cda45affa2 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setups.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setups.ts @@ -1,143 +1,10 @@ import { HardhatRuntimeEnvironmentExtended } from '../types'; -import { erc20SwapConversionArtifact } from '../../src/lib'; -import { batchPaymentsArtifact } from '../../src/lib'; -import utils from '@requestnetwork/utils'; -import { - updateBatchPaymentFees, - updatePaymentErc20FeeProxy, - updatePaymentEthFeeProxy, - updateChainlinkConversionPath, - updateRequestSwapFees, - updateSwapRouter, -} from './adminTasks'; +import { setupETHConversionProxy } from './setupETHConversionProxy'; +import { setupBatchPayments } from './setupBatchPayments'; +import { setupERC20SwapToConversion } from './setupERC20SwapToConversion'; /** - * Updates the values of the batch fees of the BatchPayments contract, if needed - * @param contractAddress address of the BatchPayments Proxy - * @param hre Hardhat runtime environment - */ -const setupBatchPayments = async ( - contractAddress: string, - hre: HardhatRuntimeEnvironmentExtended, -): Promise => { - // Setup contract parameters - const batchPaymentContract = new hre.ethers.Contract( - contractAddress, - batchPaymentsArtifact.getContractAbi(), - ); - await Promise.all( - hre.config.xdeploy.networks.map(async (network) => { - let provider; - if (network === 'celo') { - provider = utils.getCeloProvider(); - } else { - provider = utils.getDefaultProvider(network); - } - const wallet = new hre.ethers.Wallet(hre.config.xdeploy.signer, provider); - const signer = wallet.connect(provider); - const batchPaymentConnected = await batchPaymentContract.connect(signer); - const adminNonce = await signer.getTransactionCount(); - const gasPrice = await provider.getGasPrice(); - - // start from the adminNonce, increase gasPrice if needed - await Promise.all([ - updateBatchPaymentFees(batchPaymentConnected, adminNonce, gasPrice.mul(2)), - updatePaymentErc20FeeProxy(batchPaymentConnected, network, adminNonce + 1, gasPrice.mul(2)), - updatePaymentEthFeeProxy(batchPaymentConnected, network, adminNonce + 2, gasPrice.mul(2)), - ]); - }), - ); - console.log('Setup for setupBatchPayment successful'); -}; - -/** - * Updates the values of the chainlinkConversionPath and swap router of the ERC20SwapToConversion contract, if needed - * @param contractAddress address of the ERC20SwapToConversion Proxy - * @param hre Hardhat runtime environment - */ -const setupERC20SwapToConversion = async ( - contractAddress: string, - hre: HardhatRuntimeEnvironmentExtended, -): Promise => { - // Setup contract parameters - const ERC20SwapToConversionContract = new hre.ethers.Contract( - contractAddress, - erc20SwapConversionArtifact.getContractAbi(), - ); - await Promise.all( - hre.config.xdeploy.networks.map(async (network) => { - let provider; - if (network === 'celo') { - provider = utils.getCeloProvider(); - } else { - provider = utils.getDefaultProvider(network); - } - const wallet = new hre.ethers.Wallet(hre.config.xdeploy.signer, provider); - const signer = wallet.connect(provider); - const ERC20SwapToConversionConnected = await ERC20SwapToConversionContract.connect(signer); - const adminNonce = await signer.getTransactionCount(); - const gasPrice = await provider.getGasPrice(); - - await Promise.all([ - updateChainlinkConversionPath( - ERC20SwapToConversionConnected, - network, - adminNonce, - gasPrice, - ), - updateSwapRouter(ERC20SwapToConversionConnected, network, adminNonce + 1, gasPrice), - updateRequestSwapFees(ERC20SwapToConversionConnected, adminNonce + 2, gasPrice), - ]); - }), - ); - console.log('Setup for ERC20SwapToConversion successfull'); -}; - -/** - * Updates the values of the EthConversionProxy contract, if needed - * @param contractAddress address of the EthConversion Proxy - * @param hre Hardhat runtime environment - */ -const setupEthConversionProxy = async ( - contractAddress: string, - hre: HardhatRuntimeEnvironmentExtended, -): Promise => { - // Setup contract parameters - const EthConversionProxyContract = new hre.ethers.Contract( - contractAddress, - batchPaymentsArtifact.getContractAbi(), - ); - await Promise.all( - hre.config.xdeploy.networks.map(async (network) => { - let provider; - if (network === 'celo') { - provider = utils.getCeloProvider(); - } else { - provider = utils.getDefaultProvider(network); - } - const wallet = new hre.ethers.Wallet(hre.config.xdeploy.signer, provider); - const signer = wallet.connect(provider); - const EthConversionProxyConnected = await EthConversionProxyContract.connect(signer); - const adminNonce = await signer.getTransactionCount(); - const gasPrice = await provider.getGasPrice(); - - // start from the adminNonce, increase gasPrice if needed - await Promise.all([ - updatePaymentErc20FeeProxy(EthConversionProxyConnected, network, adminNonce, gasPrice), - updateChainlinkConversionPath( - EthConversionProxyConnected, - network, - adminNonce + 1, - gasPrice, - ), - ]); - }), - ); - console.log('Setup for EthConversionProxy successful'); -}; - -/** - * Updates the values of either BatchPayments, EthConversionProxy, or ERC20SwapToConversion contract, if needed + * Updates the values of either BatchPayments, ETHConversionProxy, or ERC20SwapToConversion contract, if needed * @param contractAddress address of the proxy * @param hre Hardhat runtime environment * @param contractName name of the contract @@ -148,8 +15,8 @@ export const setupContract = async ( contractName: string, ): Promise => { switch (contractName) { - case 'EthConversionProxy': { - await setupEthConversionProxy(contractAddress, hre); + case 'ETHConversionProxy': { + await setupETHConversionProxy(contractAddress, hre); break; } case 'ERC20SwapToConversion': { diff --git a/packages/smart-contracts/scripts-create2/deploy.ts b/packages/smart-contracts/scripts-create2/deploy.ts index ec15644fac..23dbfc931b 100644 --- a/packages/smart-contracts/scripts-create2/deploy.ts +++ b/packages/smart-contracts/scripts-create2/deploy.ts @@ -53,7 +53,7 @@ export const deployWithCreate2FromList = async ( switch (contract) { case 'EthereumProxy': case 'EthereumFeeProxy': - case 'ETHConversionProxy': + case 'EthConversionProxy': case 'ERC20FeeProxy': case 'Erc20ConversionProxy': { const constructorArgs = getConstructorArgs(contract); diff --git a/packages/smart-contracts/scripts-create2/utils.ts b/packages/smart-contracts/scripts-create2/utils.ts index 421bba148c..6956b562ae 100644 --- a/packages/smart-contracts/scripts-create2/utils.ts +++ b/packages/smart-contracts/scripts-create2/utils.ts @@ -9,7 +9,7 @@ import * as artifacts from '../src/lib'; export const create2ContractDeploymentList = [ 'EthereumProxy', 'EthereumFeeProxy', - 'ETHConversionProxy', + 'EthConversionProxy', 'ERC20FeeProxy', 'Erc20ConversionProxy', 'ERC20SwapToConversion', @@ -39,7 +39,7 @@ export const getArtifact = (contract: string): artifacts.ContractArtifact { const NONCE_BATCH_4 = 10; @@ -170,7 +170,7 @@ export async function deployAllPaymentContracts( }); // Deploy ETH Conversion - const ethConversionResult = await deployETHConversionProxy( + const ethConversionResult = await deployEthConversionProxy( { ...args, chainlinkConversionPathAddress, @@ -265,12 +265,12 @@ export async function deployAllPaymentContracts( const ethConversionAdminNonce = NONCE_BATCH_5 + 3; await jumpToNonce(args, hre, ethConversionAdminNonce); - // 5.d ETHConversion.transferOwnership + // 5.d EthConversion.transferOwnership if (await nonceReady(ethConversionAdminNonce)) { if (ethConversionResultInstance) { if (!process.env.ADMIN_WALLET_ADDRESS) { throw new Error( - 'ADMIN_WALLET_ADDRESS missing, cannot addWhitelistAdmin on ETHConversion.', + 'ADMIN_WALLET_ADDRESS missing, cannot addWhitelistAdmin on EthConversion.', ); } if (args.simulate === false) { @@ -280,13 +280,13 @@ export async function deployAllPaymentContracts( await tx.wait(1); } else { console.log( - `[i] Simulating addWhitelistAdmin to ETHConversion at ${ethConversionResultInstance.address}`, + `[i] Simulating addWhitelistAdmin to EthConversion at ${ethConversionResultInstance.address}`, ); } } else { if (!ethConversionResultInstance) { console.warn( - `Warning: the ETHConversion contract instance is not ready for ETHConversion update, consider retrying.`, + `Warning: the EthConversion contract instance is not ready for EthConversion update, consider retrying.`, ); switchToSimulation(); } diff --git a/packages/smart-contracts/scripts/test-deploy_chainlink_contract.ts b/packages/smart-contracts/scripts/test-deploy_chainlink_contract.ts index 88fa62a254..099be843a4 100644 --- a/packages/smart-contracts/scripts/test-deploy_chainlink_contract.ts +++ b/packages/smart-contracts/scripts/test-deploy_chainlink_contract.ts @@ -1,7 +1,7 @@ import '@nomiclabs/hardhat-ethers'; import { CurrencyManager } from '@requestnetwork/currency'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { deployERC20ConversionProxy, deployETHConversionProxy } from './conversion-proxy'; +import { deployERC20ConversionProxy, deployEthConversionProxy } from './conversion-proxy'; import { deploySwapConversion } from './erc20-swap-to-conversion'; import { deployOne } from './deploy-one'; @@ -93,7 +93,7 @@ export default async function deploy( // EthConversion const ethConversionProxyAddress = ( - await deployETHConversionProxy( + await deployEthConversionProxy( { ...args, chainlinkConversionPathAddress: conversionPathInstance.address, diff --git a/packages/smart-contracts/src/contracts/interfaces/IERC20ConversionProxy.sol b/packages/smart-contracts/src/contracts/interfaces/IERC20ConversionProxy.sol index 946d170691..3a7b8b8f6a 100644 --- a/packages/smart-contracts/src/contracts/interfaces/IERC20ConversionProxy.sol +++ b/packages/smart-contracts/src/contracts/interfaces/IERC20ConversionProxy.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20ConversionProxy { diff --git a/packages/smart-contracts/src/lib/artifacts/ChainlinkConversionPath/index.ts b/packages/smart-contracts/src/lib/artifacts/ChainlinkConversionPath/index.ts index ee0761fde6..817dd671ee 100644 --- a/packages/smart-contracts/src/lib/artifacts/ChainlinkConversionPath/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/ChainlinkConversionPath/index.ts @@ -72,6 +72,10 @@ export const chainlinkConversionPath = new ContractArtifact( address: '0x1B5077Ca852d39CDDeDaF45FAF1235841854420b', creationBlockNumber: 7408086, }, + goerli: { + address: '0x0Ef49176A87Adcc88bD5125126C6a6c23a28303C', + creationBlockNumber: 7109102, + }, bsc: { address: '0x75740D9b5cA3BCCb356CA7f0D0dB71aBE427a835', creationBlockNumber: 16165020, diff --git a/packages/smart-contracts/src/lib/artifacts/EthConversionProxy/index.ts b/packages/smart-contracts/src/lib/artifacts/EthConversionProxy/index.ts index 01ced6caa8..c9720fa6d9 100644 --- a/packages/smart-contracts/src/lib/artifacts/EthConversionProxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/EthConversionProxy/index.ts @@ -55,6 +55,10 @@ export const ethConversionArtifact = new ContractArtifact( address: '0x7Ebf48a26253810629C191b56C3212Fd0D211c26', creationBlockNumber: 10023415, }, + goerli: { + address: '0xED250D9219EB93098Bb67aEbc992963172B9c8DA', + creationBlockNumber: 7108896, + }, fantom: { address: '0x7Ebf48a26253810629C191b56C3212Fd0D211c26', creationBlockNumber: 28552915, diff --git a/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts b/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts index 06dd436767..48bfbf6b22 100644 --- a/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts @@ -66,6 +66,10 @@ export const ethereumFeeProxyArtifact = new ContractArtifact( address: '0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8', creationBlockNumber: 10307582, }, + goerli: { + address: '0xe11BF2fDA23bF0A98365e1A4c04A87C9339e8687', + creationBlockNumber: 7091386, + }, fantom: { address: '0xfCFBcfc4f5A421089e3Df45455F7f4985FE2D6a8', creationBlockNumber: 33495801, diff --git a/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts b/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts index 527cedbb78..b318578e54 100644 --- a/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts @@ -21,10 +21,6 @@ export const ethereumProxyArtifact = new ContractArtifact( address: '0x9c6c7817e3679c4b3f9ef9486001eae5aaed25ff', creationBlockNumber: 5955681, }, - goerli: { - address: '0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e', - creationBlockNumber: 7069045, - }, xdai: { address: '0x27c60BE17e853c47A9F1d280B05365f483c2dFAF', creationBlockNumber: 18326895, @@ -136,6 +132,10 @@ export const ethereumProxyArtifact = new ContractArtifact( address: '0x322F0037d272E980984F89E94Aae43BD0FC065E6', creationBlockNumber: 10307566, }, + goerli: { + address: '0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e', + creationBlockNumber: 7069045, + }, fantom: { address: '0x322F0037d272E980984F89E94Aae43BD0FC065E6', creationBlockNumber: 33496209,