From d28ae8f233021b2255ee7c6f3aec36c258371287 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Wed, 7 Feb 2024 01:48:52 +0100 Subject: [PATCH 01/14] refactor: chain manager WIP --- .circleci/config.yml | 19 +++ packages/advanced-logic/package.json | 1 + packages/advanced-logic/src/advanced-logic.ts | 6 +- .../payment-network/address-based.ts | 12 +- .../payment-network/any-to-native.ts | 6 +- .../bitcoin/mainnet-address-based.ts | 6 +- .../bitcoin/testnet-address-based.ts | 6 +- .../erc20/fee-proxy-contract.ts | 45 ++++-- .../payment-network/native-token.ts | 15 +- .../payment-network/near/any-to-near.ts | 2 +- .../payment-network/near/near-native.ts | 2 +- .../payment-network/any-to-eth-proxy.test.ts | 2 +- .../payment-network/any-to-near.test.ts | 2 +- .../payment-network/native-token.test.ts | 4 +- packages/chain/.nycrc | 8 ++ packages/chain/.vscode/settings.json | 5 + packages/chain/README.md | 40 ++++++ packages/chain/jest.config.js | 6 + packages/chain/package.json | 55 ++++++++ packages/chain/src/chain-manager.ts | 123 +++++++++++++++++ packages/chain/src/chains/btc/btc-chain.ts | 7 + .../chain/src/chains/btc/btc-ecosystem.ts | 7 + .../src/chains/btc/data/mainnet.ts | 0 .../src/chains/btc/data/testnet.ts | 0 packages/chain/src/chains/btc/index.ts | 13 ++ packages/chain/src/chains/chain-abstract.ts | 7 + .../src/chains/declarative/data/solana.ts | 0 .../src/chains/declarative/data/tron.ts | 0 .../chains/declarative/declarative-chain.ts | 7 + .../declarative/declarative-ecosystem.ts | 12 ++ .../chain/src/chains/declarative/index.ts | 13 ++ .../chain/src/chains/ecosystem-abstract.ts | 95 +++++++++++++ .../chain/src/chains/evm/data/alfajores.ts | 1 + .../chain/src/chains/evm/data/arbitrum-one.ts | 1 + .../src/chains/evm/data/arbitrum-rinkeby.ts | 2 + .../chain/src/chains/evm/data/avalanche.ts | 1 + packages/chain/src/chains/evm/data/bsc.ts | 1 + packages/chain/src/chains/evm/data/bsctest.ts | 1 + packages/chain/src/chains/evm/data/celo.ts | 1 + packages/chain/src/chains/evm/data/core.ts | 1 + packages/chain/src/chains/evm/data/fantom.ts | 1 + packages/chain/src/chains/evm/data/fuse.ts | 1 + .../src/chains/evm/data/goerli.ts} | 2 +- packages/chain/src/chains/evm/data/mainnet.ts | 1 + .../src/chains/evm/data/mantle-testnet.ts | 2 + packages/chain/src/chains/evm/data/mantle.ts | 1 + packages/chain/src/chains/evm/data/matic.ts | 1 + .../chain/src/chains/evm/data/moonbeam.ts | 1 + packages/chain/src/chains/evm/data/mumbai.ts | 2 + .../chain/src/chains/evm/data/optimism.ts | 1 + packages/chain/src/chains/evm/data/private.ts | 1 + .../src/chains/evm/data/rinkeby.ts} | 2 +- packages/chain/src/chains/evm/data/ronin.ts | 1 + packages/chain/src/chains/evm/data/sepolia.ts | 2 + packages/chain/src/chains/evm/data/sokol.ts | 1 + .../chain/src/chains/evm/data/tombchain.ts | 1 + packages/chain/src/chains/evm/data/xdai.ts | 1 + .../src/chains/evm/data/zksync-era-testnet.ts | 2 + .../chain/src/chains/evm/data/zksync-era.ts | 1 + packages/chain/src/chains/evm/evm-chain.ts | 7 + .../chain/src/chains/evm/evm-ecosystem.ts | 12 ++ .../src/chains/evm/index.ts | 13 +- .../src/chains/near/data/near-testnet.ts | 0 .../src/chains/near/data/near.ts | 0 packages/chain/src/chains/near/index.ts | 14 ++ packages/chain/src/chains/near/near-chain.ts | 7 + .../chain/src/chains/near/near-ecosystem.ts | 12 ++ packages/chain/src/chains/utils.ts | 14 ++ packages/chain/src/index.ts | 2 + packages/chain/src/types.ts | 7 + .../test/chain-utils.test.ts | 0 packages/chain/tsconfig.build.json | 12 ++ packages/chain/tsconfig.json | 7 + packages/currency/README.md | 23 +--- packages/currency/package.json | 1 + .../currency/src/chains/ChainsAbstract.ts | 95 ------------- packages/currency/src/chains/btc/BtcChains.ts | 6 - packages/currency/src/chains/btc/index.ts | 14 -- .../chains/declarative/DeclarativeChains.ts | 10 -- .../currency/src/chains/declarative/index.ts | 12 -- packages/currency/src/chains/evm/EvmChains.ts | 6 - .../currency/src/chains/evm/data/alfajores.ts | 1 - .../src/chains/evm/data/arbitrum-one.ts | 1 - .../src/chains/evm/data/arbitrum-rinkeby.ts | 2 - .../currency/src/chains/evm/data/avalanche.ts | 7 - packages/currency/src/chains/evm/data/bsc.ts | 7 - .../currency/src/chains/evm/data/bsctest.ts | 7 - packages/currency/src/chains/evm/data/celo.ts | 7 - packages/currency/src/chains/evm/data/core.ts | 1 - .../currency/src/chains/evm/data/fantom.ts | 7 - packages/currency/src/chains/evm/data/fuse.ts | 1 - .../currency/src/chains/evm/data/goerli.ts | 8 -- .../currency/src/chains/evm/data/mainnet.ts | 7 - .../currency/src/chains/evm/data/mantle.ts | 1 - .../currency/src/chains/evm/data/matic.ts | 7 - .../currency/src/chains/evm/data/moonbeam.ts | 7 - .../currency/src/chains/evm/data/mumbai.ts | 2 - .../currency/src/chains/evm/data/optimism.ts | 7 - .../currency/src/chains/evm/data/private.ts | 1 - .../currency/src/chains/evm/data/rinkeby.ts | 10 -- .../currency/src/chains/evm/data/ronin.ts | 1 - .../currency/src/chains/evm/data/sepolia.ts | 8 -- .../currency/src/chains/evm/data/sokol.ts | 1 - .../currency/src/chains/evm/data/tombchain.ts | 1 - packages/currency/src/chains/evm/data/xdai.ts | 7 - .../src/chains/evm/data/zksync-era.ts | 1 - packages/currency/src/chains/index.ts | 7 - .../currency/src/chains/near/NearChains.ts | 6 - packages/currency/src/chains/near/index.ts | 14 -- packages/currency/src/chains/utils.ts | 13 -- .../currency/src/conversion-aggregators.ts | 15 +- ...currencyManager.ts => currency-manager.ts} | 105 +++++++------- packages/currency/src/erc20/chains/index.ts | 3 +- packages/currency/src/erc20/index.ts | 28 ++-- packages/currency/src/erc777/chains/index.ts | 3 +- packages/currency/src/erc777/index.ts | 27 ++-- packages/currency/src/index.ts | 7 +- packages/currency/src/iso4217.ts | 22 ++- packages/currency/src/native.ts | 130 ++++++++---------- packages/currency/src/types.ts | 82 ++++++----- .../conversion-supported-currencies.test.ts | 6 +- packages/currency/test/currency/erc20.test.ts | 4 +- .../currency/test/currency/erc777.test.ts | 4 +- packages/ethereum-storage/src/config.ts | 2 +- .../src/ethereum-tx-submitter.ts | 2 +- .../scheduled/any-to-erc20-detector.test.ts | 2 +- .../scheduled/any-to-eth-detector.test.ts | 2 +- .../test/scheduled/erc20-fee-proxy.test.ts | 2 +- .../test/scheduled/erc777-stream.test.ts | 2 +- packages/integration-test/test/utils.ts | 8 +- .../src/any/any-to-erc20-proxy.ts | 8 +- .../src/any/any-to-eth-proxy.ts | 8 +- .../src/erc20/fee-proxy-contract.ts | 13 +- .../src/erc20/proxy-contract.ts | 6 +- .../src/erc20/transferable-receivable.ts | 6 +- .../src/erc777/superfluid-detector.ts | 9 +- .../src/erc777/superfluid-retriever.ts | 10 +- .../src/eth/fee-proxy-detector.ts | 6 +- .../payment-detection/src/eth/input-data.ts | 11 +- .../src/native-token-detector.ts | 2 +- .../src/near/near-conversion-detector.ts | 8 +- .../src/near/near-detector.ts | 6 +- .../near-conversion-info-retriever.ts | 4 +- .../near/retrievers/near-info-retriever.ts | 4 +- .../src/payment-network-factory.ts | 10 +- .../src/reference-based-detector.ts | 4 +- .../payment-detection/src/thegraph/client.ts | 12 +- .../src/thegraph/superfluid.ts | 7 +- packages/payment-detection/src/types.ts | 22 ++- packages/payment-detection/src/utils.ts | 5 +- .../any/any-to-erc20-proxy-contract.test.ts | 2 +- .../test/erc20/fee-proxy-contract.test.ts | 4 +- .../erc20/transferable-receivable.test.ts | 2 +- .../test/erc777/superfluid-detector.test.ts | 2 +- .../test/near/near-native-conversion.test.ts | 2 +- .../test/near/near-native.test.ts | 2 +- .../src/payment/batch-conversion-proxy.ts | 4 +- .../src/payment/utils-near.ts | 6 +- .../payment-processor/src/payment/utils.ts | 4 +- .../test/payment/batch-proxy.test.ts | 2 +- .../test/payment/encoder-approval.test.ts | 4 +- .../test/payment/encoder-payment.test.ts | 4 +- .../test/payment/erc20-batch-proxy.test.ts | 2 +- .../test/payment/erc20-escrow-payment.test.ts | 4 +- .../test/payment/erc20-fee-proxy.test.ts | 2 +- .../test/payment/erc20-proxy.test.ts | 2 +- .../test/payment/erc777-stream.test.ts | 2 +- .../test/payment/eth-batch-proxy.test.ts | 2 +- .../test/payment/eth-fee-proxy.test.ts | 2 +- .../test/payment/eth-input-data.test.ts | 2 +- .../test/payment/eth-proxy.test.ts | 2 +- .../test/payment/swap-erc20-fee-proxy.test.ts | 8 +- packages/request-client.js/src/api/request.ts | 2 +- .../src/http-metamask-data-access.ts | 2 +- packages/request-node/src/dataAccess.ts | 2 +- .../deploy/deploy-zk-batch-contracts.ts | 4 +- .../scripts-create2/constructor-args.ts | 5 +- .../contract-setup/adminTasks.ts | 6 +- .../contract-setup/execute-contract-method.ts | 2 +- .../setupBatchConversionPayments.ts | 2 +- .../scripts-create2/tenderly.ts | 2 +- .../src/lib/ContractArtifact.ts | 23 ++-- .../smart-contracts/test/lib/artifact.test.ts | 2 +- .../src/chainlinkConversionPathTools.ts | 4 +- .../commands/chainlink/aggregatorsUtils.ts | 8 +- packages/types/src/advanced-logic-types.ts | 7 +- packages/types/src/chain-types.ts | 85 ++++++++++++ packages/types/src/currency-types.ts | 54 -------- .../pn-any-reference-based-types.ts | 3 +- .../pn-any-to-any-conversion-types.ts | 4 +- .../src/extensions/pn-any-to-erc20-types.ts | 4 +- packages/types/src/index.ts | 4 +- packages/types/src/payment-types.ts | 4 +- packages/types/src/request-logic-types.ts | 3 +- 194 files changed, 1091 insertions(+), 808 deletions(-) create mode 100644 packages/chain/.nycrc create mode 100644 packages/chain/.vscode/settings.json create mode 100644 packages/chain/README.md create mode 100644 packages/chain/jest.config.js create mode 100644 packages/chain/package.json create mode 100644 packages/chain/src/chain-manager.ts create mode 100644 packages/chain/src/chains/btc/btc-chain.ts create mode 100644 packages/chain/src/chains/btc/btc-ecosystem.ts rename packages/{currency => chain}/src/chains/btc/data/mainnet.ts (100%) rename packages/{currency => chain}/src/chains/btc/data/testnet.ts (100%) create mode 100644 packages/chain/src/chains/btc/index.ts create mode 100644 packages/chain/src/chains/chain-abstract.ts rename packages/{currency => chain}/src/chains/declarative/data/solana.ts (100%) rename packages/{currency => chain}/src/chains/declarative/data/tron.ts (100%) create mode 100644 packages/chain/src/chains/declarative/declarative-chain.ts create mode 100644 packages/chain/src/chains/declarative/declarative-ecosystem.ts create mode 100644 packages/chain/src/chains/declarative/index.ts create mode 100644 packages/chain/src/chains/ecosystem-abstract.ts create mode 100644 packages/chain/src/chains/evm/data/alfajores.ts create mode 100644 packages/chain/src/chains/evm/data/arbitrum-one.ts create mode 100644 packages/chain/src/chains/evm/data/arbitrum-rinkeby.ts create mode 100644 packages/chain/src/chains/evm/data/avalanche.ts create mode 100644 packages/chain/src/chains/evm/data/bsc.ts create mode 100644 packages/chain/src/chains/evm/data/bsctest.ts create mode 100644 packages/chain/src/chains/evm/data/celo.ts create mode 100644 packages/chain/src/chains/evm/data/core.ts create mode 100644 packages/chain/src/chains/evm/data/fantom.ts create mode 100644 packages/chain/src/chains/evm/data/fuse.ts rename packages/{currency/src/chains/evm/data/zksync-era-testnet.ts => chain/src/chains/evm/data/goerli.ts} (50%) create mode 100644 packages/chain/src/chains/evm/data/mainnet.ts create mode 100644 packages/chain/src/chains/evm/data/mantle-testnet.ts create mode 100644 packages/chain/src/chains/evm/data/mantle.ts create mode 100644 packages/chain/src/chains/evm/data/matic.ts create mode 100644 packages/chain/src/chains/evm/data/moonbeam.ts create mode 100644 packages/chain/src/chains/evm/data/mumbai.ts create mode 100644 packages/chain/src/chains/evm/data/optimism.ts create mode 100644 packages/chain/src/chains/evm/data/private.ts rename packages/{currency/src/chains/evm/data/mantle-testnet.ts => chain/src/chains/evm/data/rinkeby.ts} (50%) create mode 100644 packages/chain/src/chains/evm/data/ronin.ts create mode 100644 packages/chain/src/chains/evm/data/sepolia.ts create mode 100644 packages/chain/src/chains/evm/data/sokol.ts create mode 100644 packages/chain/src/chains/evm/data/tombchain.ts create mode 100644 packages/chain/src/chains/evm/data/xdai.ts create mode 100644 packages/chain/src/chains/evm/data/zksync-era-testnet.ts create mode 100644 packages/chain/src/chains/evm/data/zksync-era.ts create mode 100644 packages/chain/src/chains/evm/evm-chain.ts create mode 100644 packages/chain/src/chains/evm/evm-ecosystem.ts rename packages/{currency => chain}/src/chains/evm/index.ts (89%) rename packages/{currency => chain}/src/chains/near/data/near-testnet.ts (100%) rename packages/{currency => chain}/src/chains/near/data/near.ts (100%) create mode 100644 packages/chain/src/chains/near/index.ts create mode 100644 packages/chain/src/chains/near/near-chain.ts create mode 100644 packages/chain/src/chains/near/near-ecosystem.ts create mode 100644 packages/chain/src/chains/utils.ts create mode 100644 packages/chain/src/index.ts create mode 100644 packages/chain/src/types.ts rename packages/{currency => chain}/test/chain-utils.test.ts (100%) create mode 100644 packages/chain/tsconfig.build.json create mode 100644 packages/chain/tsconfig.json delete mode 100644 packages/currency/src/chains/ChainsAbstract.ts delete mode 100644 packages/currency/src/chains/btc/BtcChains.ts delete mode 100644 packages/currency/src/chains/btc/index.ts delete mode 100644 packages/currency/src/chains/declarative/DeclarativeChains.ts delete mode 100644 packages/currency/src/chains/declarative/index.ts delete mode 100644 packages/currency/src/chains/evm/EvmChains.ts delete mode 100644 packages/currency/src/chains/evm/data/alfajores.ts delete mode 100644 packages/currency/src/chains/evm/data/arbitrum-one.ts delete mode 100644 packages/currency/src/chains/evm/data/arbitrum-rinkeby.ts delete mode 100644 packages/currency/src/chains/evm/data/avalanche.ts delete mode 100644 packages/currency/src/chains/evm/data/bsc.ts delete mode 100644 packages/currency/src/chains/evm/data/bsctest.ts delete mode 100644 packages/currency/src/chains/evm/data/celo.ts delete mode 100644 packages/currency/src/chains/evm/data/core.ts delete mode 100644 packages/currency/src/chains/evm/data/fantom.ts delete mode 100644 packages/currency/src/chains/evm/data/fuse.ts delete mode 100644 packages/currency/src/chains/evm/data/goerli.ts delete mode 100644 packages/currency/src/chains/evm/data/mainnet.ts delete mode 100644 packages/currency/src/chains/evm/data/mantle.ts delete mode 100644 packages/currency/src/chains/evm/data/matic.ts delete mode 100644 packages/currency/src/chains/evm/data/moonbeam.ts delete mode 100644 packages/currency/src/chains/evm/data/mumbai.ts delete mode 100644 packages/currency/src/chains/evm/data/optimism.ts delete mode 100644 packages/currency/src/chains/evm/data/private.ts delete mode 100644 packages/currency/src/chains/evm/data/rinkeby.ts delete mode 100644 packages/currency/src/chains/evm/data/ronin.ts delete mode 100644 packages/currency/src/chains/evm/data/sepolia.ts delete mode 100644 packages/currency/src/chains/evm/data/sokol.ts delete mode 100644 packages/currency/src/chains/evm/data/tombchain.ts delete mode 100644 packages/currency/src/chains/evm/data/xdai.ts delete mode 100644 packages/currency/src/chains/evm/data/zksync-era.ts delete mode 100644 packages/currency/src/chains/index.ts delete mode 100644 packages/currency/src/chains/near/NearChains.ts delete mode 100644 packages/currency/src/chains/near/index.ts delete mode 100644 packages/currency/src/chains/utils.ts rename packages/currency/src/{currencyManager.ts => currency-manager.ts} (77%) create mode 100644 packages/types/src/chain-types.ts delete mode 100644 packages/types/src/currency-types.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index fd0d8d2cdb..99725cf279 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -81,6 +81,9 @@ jobs: - run: name: Build utils command: yarn workspace @requestnetwork/utils run build + - run: + name: Build chain + command: yarn workspace @requestnetwork/chain run build - run: name: Build currency command: yarn workspace @requestnetwork/currency run build @@ -284,6 +287,18 @@ jobs: command: 'yarn workspace @requestnetwork/utils run test --ci --maxWorkers=1' - store_test_results: path: packages/utils/reports/ + test-chain: + docker: + - *node_image + working_directory: *working_directory + steps: + - attach_workspace: + at: *working_directory + - run: + name: 'Test chain' + command: 'yarn workspace @requestnetwork/chain run test --ci --maxWorkers=1' + - store_test_results: + path: packages/chain/reports/ test-currency: docker: - *node_image @@ -555,6 +570,9 @@ workflows: - test-utils: requires: - build + - test-chain: + requires: + - build - test-currency: requires: - build @@ -588,6 +606,7 @@ workflows: requires: - lint - test-advanced-logic + - test-chain - test-currency - test-data-access - test-data-format diff --git a/packages/advanced-logic/package.json b/packages/advanced-logic/package.json index efcd5cb32d..0b854fc74f 100644 --- a/packages/advanced-logic/package.json +++ b/packages/advanced-logic/package.json @@ -39,6 +39,7 @@ "test:watch": "yarn test --watch" }, "dependencies": { + "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/types": "0.40.0", "@requestnetwork/utils": "0.40.0", diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index 4784ee0179..4f3bf88bc1 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -147,7 +147,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic } public getNativeTokenExtensionForNetwork( - network?: CurrencyTypes.ChainName, + network?: ChainTypes.IChain, ): ExtensionTypes.IExtension | undefined { return network ? this.extensions.nativeToken.find((nativeTokenExtension) => @@ -157,7 +157,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic } public getAnyToNativeTokenExtensionForNetwork( - network?: CurrencyTypes.ChainName, + network?: ChainTypes.IChain, ): AnyToNative | undefined { return network ? this.extensions.anyToNativeToken.find((anyToNativeTokenExtension) => @@ -175,7 +175,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic protected getNetwork( extensionAction: ExtensionTypes.IAction, requestState: RequestLogicTypes.IRequest, - ): CurrencyTypes.ChainName | undefined { + ): ChainTypes.IChain | undefined { if ( requestState.currency.network && extensionAction.parameters.paymentNetworkName && diff --git a/packages/advanced-logic/src/extensions/payment-network/address-based.ts b/packages/advanced-logic/src/extensions/payment-network/address-based.ts index c9a3f12985..407f3cd42b 100644 --- a/packages/advanced-logic/src/extensions/payment-network/address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/address-based.ts @@ -1,6 +1,6 @@ import { ICurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { - CurrencyTypes, + ChainTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -151,7 +151,11 @@ export default abstract class AddressBasedPaymentNetwork< case RequestLogicTypes.CURRENCY.ETH: case RequestLogicTypes.CURRENCY.ERC20: case RequestLogicTypes.CURRENCY.ERC777: - return this.isValidAddressForSymbolAndNetwork(address, 'ETH', 'mainnet'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'ETH', + this.currencyManager.chainManager.fromName('mainnet', ['evm']), + ); default: throw new Error( `Default implementation of isValidAddressForNetwork() does not support currency type ${this.supportedCurrencyType}. Please override this method if needed.`, @@ -162,11 +166,11 @@ export default abstract class AddressBasedPaymentNetwork< protected isValidAddressForSymbolAndNetwork( address: string, symbol: string, - network: CurrencyTypes.ChainName, + network: ChainTypes.IChain, ): boolean { const currency = this.currencyManager.from(symbol, network); if (!currency) { - throw new UnsupportedCurrencyError({ value: symbol, network }); + throw new UnsupportedCurrencyError({ value: symbol, network: network.name }); } return this.currencyManager.validateAddress(address, currency); } diff --git a/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts b/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts index 2c0fead29f..48ae797f20 100644 --- a/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts @@ -8,7 +8,7 @@ export default abstract class AnyToNativeTokenPaymentNetwork extends FeeReferenc currencyManager: ICurrencyManager, extensionId: ExtensionTypes.PAYMENT_NETWORK_ID, currentVersion: string, - public readonly supportedNetworks: CurrencyTypes.ChainName[], + public readonly supportedNetworks: ChainTypes.IChain[], ) { super(currencyManager, extensionId, currentVersion, RequestLogicTypes.CURRENCY.ETH); } @@ -47,8 +47,8 @@ export default abstract class AnyToNativeTokenPaymentNetwork extends FeeReferenc } protected throwIfInvalidNetwork( - network?: CurrencyTypes.ChainName, - ): asserts network is CurrencyTypes.ChainName { + network?: ChainTypes.IChain, + ): asserts network is ChainTypes.IChain { super.throwIfInvalidNetwork(network); if (this.supportedNetworks && !this.supportedNetworks.includes(network)) { throw new UnsupportedNetworkError(network, this.supportedNetworks); diff --git a/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts b/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts index e8ca2ab647..707e36ed63 100644 --- a/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts @@ -21,6 +21,10 @@ export default class BitcoinAddressBasedPaymentNetwork extends AddressBasedPayme } protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'BTC', BITCOIN_NETWORK); + return this.isValidAddressForSymbolAndNetwork( + address, + 'BTC', + this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, ['btc']), + ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts b/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts index 962d62d51b..0478879d6f 100644 --- a/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts @@ -17,6 +17,10 @@ export default class BitcoinTestnetAddressBasedPaymentNetwork extends BitcoinAdd } protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'BTC-testnet', BITCOIN_NETWORK); + return this.isValidAddressForSymbolAndNetwork( + address, + 'BTC-testnet', + this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, ['btc']), + ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts index d156322edb..33222c778f 100644 --- a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts +++ b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts @@ -1,7 +1,8 @@ -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { ICurrencyManager, NearChains, isSameChain } from '@requestnetwork/currency'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ICurrencyManager } from '@requestnetwork/currency'; import { UnsupportedNetworkError } from '../address-based'; import { FeeReferenceBasedPaymentNetwork } from '../fee-reference-based'; +import { ChainManager } from '@requestnetwork/chain'; const EVM_CURRENT_VERSION = '0.2.0'; const NEAR_CURRENT_VERSION = 'NEAR-0.1.0'; @@ -21,18 +22,27 @@ export default class Erc20FeeProxyPaymentNetwork< extensionId: ExtensionTypes.PAYMENT_NETWORK_ID = ExtensionTypes.PAYMENT_NETWORK_ID .ERC20_FEE_PROXY_CONTRACT, currentVersion?: string | undefined, - protected network?: string | undefined, + protected network?: ChainTypes.IChain | undefined, ) { super( currencyManager, extensionId, - currentVersion ?? Erc20FeeProxyPaymentNetwork.getDefaultCurrencyVersion(network), + currentVersion ?? + Erc20FeeProxyPaymentNetwork.getDefaultCurrencyVersion( + currencyManager.chainManager, + network, + ), RequestLogicTypes.CURRENCY.ERC20, ); } - protected static getDefaultCurrencyVersion(network?: string): string { - return NearChains.isChainSupported(network) ? NEAR_CURRENT_VERSION : EVM_CURRENT_VERSION; + protected static getDefaultCurrencyVersion( + chainManager: ChainManager, + network?: ChainTypes.IChain | undefined, + ): string { + return chainManager.ecosystems.near.isChainSupported(network) + ? NEAR_CURRENT_VERSION + : EVM_CURRENT_VERSION; } // Override `validate` to account for network-specific instanciation (non-EVM only) @@ -43,20 +53,31 @@ export default class Erc20FeeProxyPaymentNetwork< if ( this.network && request.currency.network && - !isSameChain(this.network, request.currency.network) + !this.currencyManager.chainManager.isSameChain(this.network, request.currency.network, [ + 'evm', + 'near', + ]) ) { - throw new UnsupportedNetworkError(request.currency.network, [this.network]); + throw new UnsupportedNetworkError(request.currency.network, [this.network.name]); } super.validate(request, extensionAction); } // Override `isValidAddress` to account for network-specific instanciation (non-EVM only) protected isValidAddress(address: string): boolean { - if (NearChains.isChainSupported(this.network)) { - if (NearChains.isTestnet(this.network as CurrencyTypes.NearChainName)) { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR-testnet', 'near-testnet'); + if (this.currencyManager.chainManager.ecosystems['near'].isChainSupported(this.network)) { + if (this.network?.testnet) { + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR-testnet', + this.currencyManager.chainManager.fromName('near-testnet', ['near']), + ); } else { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR', 'near'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR', + this.currencyManager.chainManager.fromName('near', ['near']), + ); } } else { return super.isValidAddress(address); diff --git a/packages/advanced-logic/src/extensions/payment-network/native-token.ts b/packages/advanced-logic/src/extensions/payment-network/native-token.ts index 03548c40eb..e4b7acd48b 100644 --- a/packages/advanced-logic/src/extensions/payment-network/native-token.ts +++ b/packages/advanced-logic/src/extensions/payment-network/native-token.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-based'; import ReferenceBasedPaymentNetwork from './reference-based'; @@ -12,7 +12,7 @@ export default abstract class NativeTokenPaymentNetwork extends ReferenceBasedPa currencyManager: ICurrencyManager, extensionId: ExtensionTypes.PAYMENT_NETWORK_ID, currentVersion: string, - public readonly supportedNetworks: CurrencyTypes.ChainName[], + public readonly supportedNetworks: ChainTypes.IChain[], ) { super(currencyManager, extensionId, currentVersion, RequestLogicTypes.CURRENCY.ETH); } @@ -53,11 +53,14 @@ export default abstract class NativeTokenPaymentNetwork extends ReferenceBasedPa } protected throwIfInvalidNetwork( - network?: CurrencyTypes.ChainName, - ): asserts network is CurrencyTypes.ChainName { - super.throwIfInvalidNetwork(network); + network?: ChainTypes.IChain, + ): asserts network is ChainTypes.IChain { + super.throwIfInvalidNetwork(network?.name); if (this.supportedNetworks && !this.supportedNetworks.includes(network)) { - throw new UnsupportedNetworkError(network, this.supportedNetworks); + throw new UnsupportedNetworkError( + network?.name, + this.supportedNetworks.map((n) => n.name), + ); } } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts index 187550fee6..db97871f6a 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts @@ -12,7 +12,7 @@ const CURRENT_VERSION = '0.1.0'; export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetwork { public constructor( currencyManager: ICurrencyManager, - supportedNetworks: CurrencyTypes.NearChainName[] = [ + supportedNetworks: ChainTypes.INearChain[] = [ 'aurora', // FIXME: enable near network support // 'near' diff --git a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts index 245ebf40e7..0ff41fc0fe 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts @@ -10,7 +10,7 @@ const CURRENT_VERSION = '0.2.0'; export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork { public constructor( currencyManager: ICurrencyManager, - supportedNetworks: CurrencyTypes.NearChainName[] = [ + supportedNetworks: ChainTypes.INearChain[] = [ 'aurora', // FIXME: enable near network support // 'near' diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts index 8525fbcdb4..a05c8b45d2 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts @@ -146,7 +146,7 @@ describe('extensions/payment-network/ethereum/any-to-eth-fee-proxy-contract', () requestCreatedNoExtension.currency = { type: RequestLogicTypes.CURRENCY.ETH, value: 'invalid value', - network: 'invalid network' as CurrencyTypes.EvmChainName, + network: 'invalid network' as ChainTypes.IEvmChain, }; const action: ExtensionTypes.IAction = deepCopy( diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts index ce3f3daa2f..57a87589e6 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts @@ -206,7 +206,7 @@ describe('extensions/payment-network/any-to-native-token', () => { expect(() => { new AnyToNearPaymentNetwork(currencyManager).createCreationAction({ ...partialCreationParams, - network: 'another-chain' as CurrencyTypes.NearChainName, + network: 'another-chain' as ChainTypes.INearChain, }); }).toThrowError( `Payment network 'another-chain' is not supported by this extension (only aurora)`, diff --git a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts index e6a2be6c7e..bfd6985d8c 100644 --- a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts @@ -154,7 +154,7 @@ describe('extensions/payment-network/native-token', () => { expect(() => { new NearNativePaymentNetwork(currencyManager).createCreationAction({ ...partialCreationParams, - paymentNetworkName: 'another-chain' as CurrencyTypes.NearChainName, + paymentNetworkName: 'another-chain' as ChainTypes.INearChain, }); }).toThrowError( `Payment network 'another-chain' is not supported by this extension (only aurora)`, @@ -331,7 +331,7 @@ describe('extensions/payment-network/native-token', () => { }); it('throws on a wrong payment network', () => { const advancedLogic = new AdvancedLogic(currencyManager); - const wrongNetwork = `wrong network` as CurrencyTypes.EvmChainName; + const wrongNetwork = `wrong network` as ChainTypes.IEvmChain; const wrongNativeTokenRequestState: typeof requestStateNoExtensions = { ...requestStateNoExtensions, diff --git a/packages/chain/.nycrc b/packages/chain/.nycrc new file mode 100644 index 0000000000..7d71de2515 --- /dev/null +++ b/packages/chain/.nycrc @@ -0,0 +1,8 @@ +{ + "extension": [".ts"], + "include": ["src/*.ts", "src/**/*.ts"], + "require": ["ts-node/register"], + "reporter": ["text-summary", "json", "html"], + "sourceMap": true, + "all": true +} diff --git a/packages/chain/.vscode/settings.json b/packages/chain/.vscode/settings.json new file mode 100644 index 0000000000..379bec3a42 --- /dev/null +++ b/packages/chain/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "mochaExplorer.files": "**/test/**/*.ts", + "mochaExplorer.require": "ts-node/register", + "mochaExplorer.cwd": "../.." +} diff --git a/packages/chain/README.md b/packages/chain/README.md new file mode 100644 index 0000000000..dbcf3e4409 --- /dev/null +++ b/packages/chain/README.md @@ -0,0 +1,40 @@ +# @requestnetwork/chain + +`@requestnetwork/chain` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork). +It is a collection of tools for the currencies and chains shared between the @requestnetwork packages. + +## Installation + +```bash +npm install @requestnetwork/chain +``` + +## Contributing + +Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. +[Read the contributing guide](/CONTRIBUTING.md) + +### Adding a new chain + +Supported chains are listed in `src/chains`: + +- `src/chains/btc/data` for BTC type chains +- `src/chains/evm/data` for EVM type chains +- `src/chains/near/data` for NEAR type chains + +The chain names are subjective, but they are unique and uniform across all Request Network packages. +They are formatted with the kebab-case naming convention. + +In order to add a new chain, first create a file `[nameOfTheChain].ts` in the correct directory. +Its internal structure should conform with the corresponding type, respectively: + +- `BtcChain` +- `EvmChain` +- `NearChain` + +These types are described in the `index.ts` file of each chain subdirectory. +Please add the `testnet: true` property for staging chains. + +## License + +[MIT](/LICENSE) diff --git a/packages/chain/jest.config.js b/packages/chain/jest.config.js new file mode 100644 index 0000000000..be20f1cb6c --- /dev/null +++ b/packages/chain/jest.config.js @@ -0,0 +1,6 @@ +const jestCommonConfig = require('../../jest.config'); + +/** @type {import('jest').Config} */ +module.exports = { + ...jestCommonConfig, +}; diff --git a/packages/chain/package.json b/packages/chain/package.json new file mode 100644 index 0000000000..71a16f8434 --- /dev/null +++ b/packages/chain/package.json @@ -0,0 +1,55 @@ +{ + "name": "@requestnetwork/chain", + "version": "0.13.0", + "publishConfig": { + "access": "public" + }, + "description": "Chain tools for Request Network packages.", + "keywords": [ + "requestnetwork", + "chain", + "utils" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/RequestNetwork/requestNetwork.git" + }, + "homepage": "https://github.com/RequestNetwork/requestNetwork/tree/master/packages/chain#readme", + "bugs": { + "url": "https://github.com/RequestNetwork/requestNetwork/issues" + }, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "directories": { + "lib": "src", + "test": "test" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsc -b tsconfig.build.json", + "clean": "rm -rf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo", + "lint": "eslint . --fix", + "lint:check": "eslint .", + "prepare": "yarn run build", + "test": "jest", + "test:watch": "yarn test --watch" + }, + "dependencies": { + "@requestnetwork/types": "0.40.0" + }, + "devDependencies": { + "@types/jest": "29.5.6", + "jest": "29.5.0", + "jest-junit": "16.0.0", + "source-map-support": "0.5.19", + "ts-jest": "29.1.0", + "ts-node": "10.9.1", + "typescript": "5.1.3" + } +} diff --git a/packages/chain/src/chain-manager.ts b/packages/chain/src/chain-manager.ts new file mode 100644 index 0000000000..06e12eb8f7 --- /dev/null +++ b/packages/chain/src/chain-manager.ts @@ -0,0 +1,123 @@ +import { ChainDefinition } from './types'; +import { EcosystemAbstract } from './chains/ecosystem-abstract'; +import BtcEcosystem from './chains/btc/btc-ecosystem'; +import DeclarativeEcosystem from './chains/declarative/declarative-ecosystem'; +import EvmEcosystem from './chains/evm/evm-ecosystem'; +import NearEcosystem from './chains/near/near-ecosystem'; +import { initializeChains } from './chains/utils'; +import { ChainTypes } from '@requestnetwork/types'; + +export class ChainManager { + private static defaultInstance: ChainManager; + + public ecosystems: Record> = { + btc: BtcEcosystem, + declarative: DeclarativeEcosystem, + evm: EvmEcosystem, + near: NearEcosystem, + }; + + constructor(inputChains?: Record>) { + if (!inputChains) return; + for (const ecosystemName in this.ecosystems) { + const ecosystem = this.ecosystems[ecosystemName as ChainTypes.ChainEcosystem]; + if (!inputChains[ecosystem.name]) continue; + const chainDefinitions = inputChains[ecosystem.name]; + const chains = initializeChains(ecosystem.chainClass, chainDefinitions); + Object.assign(ecosystem.chains, chains); + } + } + + /** + * Returns the list of supported chains + */ + get chains(): ChainTypes.IChain[] { + return Object.keys(this.ecosystems).reduce((chains, ecosystemName) => { + return chains.concat( + Object.values(this.ecosystems[ecosystemName as ChainTypes.ChainEcosystem].chains), + ); + }, [] as ChainTypes.IChain[]); + } + + static getName(chain: string | ChainTypes.IChain): string { + if (typeof chain === 'string') return chain.toLowerCase(); + return chain.name; + } + + /** + * Gets a supported chain from its name + */ + fromName( + chainName: string, + ecosystemsFilter?: T, + ): ChainTypes.ChainTypeByEcosystem[T[number]] { + const chains = this.chains.filter( + (chain) => + chain.name === chainName && + (ecosystemsFilter ? ecosystemsFilter.includes(chain.ecosystem) : true), + ); + if (chains.length < 1) { + throw new Error( + `No chain found with name "${chainName}" for ecosystem(s) "${ecosystemsFilter}"`, + ); + } + if (chains.length > 1) { + throw new Error( + `There is more than one chain named "${chainName}" for ecosystem(s) "${ecosystemsFilter}"`, + ); + } + return chains[0] as ChainTypes.ChainTypeByEcosystem[T[number]]; + } + + /** + * Gets a supported chain from its ID + */ + fromId( + chainId: string, + ecosystemsFilter?: T, + ): ChainTypes.ChainTypeByEcosystem[T[number]] { + const chains = this.chains.filter( + (chain) => + chain.id === chainId && + (ecosystemsFilter ? ecosystemsFilter.includes(chain.ecosystem) : true), + ); + if (chains.length < 1) { + throw new Error(`No chain found with ID "${chainId}" for ecosystem(s) "${ecosystemsFilter}"`); + } + if (chains.length > 1) { + throw new Error( + `There is more than one chain with ID "${chainId}" for ecosystem(s) "${ecosystemsFilter}"`, + ); + } + return chains[0] as ChainTypes.ChainTypeByEcosystem[T[number]]; + } + + static getDefault(): ChainManager { + if (this.defaultInstance) return this.defaultInstance; + + this.defaultInstance = new ChainManager(); + return this.defaultInstance; + } + + /** + * Returns true if both chains are equal or aliases. + * The third argument "chainsEcosystem" is only needed when comparing chains as strings. + */ + isSameChain = ( + chain1: string | ChainTypes.IChain, + chain2: string | ChainTypes.IChain, + chainsEcosystem?: ChainTypes.ChainEcosystem[], + ): boolean => { + const chain1Object = + typeof chain1 === 'string' ? this.fromName(chain1, chainsEcosystem) : chain1; + const chain2Object = + typeof chain2 === 'string' ? this.fromName(chain2, chainsEcosystem) : chain2; + return ( + chain1Object === chain2Object || + this.ecosystems[chain1Object.ecosystem].isSameChainFromString( + chain1Object.name, + chain2Object.name, + ) + ); + }; +} diff --git a/packages/chain/src/chains/btc/btc-chain.ts b/packages/chain/src/chains/btc/btc-chain.ts new file mode 100644 index 0000000000..cc9be4e65a --- /dev/null +++ b/packages/chain/src/chains/btc/btc-chain.ts @@ -0,0 +1,7 @@ +import { ChainAbstract } from '../chain-abstract'; +import { RequestLogicTypes } from '@requestnetwork/types'; + +export class BtcChain extends ChainAbstract { + public readonly ecosystem = 'btc'; + public readonly currenciesType = RequestLogicTypes.CURRENCY.BTC; +} diff --git a/packages/chain/src/chains/btc/btc-ecosystem.ts b/packages/chain/src/chains/btc/btc-ecosystem.ts new file mode 100644 index 0000000000..2129139f75 --- /dev/null +++ b/packages/chain/src/chains/btc/btc-ecosystem.ts @@ -0,0 +1,7 @@ +import { EcosystemAbstract } from '../ecosystem-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { chains } from './index'; +import { BtcChain } from './btc-chain'; + +class BtcEcosystem extends EcosystemAbstract {} +export default new BtcEcosystem('btc', BtcChain, chains, RequestLogicTypes.CURRENCY.BTC); diff --git a/packages/currency/src/chains/btc/data/mainnet.ts b/packages/chain/src/chains/btc/data/mainnet.ts similarity index 100% rename from packages/currency/src/chains/btc/data/mainnet.ts rename to packages/chain/src/chains/btc/data/mainnet.ts diff --git a/packages/currency/src/chains/btc/data/testnet.ts b/packages/chain/src/chains/btc/data/testnet.ts similarity index 100% rename from packages/currency/src/chains/btc/data/testnet.ts rename to packages/chain/src/chains/btc/data/testnet.ts diff --git a/packages/chain/src/chains/btc/index.ts b/packages/chain/src/chains/btc/index.ts new file mode 100644 index 0000000000..75859a1bf4 --- /dev/null +++ b/packages/chain/src/chains/btc/index.ts @@ -0,0 +1,13 @@ +import { ChainDefinition } from '../../types'; + +import * as MainnetDefinition from './data/mainnet'; +import * as TestnetDefinition from './data/testnet'; +import { BtcChain } from './btc-chain'; +import { initializeChains } from '../utils'; + +const chainDefinitions: Record = { + mainnet: MainnetDefinition, + testnet: TestnetDefinition, +}; + +export const chains = initializeChains(BtcChain, chainDefinitions); diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts new file mode 100644 index 0000000000..98933cd53b --- /dev/null +++ b/packages/chain/src/chains/chain-abstract.ts @@ -0,0 +1,7 @@ +export abstract class ChainAbstract { + constructor( + public readonly id: string, + public readonly name: string, + public readonly testnet: boolean = false, + ) {} +} diff --git a/packages/currency/src/chains/declarative/data/solana.ts b/packages/chain/src/chains/declarative/data/solana.ts similarity index 100% rename from packages/currency/src/chains/declarative/data/solana.ts rename to packages/chain/src/chains/declarative/data/solana.ts diff --git a/packages/currency/src/chains/declarative/data/tron.ts b/packages/chain/src/chains/declarative/data/tron.ts similarity index 100% rename from packages/currency/src/chains/declarative/data/tron.ts rename to packages/chain/src/chains/declarative/data/tron.ts diff --git a/packages/chain/src/chains/declarative/declarative-chain.ts b/packages/chain/src/chains/declarative/declarative-chain.ts new file mode 100644 index 0000000000..d4b6b9b7e6 --- /dev/null +++ b/packages/chain/src/chains/declarative/declarative-chain.ts @@ -0,0 +1,7 @@ +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainAbstract } from '../chain-abstract'; + +export class DeclarativeChain extends ChainAbstract implements ChainTypes.IDeclarativeChain { + public readonly ecosystem = 'declarative'; + public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; +} diff --git a/packages/chain/src/chains/declarative/declarative-ecosystem.ts b/packages/chain/src/chains/declarative/declarative-ecosystem.ts new file mode 100644 index 0000000000..b3efbb7f1a --- /dev/null +++ b/packages/chain/src/chains/declarative/declarative-ecosystem.ts @@ -0,0 +1,12 @@ +import { EcosystemAbstract } from '../ecosystem-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { DeclarativeChain } from './declarative-chain'; +import { chains } from './index'; + +class DeclarativeEcosystem extends EcosystemAbstract { + constructor(chains: Record) { + super('declarative', DeclarativeChain, chains, RequestLogicTypes.CURRENCY.ETH); + } +} + +export default new DeclarativeEcosystem(chains); diff --git a/packages/chain/src/chains/declarative/index.ts b/packages/chain/src/chains/declarative/index.ts new file mode 100644 index 0000000000..d0f88a8e39 --- /dev/null +++ b/packages/chain/src/chains/declarative/index.ts @@ -0,0 +1,13 @@ +import { ChainDefinition } from '../../types'; + +import * as TronDefinition from './data/tron'; +import * as SolanaDefinition from './data/solana'; +import { DeclarativeChain } from './declarative-chain'; +import { initializeChains } from '../utils'; + +const chainDefinitions: Record = { + tron: TronDefinition, + solana: SolanaDefinition, +}; + +export const chains = initializeChains(DeclarativeChain, chainDefinitions); diff --git a/packages/chain/src/chains/ecosystem-abstract.ts b/packages/chain/src/chains/ecosystem-abstract.ts new file mode 100644 index 0000000000..304260661d --- /dev/null +++ b/packages/chain/src/chains/ecosystem-abstract.ts @@ -0,0 +1,95 @@ +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainAbstract } from './chain-abstract'; + +export abstract class EcosystemAbstract { + constructor( + public name: ChainTypes.ChainEcosystem, + public chainClass: new (id: string, name: string, testnet?: boolean) => CHAIN, + public chains: Record, + public currencyType: RequestLogicTypes.CURRENCY, + ) { + // this.addNativeCurrenciesToChains(currencyType); + } + + get chainNames(): string[] { + return Object.keys(this.chains); + } + + /** + * Adds the native currency to the list of currencies supported by each chain + */ + // private addNativeCurrenciesToChains( + // currencyType: RequestLogicTypes.CURRENCY.ETH | RequestLogicTypes.CURRENCY.BTC, + // ): void { + // this.chainNames.forEach((chainName) => { + // const nativeCurrency = ( + // nativeCurrencies[currencyType] as CurrencyTypes.NamedNativeCurrency[] + // ).find((currency) => currency.network === chainName); + // if (nativeCurrency) { + // const chainCurrencies: TokenMap = this.chains[chainName].currencies || {}; + // chainCurrencies.native = nativeCurrency; + // this.chains[chainName].currencies = chainCurrencies; + // } + // }); + // } + + /** + * Check if chainName lives amongst the list of supported chains by this chain type. + * Throws in the case it's not supported. + */ + public assertChainNameSupported(chainName?: string) { + if (!this.isChainSupported(chainName)) throw new Error(`Unsupported chain ${chainName}`); + } + + /** + * Check if chainName lives amongst the list of supported chains by this chain type. + * Throws in the case it's not supported. + */ + public assertChainSupported(chain?: ChainAbstract): asserts chain is CHAIN { + if (!this.isChainSupported(chain)) throw new Error(`Unsupported chain ${chain?.name}`); + } + + /** + * Check if chainName lives amongst the list of supported chains by this chain type. + */ + public isChainSupported(chainName?: string | ChainAbstract) { + return ( + !!chainName && + this.chainNames.includes(chainName instanceof ChainAbstract ? chainName.name : chainName) + ); + } + + /** + * Retrieve the corresponding chain ID from Request Network's internal chain name representation + */ + public getChainId(chainName: string): string { + return this.chains[chainName].id; + } + + /** + * Returns true is the chain is a testnet chain + */ + public isTestnet(chainName: string): boolean { + return Boolean(this.chains[chainName].testnet); + } + + /** + * @returns true if both chains have the same ID or same name + */ + private isSameChain = (chain1: string, chain2: string): boolean => { + return chain1 === chain2 || this.getChainId(chain1) === this.getChainId(chain2); + }; + + /** + * @returns true if both chains have the same ID or same name + */ + public isSameChainFromString = (chain1: string, chain2: string): boolean => { + try { + this.assertChainNameSupported(chain1); + this.assertChainNameSupported(chain2); + } catch { + return false; + } + return this.isSameChain(chain1, chain2); + }; +} diff --git a/packages/chain/src/chains/evm/data/alfajores.ts b/packages/chain/src/chains/evm/data/alfajores.ts new file mode 100644 index 0000000000..93ebc879f7 --- /dev/null +++ b/packages/chain/src/chains/evm/data/alfajores.ts @@ -0,0 +1 @@ +export const chainId = '44787'; diff --git a/packages/chain/src/chains/evm/data/arbitrum-one.ts b/packages/chain/src/chains/evm/data/arbitrum-one.ts new file mode 100644 index 0000000000..594beaa41e --- /dev/null +++ b/packages/chain/src/chains/evm/data/arbitrum-one.ts @@ -0,0 +1 @@ +export const chainId = '42161'; diff --git a/packages/chain/src/chains/evm/data/arbitrum-rinkeby.ts b/packages/chain/src/chains/evm/data/arbitrum-rinkeby.ts new file mode 100644 index 0000000000..052b36ed95 --- /dev/null +++ b/packages/chain/src/chains/evm/data/arbitrum-rinkeby.ts @@ -0,0 +1,2 @@ +export const chainId = '421611'; +export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/avalanche.ts b/packages/chain/src/chains/evm/data/avalanche.ts new file mode 100644 index 0000000000..f1385eba17 --- /dev/null +++ b/packages/chain/src/chains/evm/data/avalanche.ts @@ -0,0 +1 @@ +export const chainId = '43114'; diff --git a/packages/chain/src/chains/evm/data/bsc.ts b/packages/chain/src/chains/evm/data/bsc.ts new file mode 100644 index 0000000000..1b5520fa57 --- /dev/null +++ b/packages/chain/src/chains/evm/data/bsc.ts @@ -0,0 +1 @@ +export const chainId = '56'; diff --git a/packages/chain/src/chains/evm/data/bsctest.ts b/packages/chain/src/chains/evm/data/bsctest.ts new file mode 100644 index 0000000000..2fe0d0b668 --- /dev/null +++ b/packages/chain/src/chains/evm/data/bsctest.ts @@ -0,0 +1 @@ +export const chainId = '97'; diff --git a/packages/chain/src/chains/evm/data/celo.ts b/packages/chain/src/chains/evm/data/celo.ts new file mode 100644 index 0000000000..b09d4be5fd --- /dev/null +++ b/packages/chain/src/chains/evm/data/celo.ts @@ -0,0 +1 @@ +export const chainId = '42220'; diff --git a/packages/chain/src/chains/evm/data/core.ts b/packages/chain/src/chains/evm/data/core.ts new file mode 100644 index 0000000000..325b50fd10 --- /dev/null +++ b/packages/chain/src/chains/evm/data/core.ts @@ -0,0 +1 @@ +export const chainId = '1116'; diff --git a/packages/chain/src/chains/evm/data/fantom.ts b/packages/chain/src/chains/evm/data/fantom.ts new file mode 100644 index 0000000000..b1d91043cd --- /dev/null +++ b/packages/chain/src/chains/evm/data/fantom.ts @@ -0,0 +1 @@ +export const chainId = '250'; diff --git a/packages/chain/src/chains/evm/data/fuse.ts b/packages/chain/src/chains/evm/data/fuse.ts new file mode 100644 index 0000000000..e15d0c13a9 --- /dev/null +++ b/packages/chain/src/chains/evm/data/fuse.ts @@ -0,0 +1 @@ +export const chainId = '122'; diff --git a/packages/currency/src/chains/evm/data/zksync-era-testnet.ts b/packages/chain/src/chains/evm/data/goerli.ts similarity index 50% rename from packages/currency/src/chains/evm/data/zksync-era-testnet.ts rename to packages/chain/src/chains/evm/data/goerli.ts index 728f31719b..71e65f0fc5 100644 --- a/packages/currency/src/chains/evm/data/zksync-era-testnet.ts +++ b/packages/chain/src/chains/evm/data/goerli.ts @@ -1,2 +1,2 @@ -export const chainId = 280; +export const chainId = '5'; export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/mainnet.ts b/packages/chain/src/chains/evm/data/mainnet.ts new file mode 100644 index 0000000000..0b2acfaa17 --- /dev/null +++ b/packages/chain/src/chains/evm/data/mainnet.ts @@ -0,0 +1 @@ +export const chainId = '1'; diff --git a/packages/chain/src/chains/evm/data/mantle-testnet.ts b/packages/chain/src/chains/evm/data/mantle-testnet.ts new file mode 100644 index 0000000000..bb05b33cb7 --- /dev/null +++ b/packages/chain/src/chains/evm/data/mantle-testnet.ts @@ -0,0 +1,2 @@ +export const chainId = '5001'; +export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/mantle.ts b/packages/chain/src/chains/evm/data/mantle.ts new file mode 100644 index 0000000000..e63ae4f87f --- /dev/null +++ b/packages/chain/src/chains/evm/data/mantle.ts @@ -0,0 +1 @@ +export const chainId = '5000'; diff --git a/packages/chain/src/chains/evm/data/matic.ts b/packages/chain/src/chains/evm/data/matic.ts new file mode 100644 index 0000000000..3cadbc6ef0 --- /dev/null +++ b/packages/chain/src/chains/evm/data/matic.ts @@ -0,0 +1 @@ +export const chainId = '137'; diff --git a/packages/chain/src/chains/evm/data/moonbeam.ts b/packages/chain/src/chains/evm/data/moonbeam.ts new file mode 100644 index 0000000000..b1c2507e4f --- /dev/null +++ b/packages/chain/src/chains/evm/data/moonbeam.ts @@ -0,0 +1 @@ +export const chainId = '1284'; diff --git a/packages/chain/src/chains/evm/data/mumbai.ts b/packages/chain/src/chains/evm/data/mumbai.ts new file mode 100644 index 0000000000..663d649b2b --- /dev/null +++ b/packages/chain/src/chains/evm/data/mumbai.ts @@ -0,0 +1,2 @@ +export const chainId = '80001'; +export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/optimism.ts b/packages/chain/src/chains/evm/data/optimism.ts new file mode 100644 index 0000000000..7c623307bd --- /dev/null +++ b/packages/chain/src/chains/evm/data/optimism.ts @@ -0,0 +1 @@ +export const chainId = '10'; diff --git a/packages/chain/src/chains/evm/data/private.ts b/packages/chain/src/chains/evm/data/private.ts new file mode 100644 index 0000000000..9b724bb018 --- /dev/null +++ b/packages/chain/src/chains/evm/data/private.ts @@ -0,0 +1 @@ +export const chainId = '0'; diff --git a/packages/currency/src/chains/evm/data/mantle-testnet.ts b/packages/chain/src/chains/evm/data/rinkeby.ts similarity index 50% rename from packages/currency/src/chains/evm/data/mantle-testnet.ts rename to packages/chain/src/chains/evm/data/rinkeby.ts index 9e7a5a5dd8..632dcc8377 100644 --- a/packages/currency/src/chains/evm/data/mantle-testnet.ts +++ b/packages/chain/src/chains/evm/data/rinkeby.ts @@ -1,2 +1,2 @@ -export const chainId = 5001; +export const chainId = '4'; export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/ronin.ts b/packages/chain/src/chains/evm/data/ronin.ts new file mode 100644 index 0000000000..db757a30f8 --- /dev/null +++ b/packages/chain/src/chains/evm/data/ronin.ts @@ -0,0 +1 @@ +export const chainId = '2020'; diff --git a/packages/chain/src/chains/evm/data/sepolia.ts b/packages/chain/src/chains/evm/data/sepolia.ts new file mode 100644 index 0000000000..91f9161b5e --- /dev/null +++ b/packages/chain/src/chains/evm/data/sepolia.ts @@ -0,0 +1,2 @@ +export const chainId = '11155111'; +export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/sokol.ts b/packages/chain/src/chains/evm/data/sokol.ts new file mode 100644 index 0000000000..a46ea22248 --- /dev/null +++ b/packages/chain/src/chains/evm/data/sokol.ts @@ -0,0 +1 @@ +export const chainId = '77'; diff --git a/packages/chain/src/chains/evm/data/tombchain.ts b/packages/chain/src/chains/evm/data/tombchain.ts new file mode 100644 index 0000000000..8f9214959b --- /dev/null +++ b/packages/chain/src/chains/evm/data/tombchain.ts @@ -0,0 +1 @@ +export const chainId = '6969'; diff --git a/packages/chain/src/chains/evm/data/xdai.ts b/packages/chain/src/chains/evm/data/xdai.ts new file mode 100644 index 0000000000..48d540230f --- /dev/null +++ b/packages/chain/src/chains/evm/data/xdai.ts @@ -0,0 +1 @@ +export const chainId = '100'; diff --git a/packages/chain/src/chains/evm/data/zksync-era-testnet.ts b/packages/chain/src/chains/evm/data/zksync-era-testnet.ts new file mode 100644 index 0000000000..8f31d4d87a --- /dev/null +++ b/packages/chain/src/chains/evm/data/zksync-era-testnet.ts @@ -0,0 +1,2 @@ +export const chainId = '280'; +export const testnet = true; diff --git a/packages/chain/src/chains/evm/data/zksync-era.ts b/packages/chain/src/chains/evm/data/zksync-era.ts new file mode 100644 index 0000000000..82bec8c179 --- /dev/null +++ b/packages/chain/src/chains/evm/data/zksync-era.ts @@ -0,0 +1 @@ +export const chainId = '324'; diff --git a/packages/chain/src/chains/evm/evm-chain.ts b/packages/chain/src/chains/evm/evm-chain.ts new file mode 100644 index 0000000000..99cb8af77a --- /dev/null +++ b/packages/chain/src/chains/evm/evm-chain.ts @@ -0,0 +1,7 @@ +import { ChainAbstract } from '../chain-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; + +export class EvmChain extends ChainAbstract implements ChainTypes.IEvmChain { + public readonly ecosystem = 'evm'; + public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; +} diff --git a/packages/chain/src/chains/evm/evm-ecosystem.ts b/packages/chain/src/chains/evm/evm-ecosystem.ts new file mode 100644 index 0000000000..4c3e2f9e26 --- /dev/null +++ b/packages/chain/src/chains/evm/evm-ecosystem.ts @@ -0,0 +1,12 @@ +import { EcosystemAbstract } from '../ecosystem-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { chains } from './index'; +import { EvmChain } from './evm-chain'; + +class EvmEcosystem extends EcosystemAbstract { + constructor(chains: Record) { + super('evm', EvmChain, chains, RequestLogicTypes.CURRENCY.ETH); + } +} + +export default new EvmEcosystem(chains); diff --git a/packages/currency/src/chains/evm/index.ts b/packages/chain/src/chains/evm/index.ts similarity index 89% rename from packages/currency/src/chains/evm/index.ts rename to packages/chain/src/chains/evm/index.ts index e987a129d8..b64d25b339 100644 --- a/packages/currency/src/chains/evm/index.ts +++ b/packages/chain/src/chains/evm/index.ts @@ -1,5 +1,4 @@ -import { CurrencyTypes } from '@requestnetwork/types'; -import { Chain } from '../../types'; +import { ChainDefinition } from '../../types'; import * as AlfajoresDefinition from './data/alfajores'; import * as ArbitrumOneDefinition from './data/arbitrum-one'; @@ -28,12 +27,10 @@ import * as XDaiDefinition from './data/xdai'; import * as SepoliaDefinition from './data/sepolia'; import * as ZkSyncEraTestnetDefinition from './data/zksync-era-testnet'; import * as ZkSyncEraDefinition from './data/zksync-era'; +import { initializeChains } from '../utils'; +import { EvmChain } from './evm-chain'; -export type EvmChain = Chain & { - chainId: number; -}; - -export const chains: Record = { +export const chainDefinitions: Record = { alfajores: AlfajoresDefinition, 'arbitrum-one': ArbitrumOneDefinition, 'arbitrum-rinkeby': ArbitrumRinkebyDefinition, @@ -62,3 +59,5 @@ export const chains: Record = { zksynceratestnet: ZkSyncEraTestnetDefinition, zksyncera: ZkSyncEraDefinition, }; + +export const chains = initializeChains(EvmChain, chainDefinitions); diff --git a/packages/currency/src/chains/near/data/near-testnet.ts b/packages/chain/src/chains/near/data/near-testnet.ts similarity index 100% rename from packages/currency/src/chains/near/data/near-testnet.ts rename to packages/chain/src/chains/near/data/near-testnet.ts diff --git a/packages/currency/src/chains/near/data/near.ts b/packages/chain/src/chains/near/data/near.ts similarity index 100% rename from packages/currency/src/chains/near/data/near.ts rename to packages/chain/src/chains/near/data/near.ts diff --git a/packages/chain/src/chains/near/index.ts b/packages/chain/src/chains/near/index.ts new file mode 100644 index 0000000000..c57fc88cd2 --- /dev/null +++ b/packages/chain/src/chains/near/index.ts @@ -0,0 +1,14 @@ +import * as NearDefinition from './data/near'; +import * as NearTestnetDefinition from './data/near-testnet'; +import { ChainDefinition } from '../../types'; +import { initializeChains } from '../utils'; +import { NearChain } from './near-chain'; + +const chainDefinitions: Record = { + aurora: NearDefinition, + 'aurora-testnet': NearTestnetDefinition, + near: NearDefinition, + 'near-testnet': NearTestnetDefinition, +}; + +export const chains = initializeChains(NearChain, chainDefinitions); diff --git a/packages/chain/src/chains/near/near-chain.ts b/packages/chain/src/chains/near/near-chain.ts new file mode 100644 index 0000000000..38160a456b --- /dev/null +++ b/packages/chain/src/chains/near/near-chain.ts @@ -0,0 +1,7 @@ +import { ChainAbstract } from '../chain-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; + +export class NearChain extends ChainAbstract implements ChainTypes.INearChain { + public readonly ecosystem = 'near'; + public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; +} diff --git a/packages/chain/src/chains/near/near-ecosystem.ts b/packages/chain/src/chains/near/near-ecosystem.ts new file mode 100644 index 0000000000..d019bad618 --- /dev/null +++ b/packages/chain/src/chains/near/near-ecosystem.ts @@ -0,0 +1,12 @@ +import { EcosystemAbstract } from '../ecosystem-abstract'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { chains } from './index'; +import { NearChain } from './near-chain'; + +class NearEcosystem extends EcosystemAbstract { + constructor(chains: Record) { + super('near', NearChain, chains, RequestLogicTypes.CURRENCY.ETH); + } +} + +export default new NearEcosystem(chains); diff --git a/packages/chain/src/chains/utils.ts b/packages/chain/src/chains/utils.ts new file mode 100644 index 0000000000..ca78a16d87 --- /dev/null +++ b/packages/chain/src/chains/utils.ts @@ -0,0 +1,14 @@ +import { ChainAbstract } from './chain-abstract'; +import { ChainDefinition } from '../types'; + +export const initializeChains = ( + chainClass: new (chainId: string, chainName: string) => CHAIN_CLASS, + chainDefinitions: Record, +): Record => + Object.keys(chainDefinitions).reduce( + (chains, chainName) => { + chains[chainName] = new chainClass(chainDefinitions[chainName].chainId, chainName); + return chains; + }, + {} as Record, + ); diff --git a/packages/chain/src/index.ts b/packages/chain/src/index.ts new file mode 100644 index 0000000000..5e3f74d887 --- /dev/null +++ b/packages/chain/src/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export { ChainManager } from './chain-manager'; diff --git a/packages/chain/src/types.ts b/packages/chain/src/types.ts new file mode 100644 index 0000000000..dc4039e1a0 --- /dev/null +++ b/packages/chain/src/types.ts @@ -0,0 +1,7 @@ +/** + * Common types used in chain configuration files + */ +export type ChainDefinition = { + chainId: string; + testnet?: boolean; +}; diff --git a/packages/currency/test/chain-utils.test.ts b/packages/chain/test/chain-utils.test.ts similarity index 100% rename from packages/currency/test/chain-utils.test.ts rename to packages/chain/test/chain-utils.test.ts diff --git a/packages/chain/tsconfig.build.json b/packages/chain/tsconfig.build.json new file mode 100644 index 0000000000..b2e8e973a9 --- /dev/null +++ b/packages/chain/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "exclude": ["test/", "scripts/", "**/*.test.ts", "**/*.spec.ts"], + "references": [ + { "path": "../types/tsconfig.build.json" }, + { "path": "../utils/tsconfig.build.json" } + ] +} diff --git a/packages/chain/tsconfig.json b/packages/chain/tsconfig.json new file mode 100644 index 0000000000..8a3a37edff --- /dev/null +++ b/packages/chain/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "esModuleInterop": true + }, + "include": ["src/", "test/"] +} diff --git a/packages/currency/README.md b/packages/currency/README.md index 7d4784be2d..9769df6dc7 100644 --- a/packages/currency/README.md +++ b/packages/currency/README.md @@ -1,7 +1,7 @@ # @requestnetwork/currency `@requestnetwork/currency` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork). -It is a collection of tools for the currencies and chains shared between the @requestnetwork packages. +It is a collection of tools for the currencies shared between the @requestnetwork packages. ## Installation @@ -51,27 +51,6 @@ console.log(FAUToken.symbol); // FAU Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. [Read the contributing guide](/CONTRIBUTING.md) -### Adding a new chain - -Supported chains are listed in `src/chains`: - -- `src/chains/btc/data` for BTC type chains -- `src/chains/evm/data` for EVM type chains -- `src/chains/near/data` for NEAR type chains - -The chain names are subjective, but they are unique and uniform across all Request Network packages. -They are formatted with the kebab-case naming convention. - -In order to add a new chain, first create a file `[nameOfTheChain].ts` in the correct directory. -Its internal structure should conform with the corresponding type, respectively: - -- `BtcChain` -- `EvmChain` -- `NearChain` - -These types are described in the `index.ts` file of each chain subdirectory. -Please add the `testnet: true` property for staging chains. - ## License [MIT](/LICENSE) diff --git a/packages/currency/package.json b/packages/currency/package.json index ef9d75e3b9..832859c960 100644 --- a/packages/currency/package.json +++ b/packages/currency/package.json @@ -43,6 +43,7 @@ }, "dependencies": { "@metamask/contract-metadata": "1.31.0", + "@requestnetwork/chain": "0.13.0", "@requestnetwork/types": "0.40.0", "@requestnetwork/utils": "0.40.0", "multicoin-address-validator": "0.5.15", diff --git a/packages/currency/src/chains/ChainsAbstract.ts b/packages/currency/src/chains/ChainsAbstract.ts deleted file mode 100644 index d498baa959..0000000000 --- a/packages/currency/src/chains/ChainsAbstract.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Chain, NamedNativeCurrency, TokenMap } from '../types'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { nativeCurrencies } from '../native'; - -export abstract class ChainsAbstract< - CHAIN_NAME extends CurrencyTypes.ChainName, - CHAIN extends Chain, - CHAIN_ID extends string | number, -> { - public chains: Record; - public chainNames: CHAIN_NAME[]; - - constructor( - chains: Record, - currencyType: RequestLogicTypes.CURRENCY.ETH | RequestLogicTypes.CURRENCY.BTC, - ) { - this.chains = chains; - this.chainNames = Object.keys(chains) as CHAIN_NAME[]; - this.addNativeCurrenciesToChains(currencyType); - } - - /** - * Adds the native currency to the list of currencies supported by each chain - */ - private addNativeCurrenciesToChains( - currencyType: RequestLogicTypes.CURRENCY.ETH | RequestLogicTypes.CURRENCY.BTC, - ): void { - this.chainNames.forEach((chainName) => { - const nativeCurrency = (nativeCurrencies[currencyType] as NamedNativeCurrency[]).find( - (currency) => currency.network === chainName, - ); - if (nativeCurrency) { - const chainCurrencies: TokenMap = this.chains[chainName].currencies || {}; - chainCurrencies.native = nativeCurrency; - this.chains[chainName].currencies = chainCurrencies; - } - }); - } - - /** - * Check if chainName lives amongst the list of supported chains by this chain type. - * Throws in the case it's not supported. - */ - public assertChainSupported(chainName?: string): asserts chainName is CHAIN_NAME { - if (!this.isChainSupported(chainName)) throw new Error(`Unsupported chain ${chainName}`); - } - - /** - * Check if chainName lives amongst the list of supported chains by this chain type. - */ - public isChainSupported(chainName?: string): chainName is CHAIN_NAME { - return !!chainName && (this.chainNames as string[]).includes(chainName); - } - - /** - * Retrieve the corresponding chain ID from Request Network's internal chain name representation - */ - public getChainId(chainName: CHAIN_NAME): CHAIN_ID { - return this.chains[chainName].chainId as CHAIN_ID; - } - - /** - * Retrieve Request Network's internal chain name representation from the corresponding chain ID - */ - public getChainName(chainId: CHAIN_ID): CHAIN_NAME | undefined { - return this.chainNames.find((chainName) => this.chains[chainName].chainId === chainId); - } - - /** - * Returns true is the chain is a testnet chain - */ - public isTestnet(chainName: CHAIN_NAME): boolean { - return Boolean(this.chains[chainName].testnet); - } - - /** - * @returns true if both chains have the same ID or same name - */ - public isSameChain = (chain1: CHAIN_NAME, chain2: CHAIN_NAME): boolean => { - return chain1 === chain2 || this.getChainId(chain1) === this.getChainId(chain2); - }; - - /** - * @returns true if both chains have the same ID or same name - */ - public isSameChainFromString = (chain1: string, chain2: string): boolean => { - try { - this.assertChainSupported(chain1); - this.assertChainSupported(chain2); - } catch { - return false; - } - return this.isSameChain(chain1, chain2); - }; -} diff --git a/packages/currency/src/chains/btc/BtcChains.ts b/packages/currency/src/chains/btc/BtcChains.ts deleted file mode 100644 index defd944134..0000000000 --- a/packages/currency/src/chains/btc/BtcChains.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ChainsAbstract } from '../ChainsAbstract'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { BtcChain, chains } from './index'; - -class BtcChains extends ChainsAbstract {} -export default new BtcChains(chains, RequestLogicTypes.CURRENCY.BTC); diff --git a/packages/currency/src/chains/btc/index.ts b/packages/currency/src/chains/btc/index.ts deleted file mode 100644 index 7c46a09b8e..0000000000 --- a/packages/currency/src/chains/btc/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CurrencyTypes } from '@requestnetwork/types'; -import { Chain } from '../../types'; - -import * as MainnetDefinition from './data/mainnet'; -import * as TestnetDefinition from './data/testnet'; - -export type BtcChain = Chain & { - chainId: string; -}; - -export const chains: Record = { - mainnet: MainnetDefinition, - testnet: TestnetDefinition, -}; diff --git a/packages/currency/src/chains/declarative/DeclarativeChains.ts b/packages/currency/src/chains/declarative/DeclarativeChains.ts deleted file mode 100644 index 68f36f7454..0000000000 --- a/packages/currency/src/chains/declarative/DeclarativeChains.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ChainsAbstract } from '../ChainsAbstract'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { DeclarativeChain, chains } from './index'; - -class DeclarativeChains extends ChainsAbstract< - CurrencyTypes.DeclarativeChainName, - DeclarativeChain, - string -> {} -export default new DeclarativeChains(chains, RequestLogicTypes.CURRENCY.ETH); diff --git a/packages/currency/src/chains/declarative/index.ts b/packages/currency/src/chains/declarative/index.ts deleted file mode 100644 index 6e38952bd8..0000000000 --- a/packages/currency/src/chains/declarative/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CurrencyTypes } from '@requestnetwork/types'; -import { Chain } from '../../types'; - -import * as TronDefinition from './data/tron'; -import * as SolanaDefinition from './data/solana'; - -export type DeclarativeChain = Chain; - -export const chains: Record = { - tron: TronDefinition, - solana: SolanaDefinition, -}; diff --git a/packages/currency/src/chains/evm/EvmChains.ts b/packages/currency/src/chains/evm/EvmChains.ts deleted file mode 100644 index f9ee82f6de..0000000000 --- a/packages/currency/src/chains/evm/EvmChains.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ChainsAbstract } from '../ChainsAbstract'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { chains, EvmChain } from './index'; - -class EvmChains extends ChainsAbstract {} -export default new EvmChains(chains, RequestLogicTypes.CURRENCY.ETH); diff --git a/packages/currency/src/chains/evm/data/alfajores.ts b/packages/currency/src/chains/evm/data/alfajores.ts deleted file mode 100644 index 8614655cb8..0000000000 --- a/packages/currency/src/chains/evm/data/alfajores.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 44787; diff --git a/packages/currency/src/chains/evm/data/arbitrum-one.ts b/packages/currency/src/chains/evm/data/arbitrum-one.ts deleted file mode 100644 index 7dd7a3a62d..0000000000 --- a/packages/currency/src/chains/evm/data/arbitrum-one.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 42161; diff --git a/packages/currency/src/chains/evm/data/arbitrum-rinkeby.ts b/packages/currency/src/chains/evm/data/arbitrum-rinkeby.ts deleted file mode 100644 index 19da716ff9..0000000000 --- a/packages/currency/src/chains/evm/data/arbitrum-rinkeby.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const chainId = 421611; -export const testnet = true; diff --git a/packages/currency/src/chains/evm/data/avalanche.ts b/packages/currency/src/chains/evm/data/avalanche.ts deleted file mode 100644 index 6bd1c9f5d6..0000000000 --- a/packages/currency/src/chains/evm/data/avalanche.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedAvalancheERC20 } from '../../../erc20/chains/avalanche'; - -export const chainId = 43114; -export const currencies: TokenMap = { - ...supportedAvalancheERC20, -}; diff --git a/packages/currency/src/chains/evm/data/bsc.ts b/packages/currency/src/chains/evm/data/bsc.ts deleted file mode 100644 index b13f8f522a..0000000000 --- a/packages/currency/src/chains/evm/data/bsc.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedBSCERC20 } from '../../../erc20/chains/bsc'; - -export const chainId = 56; -export const currencies: TokenMap = { - ...supportedBSCERC20, -}; diff --git a/packages/currency/src/chains/evm/data/bsctest.ts b/packages/currency/src/chains/evm/data/bsctest.ts deleted file mode 100644 index 7fc2bc374e..0000000000 --- a/packages/currency/src/chains/evm/data/bsctest.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedBSCTestERC20 } from '../../../erc20/chains/bsctest'; - -export const chainId = 97; -export const currencies: TokenMap = { - ...supportedBSCTestERC20, -}; diff --git a/packages/currency/src/chains/evm/data/celo.ts b/packages/currency/src/chains/evm/data/celo.ts deleted file mode 100644 index f07c603cd4..0000000000 --- a/packages/currency/src/chains/evm/data/celo.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedCeloERC20 } from '../../../erc20/chains/celo'; - -export const chainId = 42220; -export const currencies: TokenMap = { - ...supportedCeloERC20, -}; diff --git a/packages/currency/src/chains/evm/data/core.ts b/packages/currency/src/chains/evm/data/core.ts deleted file mode 100644 index d148ecf595..0000000000 --- a/packages/currency/src/chains/evm/data/core.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 1116; diff --git a/packages/currency/src/chains/evm/data/fantom.ts b/packages/currency/src/chains/evm/data/fantom.ts deleted file mode 100644 index 596a2db0db..0000000000 --- a/packages/currency/src/chains/evm/data/fantom.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedFantomERC20 } from '../../../erc20/chains/fantom'; - -export const chainId = 250; -export const currencies: TokenMap = { - ...supportedFantomERC20, -}; diff --git a/packages/currency/src/chains/evm/data/fuse.ts b/packages/currency/src/chains/evm/data/fuse.ts deleted file mode 100644 index 010d964245..0000000000 --- a/packages/currency/src/chains/evm/data/fuse.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 122; diff --git a/packages/currency/src/chains/evm/data/goerli.ts b/packages/currency/src/chains/evm/data/goerli.ts deleted file mode 100644 index 2f700bcfbd..0000000000 --- a/packages/currency/src/chains/evm/data/goerli.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedGoerliERC20 } from '../../../erc20/chains/goerli'; - -export const chainId = 5; -export const testnet = true; -export const currencies: TokenMap = { - ...supportedGoerliERC20, -}; diff --git a/packages/currency/src/chains/evm/data/mainnet.ts b/packages/currency/src/chains/evm/data/mainnet.ts deleted file mode 100644 index 4e6bb83ceb..0000000000 --- a/packages/currency/src/chains/evm/data/mainnet.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedMainnetERC20 } from '../../../erc20/chains/mainnet'; - -export const chainId = 1; -export const currencies: TokenMap = { - ...supportedMainnetERC20, -}; diff --git a/packages/currency/src/chains/evm/data/mantle.ts b/packages/currency/src/chains/evm/data/mantle.ts deleted file mode 100644 index 7528d6abaa..0000000000 --- a/packages/currency/src/chains/evm/data/mantle.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 5000; diff --git a/packages/currency/src/chains/evm/data/matic.ts b/packages/currency/src/chains/evm/data/matic.ts deleted file mode 100644 index a7738d898c..0000000000 --- a/packages/currency/src/chains/evm/data/matic.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedMaticERC20 } from '../../../erc20/chains/matic'; - -export const chainId = 137; -export const currencies: TokenMap = { - ...supportedMaticERC20, -}; diff --git a/packages/currency/src/chains/evm/data/moonbeam.ts b/packages/currency/src/chains/evm/data/moonbeam.ts deleted file mode 100644 index de586f0b7b..0000000000 --- a/packages/currency/src/chains/evm/data/moonbeam.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedMoonbeamERC20 } from '../../../erc20/chains/moonbeam'; - -export const chainId = 1284; -export const currencies: TokenMap = { - ...supportedMoonbeamERC20, -}; diff --git a/packages/currency/src/chains/evm/data/mumbai.ts b/packages/currency/src/chains/evm/data/mumbai.ts deleted file mode 100644 index a5b0bd6e95..0000000000 --- a/packages/currency/src/chains/evm/data/mumbai.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const chainId = 80001; -export const testnet = true; diff --git a/packages/currency/src/chains/evm/data/optimism.ts b/packages/currency/src/chains/evm/data/optimism.ts deleted file mode 100644 index 447d2f2300..0000000000 --- a/packages/currency/src/chains/evm/data/optimism.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedOptimismERC20 } from '../../../erc20/chains/optimism'; - -export const chainId = 10; -export const currencies: TokenMap = { - ...supportedOptimismERC20, -}; diff --git a/packages/currency/src/chains/evm/data/private.ts b/packages/currency/src/chains/evm/data/private.ts deleted file mode 100644 index 8334ef3906..0000000000 --- a/packages/currency/src/chains/evm/data/private.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 0; diff --git a/packages/currency/src/chains/evm/data/rinkeby.ts b/packages/currency/src/chains/evm/data/rinkeby.ts deleted file mode 100644 index aa9da936d3..0000000000 --- a/packages/currency/src/chains/evm/data/rinkeby.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedRinkebyERC20 } from '../../../erc20/chains/rinkeby'; -import { supportedRinkebyERC777 } from '../../../erc777/chains/rinkeby'; - -export const chainId = 4; -export const testnet = true; -export const currencies: TokenMap = { - ...supportedRinkebyERC20, - ...supportedRinkebyERC777, -}; diff --git a/packages/currency/src/chains/evm/data/ronin.ts b/packages/currency/src/chains/evm/data/ronin.ts deleted file mode 100644 index ca79b559f7..0000000000 --- a/packages/currency/src/chains/evm/data/ronin.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 2020; diff --git a/packages/currency/src/chains/evm/data/sepolia.ts b/packages/currency/src/chains/evm/data/sepolia.ts deleted file mode 100644 index 9b90d7f875..0000000000 --- a/packages/currency/src/chains/evm/data/sepolia.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedSepoliaERC20 } from '../../../erc20/chains/sepolia'; - -export const chainId = 11155111; -export const testnet = true; -export const currencies: TokenMap = { - ...supportedSepoliaERC20, -}; diff --git a/packages/currency/src/chains/evm/data/sokol.ts b/packages/currency/src/chains/evm/data/sokol.ts deleted file mode 100644 index ba023a8140..0000000000 --- a/packages/currency/src/chains/evm/data/sokol.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 77; diff --git a/packages/currency/src/chains/evm/data/tombchain.ts b/packages/currency/src/chains/evm/data/tombchain.ts deleted file mode 100644 index 43cc4b72b6..0000000000 --- a/packages/currency/src/chains/evm/data/tombchain.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 6969; diff --git a/packages/currency/src/chains/evm/data/xdai.ts b/packages/currency/src/chains/evm/data/xdai.ts deleted file mode 100644 index edbf8ba0ce..0000000000 --- a/packages/currency/src/chains/evm/data/xdai.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TokenMap } from '../../../types'; -import { supportedXDAIERC20 } from '../../../erc20/chains/xdai'; - -export const chainId = 100; -export const currencies: TokenMap = { - ...supportedXDAIERC20, -}; diff --git a/packages/currency/src/chains/evm/data/zksync-era.ts b/packages/currency/src/chains/evm/data/zksync-era.ts deleted file mode 100644 index 293661efc3..0000000000 --- a/packages/currency/src/chains/evm/data/zksync-era.ts +++ /dev/null @@ -1 +0,0 @@ -export const chainId = 324; diff --git a/packages/currency/src/chains/index.ts b/packages/currency/src/chains/index.ts deleted file mode 100644 index 3bcd7acd23..0000000000 --- a/packages/currency/src/chains/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import BtcChains from './btc/BtcChains'; -import EvmChains from './evm/EvmChains'; -import NearChains from './near/NearChains'; -import DeclarativeChains from './declarative/DeclarativeChains'; -import { isSameChain } from './utils'; - -export { BtcChains, EvmChains, NearChains, DeclarativeChains, isSameChain }; diff --git a/packages/currency/src/chains/near/NearChains.ts b/packages/currency/src/chains/near/NearChains.ts deleted file mode 100644 index 411d734c56..0000000000 --- a/packages/currency/src/chains/near/NearChains.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ChainsAbstract } from '../ChainsAbstract'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { NearChain, chains } from './index'; - -class NearChains extends ChainsAbstract {} -export default new NearChains(chains, RequestLogicTypes.CURRENCY.ETH); diff --git a/packages/currency/src/chains/near/index.ts b/packages/currency/src/chains/near/index.ts deleted file mode 100644 index 923cce384f..0000000000 --- a/packages/currency/src/chains/near/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CurrencyTypes } from '@requestnetwork/types'; -import { Chain } from '../../types'; - -import * as NearDefinition from './data/near'; -import * as NearTestnetDefinition from './data/near-testnet'; - -export type NearChain = Chain; - -export const chains: Record = { - aurora: NearDefinition, - 'aurora-testnet': NearTestnetDefinition, - near: NearDefinition, - 'near-testnet': NearTestnetDefinition, -}; diff --git a/packages/currency/src/chains/utils.ts b/packages/currency/src/chains/utils.ts deleted file mode 100644 index 8850405067..0000000000 --- a/packages/currency/src/chains/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -import BtcChains from './btc/BtcChains'; -import EvmChains from './evm/EvmChains'; -import NearChains from './near/NearChains'; - -// Returns true if both chains are equal or aliases -export const isSameChain = (chain1: string, chain2: string): boolean => { - return ( - chain1 === chain2 || - !![EvmChains, NearChains, BtcChains].find((chainSystem) => { - return chainSystem.isSameChainFromString(chain1, chain2); - }) - ); -}; diff --git a/packages/currency/src/conversion-aggregators.ts b/packages/currency/src/conversion-aggregators.ts index b37affbe4a..052edd772e 100644 --- a/packages/currency/src/conversion-aggregators.ts +++ b/packages/currency/src/conversion-aggregators.ts @@ -8,7 +8,6 @@ import sepoliaAggregator from './aggregators/sepolia.json'; import rinkebyAggregator from './aggregators/rinkeby.json'; import maticAggregator from './aggregators/matic.json'; import fantomAggregator from './aggregators/fantom.json'; -import { CurrencyTypes } from '@requestnetwork/types'; /** * currencyFrom => currencyTo => cost @@ -16,16 +15,14 @@ import { CurrencyTypes } from '@requestnetwork/types'; export type CurrencyPairs = Record>; /** - * Aggregators maps define pairs of currencies for which an onchain oracle exists, by network. + * Aggregator maps define pairs of currencies for which an onchain oracle exists, by network. * * Network => currencyFrom => currencyTo => cost */ -export type AggregatorsMap = Partial< - Record ->; +export type AggregatorsMap = Partial>; // Pairs supported by Chainlink (can be generated from requestNetwork/toolbox/src/chainlinkConversionPathTools.ts) -const chainlinkCurrencyPairs: AggregatorsMap = { +const chainlinkCurrencyPairs: AggregatorsMap = { private: privateAggregator, goerli: goerliAggregator, rinkeby: rinkebyAggregator, @@ -59,9 +56,7 @@ export const defaultConversionPairs: AggregatorsMap = { ...noConversionNetworks, }; -export const conversionSupportedNetworks = Object.keys( - defaultConversionPairs, -) as CurrencyTypes.ChainName[]; +export const conversionSupportedNetworks = Object.keys(defaultConversionPairs); /** * Gets the on-chain conversion path between two currencies. @@ -76,7 +71,7 @@ export const conversionSupportedNetworks = Object.keys( export function getPath( currencyFrom: Pick, currencyTo: Pick, - network: CurrencyTypes.ChainName = 'mainnet', + network = 'mainnet', pairs = defaultConversionPairs, ): string[] | null { if (!pairs[network]) { diff --git a/packages/currency/src/currencyManager.ts b/packages/currency/src/currency-manager.ts similarity index 77% rename from packages/currency/src/currencyManager.ts rename to packages/currency/src/currency-manager.ts index d5e9d22907..813be48d85 100644 --- a/packages/currency/src/currencyManager.ts +++ b/packages/currency/src/currency-manager.ts @@ -1,23 +1,21 @@ -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { utils } from 'ethers'; import addressValidator from 'multicoin-address-validator'; -import { getSupportedERC20Tokens } from './erc20'; -import { getSupportedERC777Tokens } from './erc777'; +import { getSupportedERC20Currencies } from './erc20'; +import { getSupportedERC777Currencies } from './erc777'; import { getHash } from './getHash'; -import iso4217 from './iso4217'; -import { nativeCurrencies } from './native'; +import { ChainManager } from '@requestnetwork/chain'; import { - StorageCurrency, CurrencyDefinition, CurrencyInput, - ERC20Currency, ICurrencyManager, LegacyTokenMap, NativeCurrencyType, + StorageCurrency, } from './types'; -import { defaultConversionPairs, AggregatorsMap, getPath } from './conversion-aggregators'; +import { AggregatorsMap, defaultConversionPairs, getPath } from './conversion-aggregators'; import { isValidNearAddress } from './currency-utils'; -import { NearChains } from './chains'; +import { getSupportedNativeCurrencies } from './native'; const { BTC, ERC20, ERC777, ETH, ISO4217 } = RequestLogicTypes.CURRENCY; @@ -28,6 +26,7 @@ export class CurrencyManager implements ICurrencyManager private readonly knownCurrencies: CurrencyDefinition[]; private readonly legacyTokens: LegacyTokenMap; private readonly conversionPairs: AggregatorsMap; + public readonly chainManager: ChainManager; private static defaultInstance: CurrencyManager; @@ -41,6 +40,7 @@ export class CurrencyManager implements ICurrencyManager inputCurrencies: (CurrencyInput & { id?: string; meta?: TMeta })[], legacyTokens?: LegacyTokenMap, conversionPairs?: AggregatorsMap, + chainManager?: ChainManager, ) { this.knownCurrencies = []; for (const input of inputCurrencies) { @@ -52,6 +52,7 @@ export class CurrencyManager implements ICurrencyManager } this.legacyTokens = legacyTokens || CurrencyManager.getDefaultLegacyTokens(); this.conversionPairs = conversionPairs || CurrencyManager.getDefaultConversionPairs(); + this.chainManager = chainManager || ChainManager.getDefault(); } /** @@ -63,7 +64,7 @@ export class CurrencyManager implements ICurrencyManager */ from( currencyIdentifier: string | undefined, - network?: CurrencyTypes.ChainName, + network?: string | ChainTypes.IChain, ): CurrencyDefinition | undefined { if (!currencyIdentifier) { return; @@ -72,7 +73,7 @@ export class CurrencyManager implements ICurrencyManager return this.fromAddress(currencyIdentifier, network); } - if (network && currencyIdentifier.indexOf(network) === -1) { + if (network && currencyIdentifier.indexOf(ChainManager.getName(network)) === -1) { currencyIdentifier = CurrencyManager.currencyId({ symbol: currencyIdentifier, network }); } @@ -82,7 +83,7 @@ export class CurrencyManager implements ICurrencyManager const parts = currencyIdentifier.split('-'); const currencyFromSymbol = - this.fromSymbol(parts[0], network || (parts[1] as CurrencyTypes.ChainName)) || + this.fromSymbol(parts[0], network || parts[1]) || // try without splitting the symbol to support currencies like ETH-rinkeby this.fromSymbol(currencyIdentifier, network); @@ -100,7 +101,10 @@ export class CurrencyManager implements ICurrencyManager * Gets a supported currency from its address and network. * If more than one currency are found, undefined is returned */ - fromAddress(address: string, network?: string): CurrencyDefinition | undefined { + fromAddress( + address: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined { address = utils.getAddress(address); const matches = this.knownCurrencies.filter( (x) => @@ -109,9 +113,9 @@ export class CurrencyManager implements ICurrencyManager (!network || x.network === network), ); if (matches.length > 1) { - const networks = matches.map((x) => (x as ERC20Currency).network).join(', '); + const networks = matches.map((x) => ('network' in x ? x.network : '')).join(', '); console.warn( - `${address} has several matches on ${networks}. To avoid errors, specify a network.`, + `${address} has several matches on "${networks}". To avoid errors, specify a network.`, ); return undefined; } @@ -123,12 +127,10 @@ export class CurrencyManager implements ICurrencyManager */ fromSymbol( symbol: string, - network?: CurrencyTypes.ChainName, + network?: string | ChainTypes.IChain, ): CurrencyDefinition | undefined { symbol = symbol?.toUpperCase(); - network = network?.toLowerCase() as CurrencyTypes.ChainName | undefined; - - const legacy = network ? this.legacyTokens[network]?.[symbol] : undefined; + const legacy = network ? this.legacyTokens[ChainManager.getName(network)]?.[symbol] : undefined; if (legacy) { [symbol, network] = legacy; } @@ -136,17 +138,27 @@ export class CurrencyManager implements ICurrencyManager return this.knownCurrencies.find( (x) => x.symbol.toUpperCase() === symbol && - ((x.type === ISO4217 && !network) || ('network' in x && x.network === network) || !network), + (!network || ('network' in x && x.network === ChainManager.getName(network))) && + (!network || + typeof network === 'string' || + x.type === this.chainManager.ecosystems[network.ecosystem].currencyType), ); } - fromHash(hash: string, network?: string): CurrencyDefinition | undefined { + fromHash( + hash: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined { return this.knownCurrencies.find( (x) => x.hash.toLowerCase() === hash.toLowerCase() && - ((x.type === ISO4217 && !network) || ('network' in x && x.network === network) || !network), + (!network || ('network' in x && x.network === ChainManager.getName(network))) && + (!network || + typeof network === 'string' || + x.type === this.chainManager.ecosystems[network.ecosystem].currencyType), ); } + /** * Retrieves a currency given its storage format (ICurrency) */ @@ -174,27 +186,26 @@ export class CurrencyManager implements ICurrencyManager */ getNativeCurrency( type: NativeCurrencyType, - network: string, + network: string | ChainTypes.IChain, ): CurrencyDefinition | undefined { - return this.knownCurrencies.find((x) => x.type === type && x.network === network); + return this.knownCurrencies.find( + (x) => x.type === type && x.network === ChainManager.getName(network), + ); } getConversionPath( from: Pick, to: Pick, - network: CurrencyTypes.ChainName, + network: string | ChainTypes.IChain, ): string[] | null { try { - return getPath(from, to, network, this.conversionPairs); + return getPath(from, to, ChainManager.getName(network), this.conversionPairs); } catch (e) { return null; } } - supportsConversion( - currency: Pick, - network: CurrencyTypes.ChainName, - ): boolean { + supportsConversion(currency: Pick, network: string): boolean { return !!this.conversionPairs[network]?.[currency.hash.toLowerCase()]; } @@ -223,8 +234,10 @@ export class CurrencyManager implements ICurrencyManager /** * Utility function to compute the unique identifier */ - static currencyId(currency: { symbol: string; network?: string }): string { - return 'network' in currency ? `${currency.symbol}-${currency.network}` : currency.symbol; + static currencyId(currency: { symbol: string; network?: string | ChainTypes.IChain }): string { + return currency.network + ? `${currency.symbol}-${ChainManager.getName(currency.network)}` + : currency.symbol; } /** @@ -251,7 +264,7 @@ export class CurrencyManager implements ICurrencyManager case RequestLogicTypes.CURRENCY.ETH: case RequestLogicTypes.CURRENCY.ERC20: case RequestLogicTypes.CURRENCY.ERC777: - if (NearChains.isChainSupported(currency.network)) { + if (this.chainManager.ecosystems.near.isChainSupported(currency.network)) { return isValidNearAddress(address, currency.network); } else if (currency.network === 'tron' || currency.network === 'solana') { return addressValidator.validate(address, currency.network); @@ -292,27 +305,11 @@ export class CurrencyManager implements ICurrencyManager * - ETH-rinkeby, FAU-rinkeby, CTBK-rinkeby */ static getDefaultList(): CurrencyDefinition[] { - const isoCurrencies: CurrencyInput[] = iso4217.map((cc) => ({ - decimals: cc.digits, - name: cc.currency, - symbol: cc.code, - type: ISO4217, - })); - - const eth: CurrencyInput[] = nativeCurrencies.ETH.map((x) => ({ ...x, type: ETH })); - const btc: CurrencyInput[] = nativeCurrencies.BTC.map((x) => ({ ...x, type: BTC })); - - const erc20Tokens = getSupportedERC20Tokens(); - const erc20Currencies: CurrencyInput[] = erc20Tokens.map((x) => ({ ...x, type: ERC20 })); - - const erc777Tokens = getSupportedERC777Tokens(); - const erc777Currencies: CurrencyInput[] = erc777Tokens.map((x) => ({ ...x, type: ERC777 })); - - return isoCurrencies - .concat(erc20Currencies) - .concat(erc777Currencies) - .concat(eth) - .concat(btc) + return ([] as CurrencyInput[]) + .concat(getSupportedNativeCurrencies()) + .concat(getSupportedNativeCurrencies()) + .concat(getSupportedERC20Currencies()) + .concat(getSupportedERC777Currencies()) .map(CurrencyManager.fromInput); } diff --git a/packages/currency/src/erc20/chains/index.ts b/packages/currency/src/erc20/chains/index.ts index fa2dad08d9..d09b8a375b 100644 --- a/packages/currency/src/erc20/chains/index.ts +++ b/packages/currency/src/erc20/chains/index.ts @@ -1,5 +1,4 @@ import { TokenMap } from '../../types'; -import { CurrencyTypes } from '@requestnetwork/types'; import { supportedAvalancheERC20 } from './avalanche'; import { supportedBSCERC20 } from './bsc'; @@ -15,7 +14,7 @@ import { supportedRinkebyERC20 } from './rinkeby'; import { supportedXDAIERC20 } from './xdai'; import { supportedSepoliaERC20 } from './sepolia'; -export const supportedNetworks: Partial> = { +export const supportedNetworks: Record = { celo: supportedCeloERC20, // FIXME: Rinkeby is deprecated rinkeby: supportedRinkebyERC20, diff --git a/packages/currency/src/erc20/index.ts b/packages/currency/src/erc20/index.ts index b0f4f6b316..fedb95101c 100644 --- a/packages/currency/src/erc20/index.ts +++ b/packages/currency/src/erc20/index.ts @@ -1,24 +1,28 @@ -import { ERC20Currency, TokenMap } from '../types'; +import { ERC20CurrencyInput, TokenMap } from '../types'; import { supportedNetworks } from './chains'; -import { CurrencyTypes } from '@requestnetwork/types'; +import { RequestLogicTypes } from '@requestnetwork/types'; /** * Returns a list of supported ERC20 tokens * * @returns List of supported ERC20 tokens */ -export function getSupportedERC20Tokens(): ERC20Currency[] { - return (Object.entries(supportedNetworks) as [CurrencyTypes.EvmChainName, TokenMap][]).reduce( - (acc: ERC20Currency[], [networkName, supportedCurrencies]) => { +export function getSupportedERC20Currencies(): ERC20CurrencyInput[] { + return (Object.entries(supportedNetworks) as [string, TokenMap][]).reduce( + (acc: ERC20CurrencyInput[], [networkName, supportedCurrencies]) => { return [ ...acc, - ...Object.entries(supportedCurrencies).map(([address, token]) => ({ - address, - network: networkName, - decimals: token.decimals, - symbol: token.symbol, - id: token.id, - })), + ...Object.entries(supportedCurrencies).map( + ([address, token]) => + ({ + type: RequestLogicTypes.CURRENCY.ERC20, + address, + network: networkName, + decimals: token.decimals, + symbol: token.symbol, + id: token.id, + }) as const, + ), ]; }, [], diff --git a/packages/currency/src/erc777/chains/index.ts b/packages/currency/src/erc777/chains/index.ts index 05d09408bb..e76ffff928 100644 --- a/packages/currency/src/erc777/chains/index.ts +++ b/packages/currency/src/erc777/chains/index.ts @@ -1,7 +1,6 @@ import { supportedRinkebyERC777 } from './rinkeby'; import { TokenMap } from '../../types'; -import { CurrencyTypes } from '@requestnetwork/types'; -export const supportedNetworks: Partial> = { +export const supportedNetworks: Record = { rinkeby: supportedRinkebyERC777, }; diff --git a/packages/currency/src/erc777/index.ts b/packages/currency/src/erc777/index.ts index 36e2f5f53a..cd41f42188 100644 --- a/packages/currency/src/erc777/index.ts +++ b/packages/currency/src/erc777/index.ts @@ -1,23 +1,28 @@ -import { ERC777Currency, TokenMap } from '../types'; +import { ERC777Currency, ERC777CurrencyInput, TokenMap } from '../types'; import { supportedNetworks } from './chains'; -import { CurrencyTypes } from '@requestnetwork/types'; +import { ChainManager } from '@requestnetwork/chain'; +import { RequestLogicTypes } from '@requestnetwork/types'; /** * Returns a list of supported ERC777 tokens * * @returns List of supported ERC777 tokens */ -export function getSupportedERC777Tokens(): ERC777Currency[] { - return (Object.entries(supportedNetworks) as [CurrencyTypes.EvmChainName, TokenMap][]).reduce( - (acc: ERC777Currency[], [networkName, supportedCurrencies]) => { +export function getSupportedERC777Currencies(): ERC777CurrencyInput[] { + return (Object.entries(supportedNetworks) as [string, TokenMap][]).reduce( + (acc: ERC777CurrencyInput[], [networkName, supportedCurrencies]) => { return [ ...acc, - ...Object.entries(supportedCurrencies).map(([address, token]) => ({ - address, - network: networkName, - decimals: token.decimals, - symbol: token.symbol, - })), + ...Object.entries(supportedCurrencies).map( + ([address, token]) => + ({ + type: RequestLogicTypes.CURRENCY.ERC777, + address, + network: networkName, + decimals: token.decimals, + symbol: token.symbol, + }) as const, + ), ]; }, [], diff --git a/packages/currency/src/index.ts b/packages/currency/src/index.ts index e3f77834d2..eaf3bfab42 100644 --- a/packages/currency/src/index.ts +++ b/packages/currency/src/index.ts @@ -1,13 +1,12 @@ -export * from './chains'; -export { getSupportedERC20Tokens } from './erc20'; -export { getSupportedERC777Tokens } from './erc777'; +export { getSupportedERC20Currencies } from './erc20'; +export { getSupportedERC777Currencies } from './erc777'; export { conversionSupportedNetworks, CurrencyPairs, AggregatorsMap, } from './conversion-aggregators'; export { getHash as getCurrencyHash } from './getHash'; -export { CurrencyManager } from './currencyManager'; +export { CurrencyManager } from './currency-manager'; export * from './types'; export * from './errors'; export * from './currency-utils'; diff --git a/packages/currency/src/iso4217.ts b/packages/currency/src/iso4217.ts index 4a648f8717..ad2a4b6c82 100644 --- a/packages/currency/src/iso4217.ts +++ b/packages/currency/src/iso4217.ts @@ -4,7 +4,11 @@ Data last updated 2018-08-29 */ -export default [ +import { ISO4217CurrencyInput, NativeCurrencyInput } from './types'; +import { nativeCurrencies } from './native'; +import { RequestLogicTypes } from '@requestnetwork/types'; + +const iso4217Currencies = [ { code: 'AED', number: '784', @@ -1354,3 +1358,19 @@ export default [ countries: ['Zimbabwe'], }, ]; + +export default iso4217Currencies; + +/** + * Returns a list of supported ISO-4217 currencies + * + * @returns List of supported ISO-4217 currencies + */ +export function getSupportedNativeCurrencies(): ISO4217CurrencyInput[] { + return iso4217Currencies.map((cc) => ({ + type: RequestLogicTypes.CURRENCY.ISO4217, + decimals: cc.digits, + name: cc.currency, + symbol: cc.code, + })); +} diff --git a/packages/currency/src/native.ts b/packages/currency/src/native.ts index 70c99ee419..4157aac853 100644 --- a/packages/currency/src/native.ts +++ b/packages/currency/src/native.ts @@ -1,183 +1,175 @@ -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { NamedNativeCurrency } from './types'; +import { RequestLogicTypes } from '@requestnetwork/types'; +import { NativeCurrency, NativeCurrencyInput, TokenMap } from './types'; -type NativeEthCurrency = NamedNativeCurrency & { - network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName; -}; -type NativeBtcCurrency = NamedNativeCurrency & { network: CurrencyTypes.BtcChainName }; - -export const nativeCurrencies: Record & - Record = { - [RequestLogicTypes.CURRENCY.ETH]: [ - { +export const nativeCurrencies: Record< + RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH, + TokenMap +> = { + [RequestLogicTypes.CURRENCY.ETH]: { + private: { symbol: 'ETH-private', decimals: 18, name: 'Ether', - network: 'private', }, - { + mainnet: { symbol: 'ETH', decimals: 18, name: 'Ether', - network: 'mainnet', }, - { + rinkeby: { symbol: 'ETH-rinkeby', decimals: 18, name: 'Rinkeby Ether', - network: 'rinkeby', }, - { + goerli: { symbol: 'ETH-goerli', decimals: 18, name: 'Goerli Ether', - network: 'goerli', }, - { + matic: { symbol: 'MATIC', decimals: 18, name: 'Matic', - network: 'matic', }, - { + xdai: { symbol: 'xDAI', decimals: 18, name: 'xDAI', - network: 'xdai', }, - { + sokol: { symbol: 'POA', decimals: 18, name: 'POA Sokol Ether', - network: 'sokol', }, - { + fuse: { symbol: 'FUSE', decimals: 18, name: 'FUSE', - network: 'fuse', }, - { + celo: { symbol: 'CELO', decimals: 18, name: 'CELO', - network: 'celo', }, - { + fantom: { symbol: 'FTM', decimals: 18, name: 'Fantom', - network: 'fantom', }, - { + bsc: { symbol: 'BNB', decimals: 18, name: 'BNB', - network: 'bsc', }, - { + aurora: { symbol: 'NEAR', decimals: 24, name: 'Near', - network: 'aurora', }, - { + 'aurora-testnet': { symbol: 'NEAR-testnet', decimals: 24, name: 'Near Testnet', - network: 'aurora-testnet', }, - { + 'near-testnet': { symbol: 'NEAR-testnet', decimals: 24, name: 'Test Near', - network: 'near-testnet', }, - { + 'arbitrum-rinkeby': { symbol: 'ARETH', decimals: 18, name: 'Arbitrum Testnet', - network: 'arbitrum-rinkeby', }, - { + 'arbitrum-one': { symbol: 'AETH', decimals: 18, name: 'Arbitrum Ether', - network: 'arbitrum-one', }, - { + avalanche: { symbol: 'AVAX', decimals: 18, name: 'AVAX', - network: 'avalanche', }, - { + optimism: { symbol: 'ETH-optimism', decimals: 18, name: 'Optimism Ether', - network: 'optimism', }, - { + moonbeam: { symbol: 'GLMR', decimals: 18, name: 'Glimmer', - network: 'moonbeam', }, - { + tombchain: { symbol: 'TOMB', decimals: 18, name: 'Tomb', - network: 'tombchain', }, - { + mantle: { symbol: 'MNT', decimals: 18, name: 'Mantle', - network: 'mantle', }, - { + 'mantle-testnet': { symbol: 'MNT-testnet', decimals: 18, name: 'Mantle Testnet', - network: 'mantle-testnet', }, - { + core: { symbol: 'CORE', decimals: 18, name: 'Core', - network: 'core', }, - { + sepolia: { symbol: 'ETH-sepolia', decimals: 18, name: 'Sepolia Ether', - network: 'sepolia', }, - { + zksyncera: { symbol: 'ETH-zksync', decimals: 18, name: 'Ether', - network: 'zksyncera', }, - { + zksynceratestnet: { symbol: 'ETH-zksync-testnet', decimals: 18, name: 'Ether', - network: 'zksynceratestnet', }, - ], - [RequestLogicTypes.CURRENCY.BTC]: [ - { + }, + [RequestLogicTypes.CURRENCY.BTC]: { + mainnet: { symbol: 'BTC', decimals: 8, name: 'Bitcoin', - network: 'mainnet', }, - { + testnet: { symbol: 'BTC-testnet', decimals: 8, name: 'Test Bitcoin', - network: 'testnet', }, - ], + }, }; + +/** + * Returns a list of supported native tokens + * + * @returns List of supported native tokens + */ +export function getSupportedNativeCurrencies(): NativeCurrencyInput[] { + return Object.entries(nativeCurrencies).reduce( + (acc: NativeCurrencyInput[], [CurrencyType, supportedCurrencies]) => + acc.concat( + Object.entries(supportedCurrencies).map( + ([networkName, token]) => + ({ + type: CurrencyType, + network: networkName, + decimals: token.decimals, + symbol: token.symbol, + }) as NativeCurrencyInput, + ), + ), + [], + ); +} diff --git a/packages/currency/src/types.ts b/packages/currency/src/types.ts index c976b3871b..c3f6edf1f9 100644 --- a/packages/currency/src/types.ts +++ b/packages/currency/src/types.ts @@ -1,4 +1,5 @@ -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainManager } from '@requestnetwork/chain'; /** * Common types used in token configuration files @@ -7,28 +8,14 @@ type TokenAddress = string; type TokenDefinition = { name: string; symbol: string; decimals: number; id?: string }; export type TokenMap = Record; -/** - * Common types used in chain configuration files - */ -export type Chain = { - chainId: number | string; - testnet?: boolean; - currencies?: TokenMap; -}; - /** * A native blockchain token (ETH, MATIC, ETH-rinkeby...) */ export type NativeCurrency = { symbol: string; decimals: number; - network: CurrencyTypes.ChainName; + network: ChainTypes.IChain; }; -type NamedCurrency = { name: string }; -export type NamedNativeCurrency = NativeCurrency & NamedCurrency; - -/** Native Currency types */ -export type NativeCurrencyType = RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH; /** * A Fiat currency (EUR, USD...) @@ -44,10 +31,7 @@ export type ISO4217Currency = { export type ERC20Currency = { symbol: string; decimals: number; - network: - | CurrencyTypes.EvmChainName - | CurrencyTypes.NearChainName - | CurrencyTypes.DeclarativeChainName; + network: ChainTypes.IEvmChain | ChainTypes.INearChain | ChainTypes.IDeclarativeChain; address: string; }; @@ -57,37 +41,43 @@ export type ERC20Currency = { export type ERC777Currency = { symbol: string; decimals: number; - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; address: string; }; +/** Native Currency types */ +export type NativeCurrencyType = RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH; + /** * The minimum properties of a native Currency */ -export type NativeCurrencyInput = { - type: RequestLogicTypes.CURRENCY.ETH | RequestLogicTypes.CURRENCY.BTC; -} & NativeCurrency; +export type NativeCurrencyInput = Omit & { + type: NativeCurrencyType; + network: string; +}; /** * The minimum properties of an ISO4217 Currency */ -export type ISO4217CurrencyInput = { +export type ISO4217CurrencyInput = ISO4217Currency & { type: RequestLogicTypes.CURRENCY.ISO4217; -} & ISO4217Currency; +}; /** * The minimum properties of an ERC20 Currency */ -export type ERC20CurrencyInput = { +export type ERC20CurrencyInput = Omit & { type: RequestLogicTypes.CURRENCY.ERC20; -} & ERC20Currency; + network: string; +}; /** * The minimum properties of an ERC777 Currency */ -export type ERC777CurrencyInput = { +export type ERC777CurrencyInput = Omit & { type: RequestLogicTypes.CURRENCY.ERC777; -} & ERC777Currency; + network: string; +}; /** * The minimum properties of a Currency @@ -117,21 +107,37 @@ export type StorageCurrency = RequestLogicTypes.ICurrency; * A Currency manager handles a list of currencies and provides utility to retrieve and change format */ export interface ICurrencyManager { - from(symbolOrAddress: string, network?: string): CurrencyDefinition | undefined; - fromAddress(address: string, network?: string): CurrencyDefinition | undefined; - fromSymbol(symbol: string, network?: string): CurrencyDefinition | undefined; - fromHash(hash: string, network?: string): CurrencyDefinition | undefined; + chainManager: ChainManager; + from( + symbolOrAddress: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined; + fromAddress( + address: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined; + fromSymbol( + symbol: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined; + fromHash( + hash: string, + network?: string | ChainTypes.IChain, + ): CurrencyDefinition | undefined; fromStorageCurrency(currency: StorageCurrency): CurrencyDefinition | undefined; getNativeCurrency( type: NativeCurrencyType, - network: string, + network: string | ChainTypes.IChain, ): CurrencyDefinition | undefined; getConversionPath( from: Pick, to: Pick, - network: string, + network: string | ChainTypes.IChain, ): string[] | null; - supportsConversion(currency: Pick, network: string): boolean; + supportsConversion( + currency: Pick, + network: string | ChainTypes.IChain, + ): boolean; validateAddress(address: string, currency: CurrencyInput | StorageCurrency): boolean; validateCurrency(currency: StorageCurrency): boolean; } @@ -141,4 +147,4 @@ export interface ICurrencyManager { * * Format { "chainName": {"TOKEN": ["NEW_TOKEN","NEW_CHAIN"]}} */ -export type LegacyTokenMap = Record>; +export type LegacyTokenMap = Record>; diff --git a/packages/currency/test/conversion-supported-currencies.test.ts b/packages/currency/test/conversion-supported-currencies.test.ts index 04f6ed14e0..9d0c063c2a 100644 --- a/packages/currency/test/conversion-supported-currencies.test.ts +++ b/packages/currency/test/conversion-supported-currencies.test.ts @@ -20,7 +20,7 @@ describe('supported currencies with oracles from chainlink', () => { private: ['EUR', 'USD'], matic: ['AUD', 'CAD', 'CHF', 'EUR', 'GBP', 'SGD', 'USD'], fantom: ['USD', 'CHF'], - }) as [CurrencyTypes.EvmChainName, string[]][] + }) as [ChainTypes.IEvmChain, string[]][] ).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { @@ -39,7 +39,7 @@ describe('supported currencies with oracles from chainlink', () => { Object.entries({ mainnet: ['ETH'], fantom: ['FTM'], - }) as [CurrencyTypes.EvmChainName, string[]][] + }) as [ChainTypes.IEvmChain, string[]][] ).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { @@ -77,7 +77,7 @@ describe('supported currencies with oracles from chainlink', () => { '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', ], private: ['0x38cf23c52bb4b13f051aec09580a2de845a7fa35'], - }) as [CurrencyTypes.EvmChainName, string[]][] + }) as [ChainTypes.IEvmChain, string[]][] ).forEach(([network, addresses]) => { describe(network, () => { addresses.forEach((address) => { diff --git a/packages/currency/test/currency/erc20.test.ts b/packages/currency/test/currency/erc20.test.ts index 5e39700650..e59e049391 100644 --- a/packages/currency/test/currency/erc20.test.ts +++ b/packages/currency/test/currency/erc20.test.ts @@ -1,4 +1,4 @@ -import { getSupportedERC20Tokens } from '../../src/erc20'; +import { getSupportedERC20Currencies } from '../../src/erc20'; import * as metamaskContractMap from '@metamask/contract-metadata'; import { extraERC20Tokens } from '../../src/erc20/chains/mainnet'; import { utils } from 'ethers'; @@ -12,7 +12,7 @@ describe('erc20', () => { }); }); describe('uses checksumed addresses', () => { - getSupportedERC20Tokens().map(({ address, symbol }) => { + getSupportedERC20Currencies().map(({ address, symbol }) => { it(`${symbol} is checksumed`, () => { expect(address).toEqual(utils.getAddress(address)); }); diff --git a/packages/currency/test/currency/erc777.test.ts b/packages/currency/test/currency/erc777.test.ts index 1b35680c6b..6142d87778 100644 --- a/packages/currency/test/currency/erc777.test.ts +++ b/packages/currency/test/currency/erc777.test.ts @@ -1,9 +1,9 @@ -import { getSupportedERC777Tokens } from '../../src/erc777'; +import { getSupportedERC777Currencies } from '../../src/erc777'; import { utils } from 'ethers'; describe('erc777', () => { describe('uses checksumed addresses', () => { - getSupportedERC777Tokens().map(({ address, symbol }) => { + getSupportedERC777Currencies().map(({ address, symbol }) => { it(`${symbol} is checksumed`, () => { expect(address).toEqual(utils.getAddress(address)); }); diff --git a/packages/ethereum-storage/src/config.ts b/packages/ethereum-storage/src/config.ts index 81dc1b006d..a8a1144670 100644 --- a/packages/ethereum-storage/src/config.ts +++ b/packages/ethereum-storage/src/config.ts @@ -63,7 +63,7 @@ export function getDefaultEthereumProviderTimeout(): number { * Retrieve from config the default name of the network for Ethereum * @returns the name of the network */ -export function getDefaultEthereumNetwork(): CurrencyTypes.EvmChainName { +export function getDefaultEthereumNetwork(): ChainTypes.IEvmChain { return config.ethereum.default; } diff --git a/packages/ethereum-storage/src/ethereum-tx-submitter.ts b/packages/ethereum-storage/src/ethereum-tx-submitter.ts index 3fdacbc702..2665f43b8a 100644 --- a/packages/ethereum-storage/src/ethereum-tx-submitter.ts +++ b/packages/ethereum-storage/src/ethereum-tx-submitter.ts @@ -22,7 +22,7 @@ export type SubmitterProps = { * The default is 100, which does not change the value (100 is equal to x1, 200 is equal to x2). */ gasPriceMultiplier?: number; - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; logger?: LogTypes.ILogger; debugProvider?: boolean; }; diff --git a/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts b/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts index 4c4873875b..93781d3ded 100644 --- a/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts +++ b/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts @@ -8,7 +8,7 @@ import { createMockConversionErc20Request } from '../utils'; const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidEURRequest = { - network: 'matic' as CurrencyTypes.EvmChainName, + network: 'matic' as ChainTypes.IEvmChain, requestId: '0117d7a59a48e5031b3c56c92621453149e4a4462dba6eaeb3271a995c4201448b', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: '5ddb1c1645ac2daf', diff --git a/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts b/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts index c1e71e5547..9525865ce3 100644 --- a/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts +++ b/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts @@ -8,7 +8,7 @@ import { createMockConversionEthTokenRequest } from '../utils'; const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidEURRequest = { - network: 'matic' as CurrencyTypes.EvmChainName, + network: 'matic' as ChainTypes.IEvmChain, requestId: '01814304b39265cbf0c2abb4f3c7e8432d1e2c8779be6022e545d25f95144360e0', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: 'b3f2e478374bff64', diff --git a/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts b/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts index e3062b6dd9..fb745d0302 100644 --- a/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts +++ b/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts @@ -20,7 +20,7 @@ automine(); const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidRequest = { - network: 'matic' as CurrencyTypes.EvmChainName, + network: 'matic' as ChainTypes.IEvmChain, requestId: '014bcd076791fb915af457df1d3f26c81ff66f7e278e4a18f0e48a1705572a6306', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: '8c5ea6f8b4a14fe0', diff --git a/packages/integration-test/test/scheduled/erc777-stream.test.ts b/packages/integration-test/test/scheduled/erc777-stream.test.ts index a57d187432..9813d6f3a2 100644 --- a/packages/integration-test/test/scheduled/erc777-stream.test.ts +++ b/packages/integration-test/test/scheduled/erc777-stream.test.ts @@ -17,7 +17,7 @@ const createMockRequest = ({ salt, requestId, }: Record<'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId', string> & { - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { diff --git a/packages/integration-test/test/utils.ts b/packages/integration-test/test/utils.ts index 0621a4d46d..232576b227 100644 --- a/packages/integration-test/test/utils.ts +++ b/packages/integration-test/test/utils.ts @@ -16,7 +16,7 @@ export const createMockErc20FeeRequest = ({ }: Record< 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string -> & { network: CurrencyTypes.EvmChainName }): RequestLogicTypes.IRequest => ({ +> & { network: ChainTypes.IEvmChain }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { network, @@ -59,7 +59,7 @@ export const createMockConversionErc20Request = ({ 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string > & { - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; currency: RequestLogicTypes.ICurrency; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, @@ -101,7 +101,7 @@ export const createMockNativeTokenRequest = ({ 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount' | 'nativeTokenCode', string > & { - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { @@ -141,7 +141,7 @@ export const createMockConversionEthTokenRequest = ({ feeAmount, currency, }: Record<'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string> & { - network: CurrencyTypes.EvmChainName; + network: ChainTypes.IEvmChain; currency: RequestLogicTypes.ICurrency; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, diff --git a/packages/payment-detection/src/any/any-to-erc20-proxy.ts b/packages/payment-detection/src/any/any-to-erc20-proxy.ts index e55f22fcf8..d55c6b3a1b 100644 --- a/packages/payment-detection/src/any/any-to-erc20-proxy.ts +++ b/packages/payment-detection/src/any/any-to-erc20-proxy.ts @@ -24,7 +24,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< ExtensionTypes.PnAnyToErc20.IAnyToERC20, PaymentTypes.IERC20FeePaymentEventParameters > { - private readonly getSubgraphClient: TGetSubGraphClient; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions @@ -35,7 +35,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< currencyManager, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick, 'getSubgraphClient'>) { + Pick, 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY, advancedLogic.extensions.anyToErc20Proxy, @@ -85,7 +85,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { @@ -141,7 +141,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< }; } - protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.EvmChainName { + protected getPaymentChain(request: RequestLogicTypes.IRequest): ChainTypes.IEvmChain { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); diff --git a/packages/payment-detection/src/any/any-to-eth-proxy.ts b/packages/payment-detection/src/any/any-to-eth-proxy.ts index f66b6cbde5..e3b14c6573 100644 --- a/packages/payment-detection/src/any/any-to-eth-proxy.ts +++ b/packages/payment-detection/src/any/any-to-eth-proxy.ts @@ -31,7 +31,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< ExtensionTypes.PnAnyToEth.IAnyToEth, PaymentTypes.IETHFeePaymentEventParameters > { - private readonly getSubgraphClient: TGetSubGraphClient; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions */ @@ -40,7 +40,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< currencyManager, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick, 'getSubgraphClient'>) { + Pick, 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY, advancedLogic.extensions.anyToEthProxy, @@ -64,7 +64,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { @@ -127,7 +127,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< * @param paymentNetwork the payment network * @returns The network of payment */ - protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.EvmChainName { + protected getPaymentChain(request: RequestLogicTypes.IRequest): ChainTypes.IEvmChain { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); diff --git a/packages/payment-detection/src/erc20/fee-proxy-contract.ts b/packages/payment-detection/src/erc20/fee-proxy-contract.ts index 6eea1531c4..89a781ad6c 100644 --- a/packages/payment-detection/src/erc20/fee-proxy-contract.ts +++ b/packages/payment-detection/src/erc20/fee-proxy-contract.ts @@ -1,10 +1,5 @@ import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyDefinition, EvmChains, @@ -81,7 +76,7 @@ export abstract class ERC20FeeProxyPaymentDetectorBase< * Handle payment networks with ERC20 fee proxy contract extension on EVM (default) or Near chains */ export class ERC20FeeProxyPaymentDetector< - TChain extends CurrencyTypes.VMChainName = CurrencyTypes.EvmChainName, + TChain extends ChainTypes.VMChain = ChainTypes.IEvmChain, > extends ERC20FeeProxyPaymentDetectorBase< ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, PaymentTypes.IERC20FeePaymentEventParameters @@ -167,12 +162,12 @@ export class ERC20FeeProxyPaymentDetector< protected getTheGraphInfoRetriever( paymentChain: TChain, - subgraphClient: TheGraphClient | TheGraphClient, + subgraphClient: TheGraphClient | TheGraphClient, ): TheGraphInfoRetriever | NearInfoRetriever { const graphInfoRetriever = EvmChains.isChainSupported(paymentChain) ? new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager) : NearChains.isChainSupported(paymentChain) && this.network - ? new NearInfoRetriever(subgraphClient as TheGraphClient) + ? new NearInfoRetriever(subgraphClient as TheGraphClient) : undefined; if (!graphInfoRetriever) { throw new Error( diff --git a/packages/payment-detection/src/erc20/proxy-contract.ts b/packages/payment-detection/src/erc20/proxy-contract.ts index ed7205509c..8076c61ff2 100644 --- a/packages/payment-detection/src/erc20/proxy-contract.ts +++ b/packages/payment-detection/src/erc20/proxy-contract.ts @@ -22,7 +22,7 @@ export class ERC20ProxyPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PnReferenceBased.IReferenceBased, PaymentTypes.IERC20PaymentEventParameters > { - private readonly getSubgraphClient: TGetSubGraphClient; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions @@ -32,7 +32,7 @@ export class ERC20ProxyPaymentDetector extends ReferenceBasedDetector< currencyManager, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick, 'getSubgraphClient'>) { + Pick, 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_PROXY_CONTRACT, advancedLogic.extensions.proxyContractErc20, @@ -56,7 +56,7 @@ export class ERC20ProxyPaymentDetector extends ReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { diff --git a/packages/payment-detection/src/erc20/transferable-receivable.ts b/packages/payment-detection/src/erc20/transferable-receivable.ts index 7ee8243752..88ab4e62c9 100644 --- a/packages/payment-detection/src/erc20/transferable-receivable.ts +++ b/packages/payment-detection/src/erc20/transferable-receivable.ts @@ -24,7 +24,7 @@ export class ERC20TransferableReceivablePaymentDetector extends FeeReferenceBase ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, PaymentTypes.IERC20PaymentEventParameters > { - private readonly getSubgraphClient: TGetSubGraphClient; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions @@ -34,7 +34,7 @@ export class ERC20TransferableReceivablePaymentDetector extends FeeReferenceBase currencyManager, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick, 'getSubgraphClient'>) { + Pick, 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE, advancedLogic.extensions.erc20TransferableReceivable, @@ -58,7 +58,7 @@ export class ERC20TransferableReceivablePaymentDetector extends FeeReferenceBase toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { // To satisfy typescript diff --git a/packages/payment-detection/src/erc777/superfluid-detector.ts b/packages/payment-detection/src/erc777/superfluid-detector.ts index 3f329554b8..fb7eebfe7f 100644 --- a/packages/payment-detection/src/erc777/superfluid-detector.ts +++ b/packages/payment-detection/src/erc777/superfluid-detector.ts @@ -1,9 +1,4 @@ -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { SuperFluidInfoRetriever } from './superfluid-retriever'; import { ReferenceBasedDetector } from '../reference-based-detector'; import * as PaymentReferenceCalculator from '../payment-reference-calculator'; @@ -96,7 +91,7 @@ export class SuperFluidPaymentDetector extends ReferenceBasedDetector< address: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, ): Promise> { if (!address) { return { diff --git a/packages/payment-detection/src/erc777/superfluid-retriever.ts b/packages/payment-detection/src/erc777/superfluid-retriever.ts index 314491cfda..8babcdcfa5 100644 --- a/packages/payment-detection/src/erc777/superfluid-retriever.ts +++ b/packages/payment-detection/src/erc777/superfluid-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { FlowUpdatedEvent, SentEvent } from '../thegraph/generated/graphql-superfluid'; import { getTheGraphSuperfluidClient, @@ -23,7 +23,7 @@ export class SuperFluidInfoRetriever { * @param tokenContractAddress The address of the ERC777 contract * @param toAddress Address of the balance we want to check * @param eventName Indicate if it is an address for payment or refund - * @param network The Ethereum network to use + * @param chain The Ethereum network to use * @param options Extra options to GraphQL client */ constructor( @@ -31,10 +31,10 @@ export class SuperFluidInfoRetriever { private tokenContractAddress: string | null, private toAddress: string, private eventName: PaymentTypes.EVENTS_NAMES, - private network: string, + private chain: ChainTypes.IEvmChain, private options?: TheGraphClientOptions, ) { - this.client = getTheGraphSuperfluidClient(this.network, this.options); + this.client = getTheGraphSuperfluidClient(this.chain, this.options); } private getGraphVariables(): GraphPaymentQueryParams { @@ -66,7 +66,7 @@ export class SuperFluidInfoRetriever { } /** - * First MVP version which convert : + * First MVP version which converts * stream events queried from SuperFluid subgraph * into payment events with the parameters expected by extractEvents function * to compute balance from amounts in ERC20 style transactions diff --git a/packages/payment-detection/src/eth/fee-proxy-detector.ts b/packages/payment-detection/src/eth/fee-proxy-detector.ts index 2f27e1b43f..e07edec462 100644 --- a/packages/payment-detection/src/eth/fee-proxy-detector.ts +++ b/packages/payment-detection/src/eth/fee-proxy-detector.ts @@ -29,7 +29,7 @@ export class EthFeeProxyPaymentDetector extends FeeReferenceBasedDetector< ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, PaymentTypes.IETHFeePaymentEventParameters > { - private readonly getSubgraphClient: TGetSubGraphClient; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions */ @@ -38,7 +38,7 @@ export class EthFeeProxyPaymentDetector extends FeeReferenceBasedDetector< currencyManager, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick, 'getSubgraphClient'>) { + Pick, 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT, advancedLogic.extensions.feeProxyContractEth, @@ -63,7 +63,7 @@ export class EthFeeProxyPaymentDetector extends FeeReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased extends ExtensionTypes.IExtension< infer X > diff --git a/packages/payment-detection/src/eth/input-data.ts b/packages/payment-detection/src/eth/input-data.ts index 75e822d755..f6bcc2f1ff 100644 --- a/packages/payment-detection/src/eth/input-data.ts +++ b/packages/payment-detection/src/eth/input-data.ts @@ -31,8 +31,8 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PnReferenceBased.IReferenceBased, PaymentTypes.IETHPaymentEventParameters > { - private explorerApiKeys: Partial>; - private readonly getSubgraphClient: TGetSubGraphClient; + private explorerApiKeys: Partial>; + private readonly getSubgraphClient: TGetSubGraphClient; /** * @param extension The advanced logic payment network extensions @@ -43,10 +43,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< explorerApiKeys, getSubgraphClient, }: ReferenceBasedDetectorOptions & - Pick< - PaymentNetworkOptions, - 'explorerApiKeys' | 'getSubgraphClient' - >) { + Pick, 'explorerApiKeys' | 'getSubgraphClient'>) { super( ExtensionTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA, advancedLogic.extensions.ethereumInputData, @@ -71,7 +68,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.EvmChainName, + paymentChain: ChainTypes.IEvmChain, paymentNetwork: ExtensionTypes.IState, ): Promise< PaymentTypes.AllNetworkEvents< diff --git a/packages/payment-detection/src/native-token-detector.ts b/packages/payment-detection/src/native-token-detector.ts index 943d769160..13a1cb6791 100644 --- a/packages/payment-detection/src/native-token-detector.ts +++ b/packages/payment-detection/src/native-token-detector.ts @@ -10,7 +10,7 @@ export abstract class NativeTokenPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PnReferenceBased.IReferenceBased, PaymentTypes.IETHPaymentEventParameters > { - protected readonly network: CurrencyTypes.NearChainName | undefined; + protected readonly network: ChainTypes.INearChain | undefined; protected readonly getSubgraphClient: NativeDetectorOptions['getSubgraphClient']; protected constructor({ network, diff --git a/packages/payment-detection/src/near/near-conversion-detector.ts b/packages/payment-detection/src/near/near-conversion-detector.ts index fadac7f48f..b5ea01888b 100644 --- a/packages/payment-detection/src/near/near-conversion-detector.ts +++ b/packages/payment-detection/src/near/near-conversion-detector.ts @@ -31,12 +31,12 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto } public static getContractName = ( - chainName: CurrencyTypes.NearChainName, + chainName: ChainTypes.INearChain, paymentNetworkVersion = '0.1.0', ): string => { const version = NearConversionNativeTokenPaymentDetector.getVersionOrThrow(paymentNetworkVersion); - const versionMap: Record> = { + const versionMap: Record> = { aurora: { '0.1.0': 'native.conversion.reqnetwork.near' }, near: { '0.1.0': 'native.conversion.reqnetwork.near' }, 'aurora-testnet': { @@ -69,7 +69,7 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.NearChainName, + paymentChain: ChainTypes.INearChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { @@ -104,7 +104,7 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto return transferEvents; } - protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.NearChainName { + protected getPaymentChain(request: RequestLogicTypes.IRequest): ChainTypes.INearChain { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); diff --git a/packages/payment-detection/src/near/near-detector.ts b/packages/payment-detection/src/near/near-detector.ts index 97311a46fd..3d26154ffc 100644 --- a/packages/payment-detection/src/near/near-detector.ts +++ b/packages/payment-detection/src/near/near-detector.ts @@ -29,11 +29,11 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { } public static getContractName = ( - chainName: CurrencyTypes.NearChainName, + chainName: ChainTypes.INearChain, paymentNetworkVersion = '0.2.0', ): string => { const version = NearNativeTokenPaymentDetector.getVersionOrThrow(paymentNetworkVersion); - const versionMap: Record> = { + const versionMap: Record> = { aurora: { '0.1.0': 'requestnetwork.near', '0.2.0': 'requestnetwork.near' }, near: { '0.1.0': 'requestnetwork.near', '0.2.0': 'requestnetwork.near' }, 'aurora-testnet': { @@ -67,7 +67,7 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { address: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.NearChainName, + paymentChain: ChainTypes.INearChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!address) { diff --git a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts index 3e4280bf0c..6ff5f7cd6a 100644 --- a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts @@ -13,7 +13,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: CurrencyTypes.VMChainName; + paymentChain: ChainTypes.VMChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The maximum span between the time the rate was fetched and the payment */ @@ -30,7 +30,7 @@ export class NearConversionInfoRetriever extends NearInfoRetriever { * @param eventName Indicate if it is an address for payment or refund * @param network The id of network we want to check */ - constructor(protected readonly client: TheGraphClient) { + constructor(protected readonly client: TheGraphClient) { super(client); } public async getTransferEvents( diff --git a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts index 855bdc87f0..9b79f012e5 100644 --- a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts @@ -16,7 +16,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: CurrencyTypes.VMChainName; + paymentChain: ChainTypes.VMChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The list of ERC20 tokens addresses accepted for payments and refunds. Set to `undefined` for payments in NEAR token. */ @@ -33,7 +33,7 @@ export class NearInfoRetriever implements ITheGraphBaseInfoRetriever) {} + constructor(protected readonly client: TheGraphClient) {} public async getTransferEvents( params: TransferEventsParams, diff --git a/packages/payment-detection/src/payment-network-factory.ts b/packages/payment-detection/src/payment-network-factory.ts index f2f702de75..ebc4456cb9 100644 --- a/packages/payment-detection/src/payment-network-factory.ts +++ b/packages/payment-detection/src/payment-network-factory.ts @@ -47,13 +47,13 @@ const supportedPaymentNetwork: ISupportedPaymentNetworkByCurrency = { }, ERC20: { aurora: { - [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, + [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, }, 'aurora-testnet': { - [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, + [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, }, 'near-testnet': { - [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, + [PN_ID.ERC20_FEE_PROXY_CONTRACT]: ERC20FeeProxyPaymentDetector, }, '*': { @@ -123,7 +123,7 @@ export class PaymentNetworkFactory { public createPaymentNetwork( paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, currencyType: RequestLogicTypes.CURRENCY, - paymentChain?: CurrencyTypes.ChainName, + paymentChain?: ChainTypes.IChain, paymentNetworkVersion?: string, ): PaymentTypes.IPaymentNetwork { const network = paymentChain ?? 'mainnet'; @@ -154,7 +154,7 @@ export class PaymentNetworkFactory { if (detector.extension && 'getDeploymentInformation' in detectorClass) { // this throws when the contract isn't deployed and was mandatory for payment detection (detectorClass as ContractBasedDetector).getDeploymentInformation( - network as CurrencyTypes.VMChainName, + network as ChainTypes.VMChain, paymentNetworkVersion || detector.extension.currentVersion, ); } diff --git a/packages/payment-detection/src/reference-based-detector.ts b/packages/payment-detection/src/reference-based-detector.ts index d97e1690fb..580c162196 100644 --- a/packages/payment-detection/src/reference-based-detector.ts +++ b/packages/payment-detection/src/reference-based-detector.ts @@ -147,7 +147,7 @@ export abstract class ReferenceBasedDetector< address: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: CurrencyTypes.ChainName, + paymentChain: ChainTypes.IChain, paymentNetwork: TExtension extends ExtensionTypes.IExtension ? ExtensionTypes.IState : never, @@ -157,7 +157,7 @@ export abstract class ReferenceBasedDetector< * Get the network of the payment * @returns The network of payment */ - protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.ChainName { + protected getPaymentChain(request: RequestLogicTypes.IRequest): ChainTypes.IChain { const network = request.currency.network; if (!network) { throw Error(`request.currency.network must be defined for ${this.paymentNetworkId}`); diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index 097600af1d..e94390a982 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -27,8 +27,8 @@ const THE_GRAPH_URL_STUDIO_ZKSYNC = * * @type TGraphClientVariant: null if no variant, 'near' if native token payments detection on Near */ -export type TheGraphClient = - (TChain extends CurrencyTypes.NearChainName +export type TheGraphClient = + (TChain extends ChainTypes.INearChain ? ReturnType : ReturnType) & { options?: TheGraphQueryOptions; @@ -71,16 +71,14 @@ export const getTheGraphClient = (network: string, url: string, options?: TheGra export const getTheGraphEvmClient = (url: string, options?: TheGraphClientOptions) => { const [clientOptions, queryOptions] = extractClientOptions(url, options); - const sdk: TheGraphClient = getSdk( - new GraphQLClient(url, clientOptions), - ); + const sdk: TheGraphClient = getSdk(new GraphQLClient(url, clientOptions)); sdk.options = queryOptions; return sdk; }; export const getTheGraphNearClient = (url: string, options?: TheGraphClientOptions) => { const [clientOptions, queryOptions] = extractClientOptions(url, options); - const sdk: TheGraphClient = getNearSdk( + const sdk: TheGraphClient = getNearSdk( new GraphQLClient(url, clientOptions), ); sdk.options = queryOptions; @@ -88,7 +86,7 @@ export const getTheGraphNearClient = (url: string, options?: TheGraphClientOptio }; export const defaultGetTheGraphClient = ( - network: CurrencyTypes.ChainName, + network: ChainTypes.IChain, options?: TheGraphClientOptions, ) => { return network === 'private' diff --git a/packages/payment-detection/src/thegraph/superfluid.ts b/packages/payment-detection/src/thegraph/superfluid.ts index e869dd7366..539337a11e 100644 --- a/packages/payment-detection/src/thegraph/superfluid.ts +++ b/packages/payment-detection/src/thegraph/superfluid.ts @@ -1,6 +1,7 @@ import { GraphQLClient } from 'graphql-request'; import { getSdk } from './generated/graphql-superfluid'; import { RequestConfig } from 'graphql-request/src/types'; +import { ChainTypes } from '@requestnetwork/types'; const BASE_URL = `https://api.thegraph.com`; const NETWORK_TO_URL: Record = { @@ -20,19 +21,19 @@ export type TheGraphClientOptions = RequestConfig & { }; export const getTheGraphSuperfluidClient = ( - network: string, + chain: ChainTypes.IEvmChain, options?: TheGraphClientOptions, ): TheGraphSuperfluidClient => { const { baseUrl: _baseUrl, ...clientOptions } = options ?? {}; - const baseUrl = _baseUrl || network === 'private' ? 'http://localhost:8000' : BASE_URL; + const baseUrl = _baseUrl || chain.name === 'private' ? 'http://localhost:8000' : BASE_URL; // Note: it is also possible to use the IPFS hash of the subgraph // eg. /subgraphs/id/QmcCaSkefrmhe4xQj6Y6BBbHiFkbrn6UGDEBUWER7nt399 // which is a better security but would require an update of the // library each time the subgraph is updated, which isn't ideal // for early testing. const url = `${baseUrl}/subgraphs/name/superfluid-finance/protocol-v1-${ - NETWORK_TO_URL[network] || network + NETWORK_TO_URL[chain.name] || chain.name }`; return getSdk(new GraphQLClient(url, clientOptions)); }; diff --git a/packages/payment-detection/src/types.ts b/packages/payment-detection/src/types.ts index 2ffa154f38..484548cebc 100644 --- a/packages/payment-detection/src/types.ts +++ b/packages/payment-detection/src/types.ts @@ -1,6 +1,6 @@ import { AdvancedLogicTypes, - CurrencyTypes, + ChainTypes, ExtensionTypes, PaymentTypes, } from '@requestnetwork/types'; @@ -25,7 +25,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: CurrencyTypes.VMChainName; + paymentChain: ChainTypes.VMChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The list of ERC20 tokens addresses accepted for payments and refunds OR undefined for native tokens (e.g. ETH) */ @@ -94,21 +94,19 @@ export interface ISupportedPaymentNetworkByCurrency< [currency: string]: ISupportedPaymentNetworkByNetwork; } -export type TGetSubGraphClient = ( - network: CurrencyTypes.ChainName, -) => TChain extends CurrencyTypes.VMChainName ? TheGraphClient | undefined : undefined; +export type TGetSubGraphClient = ( + network: ChainTypes.IChain, +) => TChain extends ChainTypes.VMChain ? TheGraphClient | undefined : undefined; -export type PaymentNetworkOptions< - TChain extends CurrencyTypes.ChainName = CurrencyTypes.ChainName, -> = { +export type PaymentNetworkOptions = { /** override default bitcoin detection provider */ bitcoinDetectionProvider?: PaymentTypes.IBitcoinDetectionProvider; /** the explorer API (e.g. Etherscan) api keys, for PNs that rely on it. Record by network name */ - explorerApiKeys: Partial>; + explorerApiKeys: Partial>; /** override the default Subgraph for payment detection (EVM, Near) */ getSubgraphClient: TGetSubGraphClient; /** override the default RPC provider (EVM) */ - getRpcProvider: (network: CurrencyTypes.ChainName) => providers.Provider; + getRpcProvider: (network: string) => providers.Provider; }; export type ReferenceBasedDetectorOptions = { @@ -117,7 +115,7 @@ export type ReferenceBasedDetectorOptions = { }; export type NativeDetectorOptions = ReferenceBasedDetectorOptions & { - network: CurrencyTypes.NearChainName; + network: ChainTypes.INearChain; /** override the default Subgraph for payment detection (EVM, Near) */ - getSubgraphClient: TGetSubGraphClient; + getSubgraphClient: TGetSubGraphClient; }; diff --git a/packages/payment-detection/src/utils.ts b/packages/payment-detection/src/utils.ts index ba76116e96..4120b45753 100644 --- a/packages/payment-detection/src/utils.ts +++ b/packages/payment-detection/src/utils.ts @@ -10,6 +10,7 @@ import { getAddress, keccak256, LogDescription } from 'ethers/lib/utils'; import { ContractArtifact, DeploymentInformation } from '@requestnetwork/smart-contracts'; import { NetworkNotSupported, VersionNotSupported } from './balance-error'; import * as PaymentReferenceCalculator from './payment-reference-calculator'; +import { IReferenceBasedCreationParameters } from './types'; /** * Converts the Log's args from array to an object with keys being the name of the arguments @@ -62,7 +63,7 @@ const getChainlinkPaddingSize = ({ export type DeploymentInformationWithVersion = DeploymentInformation & { contractVersion: string }; export type GetDeploymentInformation = ( - network: CurrencyTypes.VMChainName, + network: ChainTypes.VMChain, paymentNetworkVersion: string, ) => TAllowUndefined extends false ? DeploymentInformationWithVersion @@ -140,7 +141,7 @@ export function getPaymentNetworkExtension( ) as ExtensionTypes.IPaymentNetworkState; } -type PaymentParameters = PaymentTypes.IReferenceBasedCreationParameters & +type PaymentParameters = IReferenceBasedCreationParameters & PaymentTypes.IDeclarativePaymentEventParameters; /** Gets the payment info based on parameters, for payment reference calculation */ 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 73477923c4..7255f9c6c2 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 @@ -56,7 +56,7 @@ describe('api/any/conversion-fee-proxy-contract', () => { jest.clearAllMocks(); }); - const testSuite = (network: CurrencyTypes.EvmChainName) => { + const testSuite = (network: ChainTypes.IEvmChain) => { it(`can createExtensionsDataForCreation on ${network}`, async () => { await anyToErc20Proxy.createExtensionsDataForCreation({ paymentAddress: 'ethereum address', 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 255e3e635f..d211d9af3f 100644 --- a/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts +++ b/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts @@ -10,7 +10,7 @@ import { CurrencyManager } from '@requestnetwork/currency'; import { ERC20FeeProxyPaymentDetector } from '../../src/erc20/fee-proxy-contract'; import { mockAdvancedLogicBase } from '../utils'; -let erc20FeeProxyContract: ERC20FeeProxyPaymentDetector; +let erc20FeeProxyContract: ERC20FeeProxyPaymentDetector; const createAddPaymentAddressAction = jest.fn(); const createAddRefundAddressAction = jest.fn(); @@ -473,7 +473,7 @@ describe('api/erc20/fee-proxy-contract', () => { describe('on Near', () => { beforeEach(() => { // Same Detector, but instanciated with a Near network and a mocked Near graph client - erc20FeeProxyContract = new ERC20FeeProxyPaymentDetector({ + erc20FeeProxyContract = new ERC20FeeProxyPaymentDetector({ advancedLogic: mockAdvancedLogic, currencyManager, network: 'aurora-testnet', diff --git a/packages/payment-detection/test/erc20/transferable-receivable.test.ts b/packages/payment-detection/test/erc20/transferable-receivable.test.ts index c0bf1f4dab..ea251d7559 100644 --- a/packages/payment-detection/test/erc20/transferable-receivable.test.ts +++ b/packages/payment-detection/test/erc20/transferable-receivable.test.ts @@ -379,7 +379,7 @@ describe('api/erc20/transferable-receivable-contract', () => { txHash: '0x3e2d6cc2534b1d340ba2954f34e6cc819d6da64ff76863ea89c6d34b15d13c97', from: '0x186e7fe6c34ea0eca7f9c2fd29651fc0443e3f29', to: paymentAddress, - network: 'rinkeby' as CurrencyTypes.EvmChainName, + network: 'rinkeby' as ChainTypes.IEvmChain, salt: '0ee84db293a752c6', amount: '30000000000000', requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1', diff --git a/packages/payment-detection/test/erc777/superfluid-detector.test.ts b/packages/payment-detection/test/erc777/superfluid-detector.test.ts index 33238f026e..1b60fa8b87 100644 --- a/packages/payment-detection/test/erc777/superfluid-detector.test.ts +++ b/packages/payment-detection/test/erc777/superfluid-detector.test.ts @@ -36,7 +36,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { const baseRequestData = { creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { - network: 'private' as CurrencyTypes.EvmChainName, + network: 'private' as ChainTypes.IEvmChain, type: RequestLogicTypes.CURRENCY.ERC20, value: '0x9FBDa871d559710256a2502A2517b794B482Db40', // local ERC20 token }, diff --git a/packages/payment-detection/test/near/near-native-conversion.test.ts b/packages/payment-detection/test/near/near-native-conversion.test.ts index 5f4fcb54e1..c291acb10d 100644 --- a/packages/payment-detection/test/near/near-native-conversion.test.ts +++ b/packages/payment-detection/test/near/near-native-conversion.test.ts @@ -69,7 +69,7 @@ const client = { GetAnyToNativePayments: jest.fn().mockImplementation(() => ({ payments: [graphPaymentEvent], })), -} as any as TheGraphClient; +} as any as TheGraphClient; const infoRetriever = new NearConversionInfoRetriever(client); const mockedGetSubgraphClient = jest.fn().mockImplementation(() => client); diff --git a/packages/payment-detection/test/near/near-native.test.ts b/packages/payment-detection/test/near/near-native.test.ts index 31c14b20ec..0c0ba9f5db 100644 --- a/packages/payment-detection/test/near/near-native.test.ts +++ b/packages/payment-detection/test/near/near-native.test.ts @@ -49,7 +49,7 @@ const client = { GetNearPayments: jest.fn().mockImplementation(() => ({ payments: [graphPaymentEvent], })), -} as any as TheGraphClient; +} as any as TheGraphClient; const mockedGetSubgraphClient = jest.fn().mockImplementation(() => client); const infoRetriever = new NearInfoRetriever(client); diff --git a/packages/payment-processor/src/payment/batch-conversion-proxy.ts b/packages/payment-processor/src/payment/batch-conversion-proxy.ts index ea77ce0d6d..a52061745c 100644 --- a/packages/payment-processor/src/payment/batch-conversion-proxy.ts +++ b/packages/payment-processor/src/payment/batch-conversion-proxy.ts @@ -2,8 +2,8 @@ import { ContractTransaction, Signer, providers, BigNumber, constants } from 'et import { batchConversionPaymentsArtifact } from '@requestnetwork/smart-contracts'; import { BatchConversionPayments__factory } from '@requestnetwork/smart-contracts/types'; import { + ChainTypes, ClientTypes, - CurrencyTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes, @@ -373,7 +373,7 @@ function getUSDPathsForFeeLimit( * @returns */ function getBatchDeploymentInformation( - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, version?: string, ): { address: string } | null { return { address: batchConversionPaymentsArtifact.getAddress(network, version) }; diff --git a/packages/payment-processor/src/payment/utils-near.ts b/packages/payment-processor/src/payment/utils-near.ts index a88bd093ff..6b6e83770f 100644 --- a/packages/payment-processor/src/payment/utils-near.ts +++ b/packages/payment-processor/src/payment/utils-near.ts @@ -62,7 +62,7 @@ const GAS_LIMIT_FUNGIBLE_PROXY = GAS_LIMIT.mul(4).toString(); // 400 TGas export const processNearPayment = async ( walletConnection: WalletConnection, - network: CurrencyTypes.NearChainName, + network: ChainTypes.INearChain, amount: BigNumberish, to: string, paymentReference: string, @@ -114,7 +114,7 @@ export const processNearPayment = async ( */ export const processNearPaymentWithConversion = async ( walletConnection: WalletConnection, - network: CurrencyTypes.NearChainName, + network: ChainTypes.INearChain, amount: BigNumberish, to: string, paymentReference: string, @@ -169,7 +169,7 @@ export const processNearPaymentWithConversion = async ( export const processNearFungiblePayment = async ( walletConnection: WalletConnection, - network: CurrencyTypes.NearChainName, + network: ChainTypes.INearChain, amount: BigNumberish, to: string, paymentReference: string, diff --git a/packages/payment-processor/src/payment/utils.ts b/packages/payment-processor/src/payment/utils.ts index a340c6fc69..505932c7e4 100644 --- a/packages/payment-processor/src/payment/utils.ts +++ b/packages/payment-processor/src/payment/utils.ts @@ -79,7 +79,7 @@ export function getRequestPaymentValues(request: ClientTypes.IRequestData): { expectedStartDate?: string; acceptedTokens?: string[]; maxRateTimespan?: string; - network?: CurrencyTypes.ChainName; + network?: ChainTypes.IChain; version: string; } { const extension = getPaymentNetworkExtension(request); @@ -142,7 +142,7 @@ export function getPnAndNetwork(request: ClientTypes.IRequestData): { export const getProxyAddress = ( request: ClientTypes.IRequestData, getDeploymentInformation: ( - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, version: string, ) => { address: string } | null, version?: string, diff --git a/packages/payment-processor/test/payment/batch-proxy.test.ts b/packages/payment-processor/test/payment/batch-proxy.test.ts index 094291f24d..268bfd5790 100644 --- a/packages/payment-processor/test/payment/batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/batch-proxy.test.ts @@ -775,7 +775,7 @@ describe('batch-proxy', () => { }); it("should throw an error if one request's currencyInfo has no network", async () => { - FAURequest.currencyInfo.network = '' as CurrencyTypes.ChainName; + FAURequest.currencyInfo.network = '' as ChainTypes.IChain; await expect( payBatchConversionProxyRequest(enrichedRequests, wallet, options), ).rejects.toThrowError( diff --git a/packages/payment-processor/test/payment/encoder-approval.test.ts b/packages/payment-processor/test/payment/encoder-approval.test.ts index 69f6d606ba..3d3f4e6f0a 100644 --- a/packages/payment-processor/test/payment/encoder-approval.test.ts +++ b/packages/payment-processor/test/payment/encoder-approval.test.ts @@ -257,12 +257,12 @@ beforeAll(async () => { await revokeErc20Approval(proxyERC20Conv, alphaContractAddress, wallet); proxyERC20Swap = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, + validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, ); await revokeErc20Approval(proxyERC20Swap, alphaContractAddress, wallet); proxyERC20SwapConv = erc20SwapConversionArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, + validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, ); await revokeErc20Approval(proxyERC20SwapConv, alphaContractAddress, wallet); }); diff --git a/packages/payment-processor/test/payment/encoder-payment.test.ts b/packages/payment-processor/test/payment/encoder-payment.test.ts index 58f1ceed1d..b1fd9c7ea7 100644 --- a/packages/payment-processor/test/payment/encoder-payment.test.ts +++ b/packages/payment-processor/test/payment/encoder-payment.test.ts @@ -316,7 +316,7 @@ describe('Payment encoder handles ERC20 Swap Proxy', () => { }); const proxyAddress = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, + validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, ); expect(paymentTransaction).toEqual({ @@ -335,7 +335,7 @@ describe('Payment encoder handles ERC20 Swap & Conversion Proxy', () => { }); const proxyAddress = erc20SwapConversionArtifact.getAddress( - alphaConversionSettings.currency.network as CurrencyTypes.EvmChainName, + alphaConversionSettings.currency.network as ChainTypes.IEvmChain, ); expect(paymentTransaction).toEqual({ diff --git a/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts b/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts index 867fa2d718..77eb20210d 100644 --- a/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts @@ -139,7 +139,7 @@ const testSuite = ( }); it("should throw an error if one request's currencyInfo has no network", async () => { - request2.currencyInfo.network = '' as CurrencyTypes.ChainName; + request2.currencyInfo.network = '' as ChainTypes.IChain; await expect( payBatchProxyRequest([request1, request2], batchVersion, wallet, batchFee), ).rejects.toThrowError( diff --git a/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts b/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts index 489f4c9f1d..11c335b040 100644 --- a/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts +++ b/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts @@ -68,7 +68,7 @@ const validRequest: ClientTypes.IRequestData = { }; const escrowAddress = erc20EscrowToPayArtifact.getAddress( - validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, + validRequest.currencyInfo.network! as ChainTypes.IEvmChain, ); const payerAddress = wallet.address; @@ -105,7 +105,7 @@ describe('erc20-escrow-payment tests:', () => { }); it('Should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.ChainName; + request.currencyInfo.network = '' as ChainTypes.IChain; await expect(Escrow.payEscrow(request, wallet)).rejects.toThrowError('Unsupported chain '); }); it('Should throw an error if request has no extension', async () => { diff --git a/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts b/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts index eaf7f1af5c..6283d588ee 100644 --- a/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts @@ -108,7 +108,7 @@ describe('erc20-fee-proxy', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.ChainName; + request.currencyInfo.network = '' as ChainTypes.IChain; await expect(payErc20FeeProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-erc20-fee-proxy-contract request', ); diff --git a/packages/payment-processor/test/payment/erc20-proxy.test.ts b/packages/payment-processor/test/payment/erc20-proxy.test.ts index dee210f1c8..f2f61a4ce1 100644 --- a/packages/payment-processor/test/payment/erc20-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-proxy.test.ts @@ -92,7 +92,7 @@ describe('payErc20ProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect(payErc20ProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-erc20-proxy-contract request', ); diff --git a/packages/payment-processor/test/payment/erc777-stream.test.ts b/packages/payment-processor/test/payment/erc777-stream.test.ts index ebd8bc9d0e..0ba334e0c2 100644 --- a/packages/payment-processor/test/payment/erc777-stream.test.ts +++ b/packages/payment-processor/test/payment/erc777-stream.test.ts @@ -111,7 +111,7 @@ describe('erc777-stream', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect(payErc777StreamRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-erc777-stream request', ); diff --git a/packages/payment-processor/test/payment/eth-batch-proxy.test.ts b/packages/payment-processor/test/payment/eth-batch-proxy.test.ts index 3123bd22a2..e40d497aa6 100644 --- a/packages/payment-processor/test/payment/eth-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-batch-proxy.test.ts @@ -106,7 +106,7 @@ describe('payBatchProxyRequest', () => { it('should throw an error if in one request, currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect( payBatchProxyRequest([validRequest, request], batchVersion, wallet, batchFee), ).rejects.toThrowError( diff --git a/packages/payment-processor/test/payment/eth-fee-proxy.test.ts b/packages/payment-processor/test/payment/eth-fee-proxy.test.ts index 260cb503d3..99e2bee54b 100644 --- a/packages/payment-processor/test/payment/eth-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-fee-proxy.test.ts @@ -86,7 +86,7 @@ describe('payEthFeeProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect(payEthFeeProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-fee-proxy-contract request', ); diff --git a/packages/payment-processor/test/payment/eth-input-data.test.ts b/packages/payment-processor/test/payment/eth-input-data.test.ts index 0d38f1c37e..db548bc304 100644 --- a/packages/payment-processor/test/payment/eth-input-data.test.ts +++ b/packages/payment-processor/test/payment/eth-input-data.test.ts @@ -81,7 +81,7 @@ describe('payEthInputDataRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect(payEthInputDataRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-input-data request', ); diff --git a/packages/payment-processor/test/payment/eth-proxy.test.ts b/packages/payment-processor/test/payment/eth-proxy.test.ts index 5a85a1842f..880932df17 100644 --- a/packages/payment-processor/test/payment/eth-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-proxy.test.ts @@ -87,7 +87,7 @@ describe('payEthProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect(payEthProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-input-data request', ); diff --git a/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts b/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts index 28db587659..0528f84214 100644 --- a/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts @@ -85,9 +85,7 @@ describe('swap-erc20-fee-proxy', () => { beforeAll(async () => { // revoke erc20SwapToPay approval await revokeErc20Approval( - erc20SwapToPayArtifact.getAddress( - validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, - ), + erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network! as ChainTypes.IEvmChain), alphaErc20Address, wallet.provider, ); @@ -97,7 +95,7 @@ describe('swap-erc20-fee-proxy', () => { // revoke erc20SwapToPay approval await revokeErc20Approval( erc20SwapToPayArtifact.getAddress( - validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, + validRequest.currencyInfo.network! as ChainTypes.IEvmChain, ), alphaErc20Address, wallet.provider, @@ -126,7 +124,7 @@ describe('swap-erc20-fee-proxy', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; + request.currencyInfo.network = '' as ChainTypes.IEvmChain; await expect( swapErc20FeeProxyRequest(request, wallet, validSwapSettings), ).rejects.toThrowError('Unsupported chain '); diff --git a/packages/request-client.js/src/api/request.ts b/packages/request-client.js/src/api/request.ts index c40656814d..41d27f4921 100644 --- a/packages/request-client.js/src/api/request.ts +++ b/packages/request-client.js/src/api/request.ts @@ -709,7 +709,7 @@ export default class Request { public async getEscrowData( paymentReference: string, - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, ): Promise { const escrowContractAddress = erc20EscrowToPayArtifact.getAddress(network); const escrowInfoRetriever = new EscrowERC20InfoRetriever( diff --git a/packages/request-client.js/src/http-metamask-data-access.ts b/packages/request-client.js/src/http-metamask-data-access.ts index f3c7ab2777..4a45df8bbb 100644 --- a/packages/request-client.js/src/http-metamask-data-access.ts +++ b/packages/request-client.js/src/http-metamask-data-access.ts @@ -20,7 +20,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { } = {}; private provider: ethers.providers.JsonRpcProvider | ethers.providers.Web3Provider; - private networkName: CurrencyTypes.EvmChainName = 'private'; + private networkName: ChainTypes.IEvmChain = 'private'; /** * Creates an instance of HttpDataAccess. diff --git a/packages/request-node/src/dataAccess.ts b/packages/request-node/src/dataAccess.ts index 9f51609b41..4fb98a4636 100644 --- a/packages/request-node/src/dataAccess.ts +++ b/packages/request-node/src/dataAccess.ts @@ -8,7 +8,7 @@ import { PendingStore } from '@requestnetwork/data-access'; import { EthereumStorage, EthereumTransactionSubmitter } from '@requestnetwork/ethereum-storage'; export function getDataAccess( - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, ipfsStorage: StorageTypes.IIpfsStorage, logger: LogTypes.ILogger, ): DataAccessTypes.IDataAccess { diff --git a/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts b/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts index ecb64c0293..3c83e8e066 100644 --- a/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts +++ b/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts @@ -11,8 +11,8 @@ import { CurrencyTypes } from '@requestnetwork/types'; export default async function () { const [deployer] = await hre.ethers.getSigners(); const constructorArguments = [ - erc20FeeProxyArtifact.getAddress(hre.network.name as CurrencyTypes.EvmChainName), - ethereumFeeProxyArtifact.getAddress(hre.network.name as CurrencyTypes.EvmChainName), + erc20FeeProxyArtifact.getAddress(hre.network.name as ChainTypes.IEvmChain), + ethereumFeeProxyArtifact.getAddress(hre.network.name as ChainTypes.IEvmChain), hre.ethers.constants.AddressZero, hre.ethers.constants.AddressZero, hre.ethers.constants.AddressZero, diff --git a/packages/smart-contracts/scripts-create2/constructor-args.ts b/packages/smart-contracts/scripts-create2/constructor-args.ts index 042da3569c..09ea1ab38b 100644 --- a/packages/smart-contracts/scripts-create2/constructor-args.ts +++ b/packages/smart-contracts/scripts-create2/constructor-args.ts @@ -8,10 +8,7 @@ const getAdminWalletAddress = (contract: string): string => { return process.env.ADMIN_WALLET_ADDRESS; }; -export const getConstructorArgs = ( - contract: string, - network?: CurrencyTypes.EvmChainName, -): string[] => { +export const getConstructorArgs = (contract: string, network?: ChainTypes.IEvmChain): string[] => { switch (contract) { case 'ChainlinkConversionPath': { return ['0x0000000000000000000000000000000000000000', getAdminWalletAddress(contract)]; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts index 16be222ba5..3cb511e1a9 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts @@ -34,7 +34,7 @@ const BATCH_FEE_AMOUNT_USD_LIMIT = parseUnits('150', 8); */ export const updateChainlinkConversionPath = async ( contract: Contract, - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, txOverrides: Overrides, signer: Wallet, signWithEoa: boolean, @@ -195,7 +195,7 @@ export const updateBatchPaymentFeeAmountUSDLimit = async ( */ export const updatePaymentFeeProxyAddress = async ( contract: Contract, - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, txOverrides: Overrides, proxyType: 'native' | 'erc20', signer: Wallet, @@ -239,7 +239,7 @@ export const updatePaymentFeeProxyAddress = async ( */ export const updateBatchConversionProxy = async ( contract: Contract, - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, txOverrides: Overrides, proxyName: string, signer: Wallet, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts b/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts index a5dde97c15..0ade5735a9 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts @@ -36,7 +36,7 @@ export const executeContractMethod = async ({ signer: Wallet; signWithEoa?: boolean; }): Promise => { - const safeAddress = safeAdminArtifact.getAddress(network as CurrencyTypes.VMChainName); + const safeAddress = safeAdminArtifact.getAddress(network as ChainTypes.VMChain); const txServiceUrl = txServiceUrls[network]; if (!signWithEoa && !!safeAddress && !!txServiceUrl) { const ethAdapter = new EthersAdapter({ diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts index 48f25c6f56..60f408c003 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts @@ -31,7 +31,7 @@ export const setupBatchConversionPayments = async ({ // constants related to chainlink and conversion rate const currencyManager = CurrencyManager.getDefault(); - const setUpActions = async (network: CurrencyTypes.EvmChainName) => { + const setUpActions = async (network: ChainTypes.IEvmChain) => { console.log(`Setup BatchConversionPayments on ${network}`); if (!contractAddress) { diff --git a/packages/smart-contracts/scripts-create2/tenderly.ts b/packages/smart-contracts/scripts-create2/tenderly.ts index 14d831ce48..b60a019a1f 100644 --- a/packages/smart-contracts/scripts-create2/tenderly.ts +++ b/packages/smart-contracts/scripts-create2/tenderly.ts @@ -25,7 +25,7 @@ const capitalizeFirstLetter = (string: string) => string.charAt(0).toUpperCase() * Chains supported by Tenderly. * Supported testnet chains are commented out. */ -const supportedTenderlyChains: CurrencyTypes.EvmChainName[] = [ +const supportedTenderlyChains: ChainTypes.IEvmChain[] = [ 'arbitrum-one', 'arbitrum-rinkeby', 'avalanche', diff --git a/packages/smart-contracts/src/lib/ContractArtifact.ts b/packages/smart-contracts/src/lib/ContractArtifact.ts index cf86e6ec7c..fd605b49ee 100644 --- a/packages/smart-contracts/src/lib/ContractArtifact.ts +++ b/packages/smart-contracts/src/lib/ContractArtifact.ts @@ -13,7 +13,7 @@ export type ArtifactNetworkInfo = { }; /** Deployment information and ABI per network */ -export type ArtifactDeploymentInfo = { +export type ArtifactDeploymentInfo = { abi: JsonFragment[]; deployment: Partial>; }; @@ -21,7 +21,7 @@ export type ArtifactDeploymentInfo = /** Deployment information and ABI per version and network */ export type ArtifactInfo< TVersion extends string = string, - TNetwork extends CurrencyTypes.VMChainName = CurrencyTypes.VMChainName, + TNetwork extends ChainTypes.VMChain = ChainTypes.VMChain, > = Record>; export type DeploymentInformation = { @@ -52,7 +52,7 @@ export class ContractArtifact { * Returns an ethers contract instance for the given `networkName` */ connect( - networkName: CurrencyTypes.EvmChainName, + networkName: ChainTypes.IEvmChain, signerOrProvider: Signer | providers.Provider, version: string = this.lastVersion, ): TContract { @@ -81,7 +81,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns the address of the deployed contract */ - getAddress(networkName: CurrencyTypes.VMChainName, version = this.lastVersion): string { + getAddress(networkName: ChainTypes.VMChain, version = this.lastVersion): string { return this.getDeploymentInformation(networkName, version).address; } @@ -91,7 +91,7 @@ export class ContractArtifact { * @returns the addresses of the deployed contract and the associated version. */ getAllAddresses( - networkName: CurrencyTypes.VMChainName, + networkName: ChainTypes.VMChain, ): { version: string; address: string | undefined }[] { const entries = Object.entries(this.info); return entries.map(([version, { deployment }]) => ({ @@ -107,11 +107,11 @@ export class ContractArtifact { getAllAddressesFromAllNetworks(): { version: string; address: string; - networkName: CurrencyTypes.VMChainName; + networkName: ChainTypes.VMChain; }[] { const deployments = []; for (const version in this.info) { - let networkName: CurrencyTypes.VMChainName; + let networkName: ChainTypes.VMChain; for (networkName in this.info[version].deployment) { const address = this.info[version].deployment[networkName]?.address; if (!address) continue; @@ -131,10 +131,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns the number of the block where the contract was deployed */ - getCreationBlockNumber( - networkName: CurrencyTypes.VMChainName, - version = this.lastVersion, - ): number { + getCreationBlockNumber(networkName: ChainTypes.VMChain, version = this.lastVersion): number { return this.getDeploymentInformation(networkName, version).creationBlockNumber; } @@ -145,7 +142,7 @@ export class ContractArtifact { * @returns The address and the number of the creation block */ getDeploymentInformation( - networkName: CurrencyTypes.VMChainName, + networkName: ChainTypes.VMChain, version = this.lastVersion, ): DeploymentInformation { const versionInfo = this.info[version]; @@ -167,7 +164,7 @@ export class ContractArtifact { * @returns The address and the number of the creation block, or null if not found */ getOptionalDeploymentInformation( - networkName: CurrencyTypes.VMChainName, + networkName: ChainTypes.VMChain, version = this.lastVersion, ): DeploymentInformation | null { return this.info[version]?.deployment[networkName] || null; diff --git a/packages/smart-contracts/test/lib/artifact.test.ts b/packages/smart-contracts/test/lib/artifact.test.ts index dd98e3475e..e16e7fcd40 100644 --- a/packages/smart-contracts/test/lib/artifact.test.ts +++ b/packages/smart-contracts/test/lib/artifact.test.ts @@ -57,7 +57,7 @@ describe('Artifact', () => { it('throws for a non-existing network', () => { expect(() => - erc20ProxyArtifact.getDeploymentInformation('fakenetwork' as CurrencyTypes.EvmChainName), + erc20ProxyArtifact.getDeploymentInformation('fakenetwork' as ChainTypes.IEvmChain), ).toThrowError(`No deployment for network: fakenetwork`); }); diff --git a/packages/toolbox/src/chainlinkConversionPathTools.ts b/packages/toolbox/src/chainlinkConversionPathTools.ts index 6d165abaff..e23e09e475 100644 --- a/packages/toolbox/src/chainlinkConversionPathTools.ts +++ b/packages/toolbox/src/chainlinkConversionPathTools.ts @@ -36,7 +36,7 @@ class ChainlinkConversionPathTools { * @param network The Ethereum network to use */ constructor( - private network: CurrencyTypes.EvmChainName, + private network: ChainTypes.IEvmChain, options?: { web3Url?: string; lastBlock?: number; maxRange?: number }, ) { const web3Url = @@ -139,7 +139,7 @@ const getCurrency = (symbol: string) => { }; export const listAggregators = async (options?: IOptions): Promise => { - let networks: CurrencyTypes.EvmChainName[] = ['private', 'rinkeby', 'mainnet']; + let networks: ChainTypes.IEvmChain[] = ['private', 'rinkeby', 'mainnet']; if (options?.network) { EvmChains.assertChainSupported(options.network); networks = [options.network]; diff --git a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts index 917b1957d4..23ba43ed84 100644 --- a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts +++ b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts @@ -13,9 +13,7 @@ export type Aggregator = { aggregator: string; }; -const feedMap: Partial< - Record -> = { +const feedMap: Partial> = { mainnet: ['mainnet', 'Ethereum Mainnet'], goerli: ['goerli', 'Goerli Testnet'], sepolia: ['sepolia', 'Sepolia Testnet'], @@ -29,7 +27,7 @@ const feedMap: Partial< moonbeam: ['polkadot-mainnet-moonbeam', 'Moonbeam Mainnet'], }; -export const getAllAggregators = async (network: CurrencyTypes.EvmChainName): Promise => { +export const getAllAggregators = async (network: ChainTypes.IEvmChain): Promise => { const [feedName, networkName] = feedMap[network] || []; if (!feedName || !networkName) { throw new Error( @@ -49,7 +47,7 @@ export const getAllAggregators = async (network: CurrencyTypes.EvmChainName): Pr }; export const getAvailableAggregators = async ( - network: CurrencyTypes.EvmChainName, + network: ChainTypes.IEvmChain, cm: CurrencyManager, pairs?: string[], listAll?: boolean, diff --git a/packages/types/src/advanced-logic-types.ts b/packages/types/src/advanced-logic-types.ts index 7861176483..95d09f5d22 100644 --- a/packages/types/src/advanced-logic-types.ts +++ b/packages/types/src/advanced-logic-types.ts @@ -1,7 +1,6 @@ import * as Extension from './extension-types'; import * as Identity from './identity-types'; import * as RequestLogic from './request-logic-types'; -import { ChainName } from './currency-types'; /** Advanced Logic extensions */ export interface IAdvancedLogicExtensions { @@ -33,13 +32,13 @@ export interface IAdvancedLogic { timestamp: number, ) => RequestLogic.IExtensionStates; getNativeTokenExtensionForNetwork: ( - network: ChainName, + network: string, ) => Extension.IExtension | undefined; getAnyToNativeTokenExtensionForNetwork: ( - network: ChainName, + network: string, ) => Extension.IExtension | undefined; getFeeProxyContractErc20ForNetwork: ( - network?: ChainName, + network?: string, ) => Extension.PnFeeReferenceBased.IFeeReferenceBased | undefined; extensions: IAdvancedLogicExtensions; } diff --git a/packages/types/src/chain-types.ts b/packages/types/src/chain-types.ts new file mode 100644 index 0000000000..3b3f73cc63 --- /dev/null +++ b/packages/types/src/chain-types.ts @@ -0,0 +1,85 @@ +import { RequestLogicTypes } from './index'; + +interface IChainCommon { + id: string; + name: string; + testnet: boolean; + ecosystem: ChainEcosystem; +} + +export interface IBtcChain extends IChainCommon { + ecosystem: 'btc'; + currenciesType: RequestLogicTypes.CURRENCY.BTC; +} + +export interface IDeclarativeChain extends IChainCommon { + ecosystem: 'declarative'; + currenciesType: RequestLogicTypes.CURRENCY.ETH; +} + +export interface IEvmChain extends IChainCommon { + ecosystem: 'evm'; + currenciesType: RequestLogicTypes.CURRENCY.ETH; +} + +export interface INearChain extends IChainCommon { + ecosystem: 'near'; + currenciesType: RequestLogicTypes.CURRENCY.ETH; +} + +/** + * List of ecosystems supported by the Request Network protocol + */ +export type ChainTypeByEcosystem = { + btc: IBtcChain; + declarative: IDeclarativeChain; + evm: IEvmChain; + near: INearChain; +}; +export type ChainEcosystem = keyof ChainTypeByEcosystem; +export type IChain = ChainTypeByEcosystem[ChainEcosystem]; + +/** + * VmChains are Virtual Machine chains supported by TheGraph + */ +export type IVmChain = IEvmChain | INearChain; + +// export interface IChainManager { +// chains: IChain[]; +// +// /** +// * Gets the name of a chain +// */ +// getName(chain: string | IChain): string; +// +// /** +// * Gets a supported chain from its name +// */ +// fromName( +// chainName: string, +// ecosystemsFilter?: T, +// ): ChainTypeByEcosystem[T[number]]; +// +// /** +// * Gets a supported chain from its ID +// */ +// fromId( +// chainId: string, +// ecosystemsFilter?: T, +// ): ChainTypeByEcosystem[T[number]]; +// +// /** +// * Get default chain manager +// */ +// getDefault(): IChainManager; +// +// /** +// * Returns true if both chains are equal or aliases. +// * The third argument "chainsEcosystem" is only needed when comparing chains as strings. +// */ +// isSameChain( +// chain1: string | IChain, +// chain2: string | IChain, +// chainsEcosystem?: ChainEcosystem[], +// ): boolean; +// } diff --git a/packages/types/src/currency-types.ts b/packages/types/src/currency-types.ts deleted file mode 100644 index 5f06b0862e..0000000000 --- a/packages/types/src/currency-types.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * List of supported EVM chains - */ -export type EvmChainName = - | 'alfajores' - | 'arbitrum-one' - | 'arbitrum-rinkeby' - | 'avalanche' - | 'bsc' - | 'bsctest' - | 'celo' - | 'core' - | 'fantom' - | 'fuse' - | 'goerli' - | 'mainnet' - | 'mantle' - | 'mantle-testnet' - | 'matic' - | 'moonbeam' - | 'mumbai' - | 'optimism' - | 'private' - | 'rinkeby' // FIXME: Rinkeby is deprecated - | 'sepolia' - | 'ronin' - | 'sokol' - | 'tombchain' - | 'xdai' - | 'zksynceratestnet' - | 'zksyncera'; - -/** - * List of supported BTC chains - */ -export type BtcChainName = 'mainnet' | 'testnet'; - -/** - * List of supported Declarative chains - */ -export type DeclarativeChainName = 'tron' | 'solana'; - -/** - * List of supported NEAR chains - * FIXME: get rid of the wrong 'aurora' alias - */ -export type NearChainName = 'aurora' | 'aurora-testnet' | 'near' | 'near-testnet'; - -export type ChainName = EvmChainName | BtcChainName | NearChainName | DeclarativeChainName; - -/** - * Virtual machin chains, where payment proxy contracts can be deployed - */ -export type VMChainName = EvmChainName | NearChainName; diff --git a/packages/types/src/extensions/pn-any-reference-based-types.ts b/packages/types/src/extensions/pn-any-reference-based-types.ts index b9861a38d3..a45bae072d 100644 --- a/packages/types/src/extensions/pn-any-reference-based-types.ts +++ b/packages/types/src/extensions/pn-any-reference-based-types.ts @@ -1,5 +1,4 @@ import { PnAddressBased } from '../extension-types'; -import { ChainName } from '../currency-types'; export { ACTION, IAddPaymentAddressParameters, @@ -18,5 +17,5 @@ export interface IValues extends PnAddressBased.IValues { /** Parameters of creation action */ export interface ICreationParameters extends PnAddressBased.ICreationParameters { salt?: string; - paymentNetworkName?: ChainName; + paymentNetworkName?: string; } diff --git a/packages/types/src/extensions/pn-any-to-any-conversion-types.ts b/packages/types/src/extensions/pn-any-to-any-conversion-types.ts index 93460d3f7d..b2fd13e4ec 100644 --- a/packages/types/src/extensions/pn-any-to-any-conversion-types.ts +++ b/packages/types/src/extensions/pn-any-to-any-conversion-types.ts @@ -1,5 +1,5 @@ import { PnFeeReferenceBased } from '../extension-types'; -import { ChainName } from '../currency-types'; +import { IChain } from '../chain-types'; export { IAddPaymentAddressParameters, IAddRefundAddressParameters, @@ -13,5 +13,5 @@ export type IConversionReferenceBased /** Parameters for the creation action */ export interface ICreationParameters extends PnFeeReferenceBased.ICreationParameters { maxRateTimespan?: number; - network?: ChainName; + network?: IChain; } diff --git a/packages/types/src/extensions/pn-any-to-erc20-types.ts b/packages/types/src/extensions/pn-any-to-erc20-types.ts index 143c8619dc..daf88bd5d5 100644 --- a/packages/types/src/extensions/pn-any-to-erc20-types.ts +++ b/packages/types/src/extensions/pn-any-to-erc20-types.ts @@ -1,12 +1,12 @@ import * as PnAnyToAnyConversion from './pn-any-to-any-conversion-types'; -import { EvmChainName } from '../currency-types'; +import { IEvmChain } from '../chain-types'; /** Any to ERC20 reference-based payment network extension interface */ export type IAnyToERC20 = PnAnyToAnyConversion.IConversionReferenceBased; /** Parameters for the creation action */ export interface ICreationParameters extends PnAnyToAnyConversion.ICreationParameters { - network?: EvmChainName; + network?: IEvmChain; // FIXME: should be mandatory according to AnyToErc20ProxyPaymentNetwork createCreationAction() logic acceptedTokens?: string[]; } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 1554830bf0..7129b4b490 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,6 +1,6 @@ import * as AdvancedLogicTypes from './advanced-logic-types'; import * as ClientTypes from './client-types'; -import * as CurrencyTypes from './currency-types'; +import * as ChainTypes from './chain-types'; import * as DataAccessTypes from './data-access-types'; import * as DecryptionProviderTypes from './decryption-provider-types'; import * as EncryptionTypes from './encryption-types'; @@ -20,7 +20,7 @@ import * as FeeTypes from './fees-types'; export { AdvancedLogicTypes, ClientTypes, - CurrencyTypes, + ChainTypes, DataAccessTypes, DecryptionProviderTypes, EncryptionTypes, diff --git a/packages/types/src/payment-types.ts b/packages/types/src/payment-types.ts index 8f9f08e151..d9f44c4ea3 100644 --- a/packages/types/src/payment-types.ts +++ b/packages/types/src/payment-types.ts @@ -3,7 +3,7 @@ import * as RequestLogic from './request-logic-types'; import * as ExtensionTypes from './extension-types'; import { ICreationParameters } from './extensions/pn-any-declarative-types'; import { ICreationParameters as ICreationParametersAnyToAny } from './extensions/pn-any-to-any-conversion-types'; -import { EvmChainName } from './currency-types'; +import { IEvmChain } from './chain-types'; /** Interface for payment network extensions state and interpretation */ export interface IPaymentNetwork< @@ -37,7 +37,7 @@ export interface IFeeReferenceBasedCreationParameters extends IReferenceBasedCre /** Parameters to create a request with "any to erc20" payment network */ export interface IAnyToErc20CreationParameters extends ICreationParametersAnyToAny { acceptedTokens?: string[]; - network?: EvmChainName; + network?: IEvmChain; } /** diff --git a/packages/types/src/request-logic-types.ts b/packages/types/src/request-logic-types.ts index 3aea78052b..10cfb0577b 100644 --- a/packages/types/src/request-logic-types.ts +++ b/packages/types/src/request-logic-types.ts @@ -5,7 +5,6 @@ import * as Extension from './extension-types'; import * as Identity from './identity-types'; import * as Signature from './signature-types'; import * as Transaction from './transaction-types'; -import { CurrencyTypes } from './index'; /** Request Logic layer */ export interface IRequestLogic { @@ -267,7 +266,7 @@ export interface ICurrency { /** The currency value (e.g.: '0x123...789', 'EUR', 'ETH') */ value: string; /** The currency network (e.g.: 'mainnet', 'rinkeby', 'bank_sandbox') */ - network?: CurrencyTypes.ChainName; + network?: string; } /** Enum of name possible in a action */ From 4a7dad8ea627fe5e9b4065e054f39d9516420a1f Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Fri, 9 Feb 2024 19:48:54 +0100 Subject: [PATCH 02/14] fixed advanced logic and smart contracts --- packages/advanced-logic/src/advanced-logic.ts | 40 +++++++++++-------- .../payment-network/address-based.ts | 31 +++++++++++--- .../payment-network/any-to-erc20-proxy.ts | 4 +- .../payment-network/any-to-native.ts | 16 ++++---- .../erc20/fee-proxy-contract.ts | 4 +- .../payment-network/native-token.ts | 18 ++++----- .../near/any-to-near-testnet.ts | 8 +++- .../payment-network/near/any-to-near.ts | 16 ++++---- .../payment-network/near/near-native.ts | 16 ++++---- .../near/near-testnet-native.ts | 8 +++- packages/chain/src/chain-manager.ts | 18 +++++---- packages/chain/src/chains/btc/btc-chain.ts | 2 +- packages/chain/src/chains/chain-abstract.ts | 13 +++++- .../chains/declarative/declarative-chain.ts | 2 +- .../chain/src/chains/ecosystem-abstract.ts | 25 ++---------- packages/chain/src/chains/evm/evm-chain.ts | 2 +- packages/chain/src/chains/near/near-chain.ts | 2 +- .../src/erc20/fee-proxy-contract.ts | 25 +++++------- .../src/erc20/proxy-info-retriever.ts | 4 +- .../near-conversion-info-retriever.ts | 2 +- .../near/retrievers/near-info-retriever.ts | 12 ++---- .../src/payment-network-factory.ts | 2 +- .../payment-detection/src/thegraph/client.ts | 32 +++++++++------ packages/payment-detection/src/types.ts | 4 +- packages/payment-detection/src/utils.ts | 2 +- .../test/erc20/fee-proxy-contract.test.ts | 2 +- .../payment-processor/src/payment/index.ts | 16 ++++++-- .../deploy/deploy-zk-batch-contracts.ts | 5 +-- .../scripts-create2/compute-one-address.ts | 2 - .../scripts-create2/constructor-args.ts | 3 +- .../contract-setup/adminTasks.ts | 8 ++-- .../contract-setup/execute-contract-method.ts | 3 +- .../setupBatchConversionPayments.ts | 7 ++-- .../setupChainlinkConversionPath.ts | 3 +- .../setupERC20SwapToConversion.ts | 2 - .../contract-setup/setupERC20SwapToPay.ts | 2 - .../contract-setup/setupETHConversionProxy.ts | 3 +- .../setupErc20ConversionProxy.ts | 2 - .../contract-setup/update-owner.ts | 2 - .../contract-setup/update-whitelisted-role.ts | 2 - .../smart-contracts/scripts-create2/deploy.ts | 2 - .../scripts-create2/tenderly.ts | 18 +++++---- .../scripts-create2/transfer-ownership.ts | 3 -- .../smart-contracts/scripts-create2/utils.ts | 2 - .../smart-contracts/scripts-create2/verify.ts | 2 - .../smart-contracts/scripts/deploy-one.ts | 3 -- ...test-deploy-batch-conversion-deployment.ts | 3 +- .../test-deploy-batch-erc-eth-deployment.ts | 2 - .../src/lib/ContractArtifact.ts | 34 +++++++--------- .../contracts/BatchConversionPayments.test.ts | 4 +- .../BatchNoConversionErc20Payments.test.ts | 3 +- .../BatchNoConversionEthPayments.test.ts | 3 +- .../contracts/ChainlinkConversionPath.test.ts | 3 +- .../contracts/ERC20SwapToConversion.test.ts | 3 +- .../test/contracts/ERC20SwapToPay.test.ts | 2 - .../contracts/Erc20ConversionProxy.test.ts | 3 +- .../test/contracts/EthConversionProxy.test.ts | 3 +- .../test/contracts/EthereumFeeProxy.test.ts | 2 - .../test/contracts/EthereumProxy.test.ts | 2 - .../smart-contracts/test/lib/artifact.test.ts | 1 - packages/types/src/advanced-logic-types.ts | 7 ++-- packages/types/src/chain-types.ts | 12 +++--- packages/utils/src/providers.ts | 9 +++-- 63 files changed, 245 insertions(+), 251 deletions(-) diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index 4f3bf88bc1..2b49c128f5 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -1,11 +1,11 @@ import { AdvancedLogicTypes, - CurrencyTypes, + ChainTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, } from '@requestnetwork/types'; -import { ICurrencyManager, NearChains, isSameChain } from '@requestnetwork/currency'; +import { ICurrencyManager } from '@requestnetwork/currency'; import ContentData from './extensions/content-data'; import AddressBasedBtc from './extensions/payment-network/bitcoin/mainnet-address-based'; @@ -108,7 +108,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic requestState: RequestLogicTypes.IRequest, ): ExtensionTypes.IExtension { const id: ExtensionTypes.ID = extensionAction.id; - const network = this.getNetwork(extensionAction, requestState) || requestState.currency.network; + const chain = this.getChain(extensionAction, requestState); const extension: ExtensionTypes.IExtension | undefined = { [ExtensionTypes.ID.CONTENT_DATA]: this.extensions.contentData, [ExtensionTypes.PAYMENT_NETWORK_ID.BITCOIN_ADDRESS_BASED]: this.extensions.addressBasedBtc, @@ -118,17 +118,17 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_ADDRESS_BASED]: this.extensions.addressBasedErc20, [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_PROXY_CONTRACT]: this.extensions.proxyContractErc20, [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT]: - this.getFeeProxyContractErc20ForNetwork(network), + this.getFeeProxyContractErc20ForNetwork(chain), [ExtensionTypes.PAYMENT_NETWORK_ID.ERC777_STREAM]: this.extensions.erc777Stream, [ExtensionTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA]: this.extensions.ethereumInputData, [ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN]: - this.getNativeTokenExtensionForNetwork(network), + this.getNativeTokenExtensionForNetwork(chain), [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY]: this.extensions.anyToErc20Proxy, [ExtensionTypes.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT]: this.extensions.feeProxyContractEth, [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY]: this.extensions.anyToEthProxy, [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN]: - this.getAnyToNativeTokenExtensionForNetwork(network), + this.getAnyToNativeTokenExtensionForNetwork(chain), [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE]: this.extensions.erc20TransferableReceivable, }[id]; @@ -138,7 +138,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic id === ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN || id === ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN ) { - throw Error(`extension with id: ${id} not found for network: ${network}`); + throw Error(`extension with id: ${id} not found for network: ${chain}`); } throw Error(`extension not recognized, id: ${id}`); @@ -166,30 +166,38 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic : undefined; } - public getFeeProxyContractErc20ForNetwork(network?: string): FeeProxyContractErc20 { - return NearChains.isChainSupported(network) + public getFeeProxyContractErc20ForNetwork(network?: ChainTypes.IChain): FeeProxyContractErc20 { + return this.currencyManager.chainManager.ecosystems.near.isChainSupported(network) ? new FeeProxyContractErc20(this.currencyManager, undefined, undefined, network) : this.extensions.feeProxyContractErc20; } - protected getNetwork( + private getChain( extensionAction: ExtensionTypes.IAction, requestState: RequestLogicTypes.IRequest, ): ChainTypes.IChain | undefined { if ( requestState.currency.network && + requestState.currency.type && extensionAction.parameters.paymentNetworkName && - !isSameChain(requestState.currency.network, extensionAction.parameters.paymentNetworkName) + !this.currencyManager.chainManager.isSameChain( + requestState.currency.network, + extensionAction.parameters.paymentNetworkName, + this.currencyManager.chainManager.getEcosystemsByCurrencyType(requestState.currency.type), + ) ) { throw new Error( - `Cannot apply action for network ${extensionAction.parameters.paymentNetworkName} on state with payment network: ${requestState.currency.network}`, + `Cannot apply action for extension ${extensionAction.parameters.paymentNetworkName} on state with chain: ${requestState.currency.network}`, ); } - const network = - extensionAction.action === 'create' + + const chainName = + (extensionAction.action === 'create' ? extensionAction.parameters.network : requestState.extensions[ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN]?.values - ?.network; - return network; + ?.network) || requestState.currency.network; + + if (!chainName) return; + return this.currencyManager.chainManager.fromName(chainName); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/address-based.ts b/packages/advanced-logic/src/extensions/payment-network/address-based.ts index 407f3cd42b..9441ea18dd 100644 --- a/packages/advanced-logic/src/extensions/payment-network/address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/address-based.ts @@ -280,10 +280,21 @@ export default abstract class AddressBasedPaymentNetwork< this.throwIfInvalidNetwork(request.currency.network); } - protected throwIfInvalidNetwork(network?: string): asserts network is string { - if (!network) { + protected throwIfInvalidNetwork(chain?: string | ChainTypes.IChain): ChainTypes.IChain { + if (!chain) { throw Error('network is required'); } + const supportedEcosystems = this.currencyManager.chainManager.getEcosystemsByCurrencyType( + this.supportedCurrencyType, + ); + if (typeof chain === 'string') { + // throws if network not found + return this.currencyManager.chainManager.fromName(chain, supportedEcosystems); + } + if (!supportedEcosystems.includes(chain.ecosystem)) { + throw Error(`Payment network ${this.constructor.name} does not support chain ${chain.name}`); + } + return chain; } } @@ -295,12 +306,20 @@ export class InvalidPaymentAddressError extends Error { } export class UnsupportedNetworkError extends Error { - constructor(unsupportedNetworkName: string, supportedNetworks?: string[]) { - const supportedNetworkDetails = supportedNetworks - ? ` (only ${supportedNetworks.join(', ')})` + constructor( + extension: string, + unsupportedChain: string | ChainTypes.IChain, + supportedChains?: string[] | ChainTypes.IChain[], + ) { + const unsupportedChainName = + typeof unsupportedChain === 'string' ? unsupportedChain : unsupportedChain.name; + const supportedNetworkDetails = supportedChains + ? ` (only "${supportedChains + .map((chain) => (typeof chain === 'string' ? chain : chain.name)) + .join(', ')}")` : ''; super( - `Payment network '${unsupportedNetworkName}' is not supported by this extension${supportedNetworkDetails}`, + `The extension "${extension}" does not support the chain "${unsupportedChainName}"${supportedNetworkDetails}`, ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts b/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts index 00aa3d2ace..7111aca317 100644 --- a/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts +++ b/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts @@ -42,10 +42,10 @@ export default class AnyToErc20ProxyPaymentNetwork extends Erc20FeeProxyPaymentN if (!acceptedCurrency) { throw new UnsupportedCurrencyError({ value: address, - network, + network: network?.name, }); } - if (!this.currencyManager.supportsConversion(acceptedCurrency, network)) { + if (!network || !this.currencyManager.supportsConversion(acceptedCurrency, network)) { throw Error( `acceptedTokens must contain only supported token addresses (ERC20 only). ${address} is not supported for ${network}.`, ); diff --git a/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts b/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts index 48ae797f20..188180d2d8 100644 --- a/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/any-to-native.ts @@ -1,5 +1,5 @@ import { FeeReferenceBasedPaymentNetwork } from './fee-reference-based'; -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-based'; import { ICurrencyManager } from '@requestnetwork/currency'; @@ -46,13 +46,15 @@ export default abstract class AnyToNativeTokenPaymentNetwork extends FeeReferenc ); } - protected throwIfInvalidNetwork( - network?: ChainTypes.IChain, - ): asserts network is ChainTypes.IChain { - super.throwIfInvalidNetwork(network); - if (this.supportedNetworks && !this.supportedNetworks.includes(network)) { - throw new UnsupportedNetworkError(network, this.supportedNetworks); + protected throwIfInvalidNetwork(chain?: string | ChainTypes.IChain): ChainTypes.IChain { + const _chain = super.throwIfInvalidNetwork(chain); + if ( + this.supportedNetworks && + !this.supportedNetworks.some((supportedChain) => supportedChain.eq(_chain)) + ) { + throw new UnsupportedNetworkError(this.constructor.name, _chain.name, this.supportedNetworks); } + return _chain; } } diff --git a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts index 33222c778f..c93211cbaf 100644 --- a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts +++ b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts @@ -58,7 +58,9 @@ export default class Erc20FeeProxyPaymentNetwork< 'near', ]) ) { - throw new UnsupportedNetworkError(request.currency.network, [this.network.name]); + throw new UnsupportedNetworkError(this.constructor.name, request.currency.network, [ + this.network.name, + ]); } super.validate(request, extensionAction); } diff --git a/packages/advanced-logic/src/extensions/payment-network/native-token.ts b/packages/advanced-logic/src/extensions/payment-network/native-token.ts index e4b7acd48b..3ecc8685ac 100644 --- a/packages/advanced-logic/src/extensions/payment-network/native-token.ts +++ b/packages/advanced-logic/src/extensions/payment-network/native-token.ts @@ -3,6 +3,7 @@ import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-b import ReferenceBasedPaymentNetwork from './reference-based'; import { ICurrencyManager } from '@requestnetwork/currency'; +import * as chai from 'chai'; /** * Implementation of the payment network to pay in ETH based on input data. @@ -52,15 +53,14 @@ export default abstract class NativeTokenPaymentNetwork extends ReferenceBasedPa ); } - protected throwIfInvalidNetwork( - network?: ChainTypes.IChain, - ): asserts network is ChainTypes.IChain { - super.throwIfInvalidNetwork(network?.name); - if (this.supportedNetworks && !this.supportedNetworks.includes(network)) { - throw new UnsupportedNetworkError( - network?.name, - this.supportedNetworks.map((n) => n.name), - ); + protected throwIfInvalidNetwork(chain?: string | ChainTypes.IChain): ChainTypes.IChain { + const _chain = super.throwIfInvalidNetwork(chain); + if ( + this.supportedNetworks && + !this.supportedNetworks.some((supportedChain) => supportedChain.eq(_chain)) + ) { + throw new UnsupportedNetworkError(this.constructor.name, _chain, this.supportedNetworks); } + return _chain; } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts index 0c848ea398..791eb89589 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts @@ -4,7 +4,7 @@ import AnyToNearPaymentNetwork from './any-to-near'; export default class AnyToNearTestnetPaymentNetwork extends AnyToNearPaymentNetwork { public constructor(currencyManager: ICurrencyManager) { // testnet PN version is the same as mainnet, can be overridden here if needed - super(currencyManager, ['aurora-testnet', 'near-testnet']); + super(currencyManager, [currencyManager.chainManager.fromName('aurora-testnet', ['near'])]); } /** @@ -14,6 +14,10 @@ export default class AnyToNearTestnetPaymentNetwork extends AnyToNearPaymentNetw * @returns {boolean} true if address is valid */ protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR-testnet', 'aurora-testnet'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR-testnet', + this.currencyManager.chainManager.fromName('aurora-testnet', ['near']), + ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts index db97871f6a..d195a185ad 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts @@ -1,6 +1,6 @@ import { ICurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { - CurrencyTypes, + ChainTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -12,18 +12,14 @@ const CURRENT_VERSION = '0.1.0'; export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetwork { public constructor( currencyManager: ICurrencyManager, - supportedNetworks: ChainTypes.INearChain[] = [ - 'aurora', - // FIXME: enable near network support - // 'near' - ], + supportedNetworks?: ChainTypes.INearChain[], currentVersion: string = CURRENT_VERSION, ) { super( currencyManager, ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN, currentVersion, - supportedNetworks, + supportedNetworks ?? [currencyManager.chainManager.fromName('aurora', ['near'])], ); } @@ -34,7 +30,11 @@ export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetw * @returns {boolean} true if address is valid */ protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR', 'aurora'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR', + this.currencyManager.chainManager.fromName('aurora', ['near']), + ); } /** diff --git a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts index 0ff41fc0fe..d740899fd9 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, ExtensionTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes } from '@requestnetwork/types'; import NativeTokenPaymentNetwork from '../native-token'; import { ICurrencyManager } from '@requestnetwork/currency'; @@ -10,18 +10,14 @@ const CURRENT_VERSION = '0.2.0'; export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork { public constructor( currencyManager: ICurrencyManager, - supportedNetworks: ChainTypes.INearChain[] = [ - 'aurora', - // FIXME: enable near network support - // 'near' - ], + supportedNetworks?: ChainTypes.INearChain[], currentVersion: string = CURRENT_VERSION, ) { super( currencyManager, ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN, currentVersion, - supportedNetworks, + supportedNetworks ?? [currencyManager.chainManager.fromName('aurora', ['near'])], ); } @@ -32,6 +28,10 @@ export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork * @returns {boolean} true if address is valid */ protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR', 'aurora'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR', + this.currencyManager.chainManager.fromName('aurora', ['near']), + ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts b/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts index af114b2753..8dd7bce066 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts @@ -7,7 +7,7 @@ import { ICurrencyManager } from '@requestnetwork/currency'; export default class NearTestnetNativeNativePaymentNetwork extends NearNativePaymentNetwork { public constructor(currencyManager: ICurrencyManager) { // testnet PN version is the same as mainnet, can be overridden here if needed - super(currencyManager, ['aurora-testnet', 'near-testnet']); + super(currencyManager, [currencyManager.chainManager.fromName('aurora-testnet', ['near'])]); } /** @@ -17,6 +17,10 @@ export default class NearTestnetNativeNativePaymentNetwork extends NearNativePay * @returns {boolean} true if address is valid */ protected isValidAddress(address: string): boolean { - return this.isValidAddressForSymbolAndNetwork(address, 'NEAR-testnet', 'aurora-testnet'); + return this.isValidAddressForSymbolAndNetwork( + address, + 'NEAR-testnet', + this.currencyManager.chainManager.fromName('aurora-testnet', ['near']), + ); } } diff --git a/packages/chain/src/chain-manager.ts b/packages/chain/src/chain-manager.ts index 06e12eb8f7..66b5e59055 100644 --- a/packages/chain/src/chain-manager.ts +++ b/packages/chain/src/chain-manager.ts @@ -5,7 +5,7 @@ import DeclarativeEcosystem from './chains/declarative/declarative-ecosystem'; import EvmEcosystem from './chains/evm/evm-ecosystem'; import NearEcosystem from './chains/near/near-ecosystem'; import { initializeChains } from './chains/utils'; -import { ChainTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class ChainManager { private static defaultInstance: ChainManager; @@ -39,6 +39,14 @@ export class ChainManager { }, [] as ChainTypes.IChain[]); } + getEcosystemsByCurrencyType( + currencyType: RequestLogicTypes.CURRENCY, + ): ChainTypes.ChainEcosystem[] { + return (Object.keys(this.ecosystems) as ChainTypes.ChainEcosystem[]).filter((ecosystemName) => + this.ecosystems[ecosystemName].currencyType.includes(currencyType), + ); + } + static getName(chain: string | ChainTypes.IChain): string { if (typeof chain === 'string') return chain.toLowerCase(); return chain.name; @@ -112,12 +120,6 @@ export class ChainManager { typeof chain1 === 'string' ? this.fromName(chain1, chainsEcosystem) : chain1; const chain2Object = typeof chain2 === 'string' ? this.fromName(chain2, chainsEcosystem) : chain2; - return ( - chain1Object === chain2Object || - this.ecosystems[chain1Object.ecosystem].isSameChainFromString( - chain1Object.name, - chain2Object.name, - ) - ); + return chain1Object.eq(chain2Object); }; } diff --git a/packages/chain/src/chains/btc/btc-chain.ts b/packages/chain/src/chains/btc/btc-chain.ts index cc9be4e65a..b54c4778d4 100644 --- a/packages/chain/src/chains/btc/btc-chain.ts +++ b/packages/chain/src/chains/btc/btc-chain.ts @@ -3,5 +3,5 @@ import { RequestLogicTypes } from '@requestnetwork/types'; export class BtcChain extends ChainAbstract { public readonly ecosystem = 'btc'; - public readonly currenciesType = RequestLogicTypes.CURRENCY.BTC; + public readonly currencyType = RequestLogicTypes.CURRENCY.BTC; } diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts index 98933cd53b..dbbba8aad5 100644 --- a/packages/chain/src/chains/chain-abstract.ts +++ b/packages/chain/src/chains/chain-abstract.ts @@ -1,7 +1,18 @@ -export abstract class ChainAbstract { +import { ChainTypes } from '@requestnetwork/types'; +import { IChainCommon } from '@requestnetwork/types/src/chain-types'; +import { RequestLogicTypes } from '@requestnetwork/types/src'; + +export abstract class ChainAbstract implements ChainTypes.IChainCommon { + public declare readonly ecosystem: ChainTypes.ChainEcosystem; + public declare readonly currencyType: RequestLogicTypes.CURRENCY; + constructor( public readonly id: string, public readonly name: string, public readonly testnet: boolean = false, ) {} + + public eq(chain: ChainTypes.IChain): boolean { + return this === chain || (this.ecosystem === chain.ecosystem && this.id === chain.id); + } } diff --git a/packages/chain/src/chains/declarative/declarative-chain.ts b/packages/chain/src/chains/declarative/declarative-chain.ts index d4b6b9b7e6..be34b05ccf 100644 --- a/packages/chain/src/chains/declarative/declarative-chain.ts +++ b/packages/chain/src/chains/declarative/declarative-chain.ts @@ -3,5 +3,5 @@ import { ChainAbstract } from '../chain-abstract'; export class DeclarativeChain extends ChainAbstract implements ChainTypes.IDeclarativeChain { public readonly ecosystem = 'declarative'; - public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; + public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/ecosystem-abstract.ts b/packages/chain/src/chains/ecosystem-abstract.ts index 304260661d..7129c52886 100644 --- a/packages/chain/src/chains/ecosystem-abstract.ts +++ b/packages/chain/src/chains/ecosystem-abstract.ts @@ -59,27 +59,6 @@ export abstract class EcosystemAbstract { ); } - /** - * Retrieve the corresponding chain ID from Request Network's internal chain name representation - */ - public getChainId(chainName: string): string { - return this.chains[chainName].id; - } - - /** - * Returns true is the chain is a testnet chain - */ - public isTestnet(chainName: string): boolean { - return Boolean(this.chains[chainName].testnet); - } - - /** - * @returns true if both chains have the same ID or same name - */ - private isSameChain = (chain1: string, chain2: string): boolean => { - return chain1 === chain2 || this.getChainId(chain1) === this.getChainId(chain2); - }; - /** * @returns true if both chains have the same ID or same name */ @@ -90,6 +69,8 @@ export abstract class EcosystemAbstract { } catch { return false; } - return this.isSameChain(chain1, chain2); + const chain1Object = this.chains[chain1]; + const chain2Object = this.chains[chain2]; + return chain1Object.eq(chain2Object); }; } diff --git a/packages/chain/src/chains/evm/evm-chain.ts b/packages/chain/src/chains/evm/evm-chain.ts index 99cb8af77a..7a45f5e190 100644 --- a/packages/chain/src/chains/evm/evm-chain.ts +++ b/packages/chain/src/chains/evm/evm-chain.ts @@ -3,5 +3,5 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class EvmChain extends ChainAbstract implements ChainTypes.IEvmChain { public readonly ecosystem = 'evm'; - public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; + public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/near/near-chain.ts b/packages/chain/src/chains/near/near-chain.ts index 38160a456b..34a2bdf9b7 100644 --- a/packages/chain/src/chains/near/near-chain.ts +++ b/packages/chain/src/chains/near/near-chain.ts @@ -3,5 +3,5 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class NearChain extends ChainAbstract implements ChainTypes.INearChain { public readonly ecosystem = 'near'; - public readonly currenciesType = RequestLogicTypes.CURRENCY.ETH; + public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/payment-detection/src/erc20/fee-proxy-contract.ts b/packages/payment-detection/src/erc20/fee-proxy-contract.ts index 89a781ad6c..ffec1e5576 100644 --- a/packages/payment-detection/src/erc20/fee-proxy-contract.ts +++ b/packages/payment-detection/src/erc20/fee-proxy-contract.ts @@ -1,12 +1,6 @@ import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { - CurrencyDefinition, - EvmChains, - ICurrencyManager, - NearChains, - isSameChain, -} from '@requestnetwork/currency'; +import { CurrencyDefinition, ICurrencyManager } from '@requestnetwork/currency'; import ProxyInfoRetriever from './proxy-info-retriever'; import { loadCurrencyFromContract } from './currency'; @@ -76,7 +70,7 @@ export abstract class ERC20FeeProxyPaymentDetectorBase< * Handle payment networks with ERC20 fee proxy contract extension on EVM (default) or Near chains */ export class ERC20FeeProxyPaymentDetector< - TChain extends ChainTypes.VMChain = ChainTypes.IEvmChain, + TChain extends ChainTypes.IVmChain = ChainTypes.IEvmChain, > extends ERC20FeeProxyPaymentDetectorBase< ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, PaymentTypes.IERC20FeePaymentEventParameters @@ -113,7 +107,7 @@ export class ERC20FeeProxyPaymentDetector< paymentChain: TChain, paymentNetwork: ExtensionTypes.IState, ): Promise> { - if (this.network && !isSameChain(paymentChain, this.network)) { + if (this.network && paymentChain.eq(this.network)) { throw new NetworkNotSupported( `Unsupported network '${paymentChain}' for payment detector instanciated with '${this.network}'`, ); @@ -139,7 +133,7 @@ export class ERC20FeeProxyPaymentDetector< acceptedTokens: [requestCurrency.value], }); } else { - if (!EvmChains.isChainSupported(paymentChain)) { + if (paymentChain.ecosystem !== 'evm') { throw new Error( `Could not get a TheGraph-based info retriever for chain ${paymentChain} and RPC-based info retrievers are only compatible with EVM chains.`, ); @@ -164,11 +158,12 @@ export class ERC20FeeProxyPaymentDetector< paymentChain: TChain, subgraphClient: TheGraphClient | TheGraphClient, ): TheGraphInfoRetriever | NearInfoRetriever { - const graphInfoRetriever = EvmChains.isChainSupported(paymentChain) - ? new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager) - : NearChains.isChainSupported(paymentChain) && this.network - ? new NearInfoRetriever(subgraphClient as TheGraphClient) - : undefined; + const graphInfoRetriever = + paymentChain.ecosystem === 'evm' + ? new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager) + : paymentChain.ecosystem === 'near' && this.network + ? new NearInfoRetriever(subgraphClient as TheGraphClient) + : undefined; if (!graphInfoRetriever) { throw new Error( `Could not find graphInfoRetriever for chain ${paymentChain} in payment detector`, diff --git a/packages/payment-detection/src/erc20/proxy-info-retriever.ts b/packages/payment-detection/src/erc20/proxy-info-retriever.ts index 8dcbf7466c..7baae06c78 100644 --- a/packages/payment-detection/src/erc20/proxy-info-retriever.ts +++ b/packages/payment-detection/src/erc20/proxy-info-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { IPaymentRetriever } from '../types'; import { BigNumber, ethers } from 'ethers'; import { parseLogArgs } from '../utils'; @@ -49,7 +49,7 @@ export default class ProxyERC20InfoRetriever private tokenContractAddress: string, private toAddress: string, private eventName: PaymentTypes.EVENTS_NAMES, - private network: string, + private network: ChainTypes.IVmChain, ) { // Creates a local or default provider this.provider = getDefaultProvider(this.network); diff --git a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts index 6ff5f7cd6a..dd83ba3169 100644 --- a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts @@ -13,7 +13,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: ChainTypes.VMChain; + paymentChain: ChainTypes.IVmChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The maximum span between the time the rate was fetched and the payment */ diff --git a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts index 9b79f012e5..10d73868de 100644 --- a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { TheGraphClient } from '../../thegraph'; import { GetNearPaymentsQuery } from 'payment-detection/src/thegraph/generated/graphql-near'; import { ITheGraphBaseInfoRetriever } from 'payment-detection/src/types'; @@ -16,7 +16,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: ChainTypes.VMChain; + paymentChain: ChainTypes.IVmChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The list of ERC20 tokens addresses accepted for payments and refunds. Set to `undefined` for payments in NEAR token. */ @@ -24,15 +24,9 @@ export type TransferEventsParams = { }; /** * Gets a list of transfer events for a set of Near payment details - * TheGraph-based etriever for ERC20 Fee Proxy and Native token payments. + * TheGraph-based retriever for ERC20 Fee Proxy and Native token payments. */ export class NearInfoRetriever implements ITheGraphBaseInfoRetriever { - /** - * @param paymentReference The reference to identify the payment - * @param toAddress Address to check - * @param eventName Indicate if it is an address for payment or refund - * - */ constructor(protected readonly client: TheGraphClient) {} public async getTransferEvents( diff --git a/packages/payment-detection/src/payment-network-factory.ts b/packages/payment-detection/src/payment-network-factory.ts index ebc4456cb9..326536a723 100644 --- a/packages/payment-detection/src/payment-network-factory.ts +++ b/packages/payment-detection/src/payment-network-factory.ts @@ -154,7 +154,7 @@ export class PaymentNetworkFactory { if (detector.extension && 'getDeploymentInformation' in detectorClass) { // this throws when the contract isn't deployed and was mandatory for payment detection (detectorClass as ContractBasedDetector).getDeploymentInformation( - network as ChainTypes.VMChain, + network as ChainTypes.IVmChain, paymentNetworkVersion || detector.extension.currentVersion, ); } diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index e94390a982..9b0428768d 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -1,10 +1,9 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { CurrencyTypes } from '@requestnetwork/types'; -import { NearChains } from '@requestnetwork/currency'; import { GraphQLClient } from 'graphql-request'; import { Block_Height, Maybe, getSdk } from './generated/graphql'; import { getSdk as getNearSdk } from './generated/graphql-near'; import { RequestConfig } from 'graphql-request/src/types'; +import { ChainTypes } from '@requestnetwork/types'; const HOSTED_THE_GRAPH_URL = 'https://api.thegraph.com/subgraphs/name/requestnetwork/request-payments-'; @@ -27,7 +26,7 @@ const THE_GRAPH_URL_STUDIO_ZKSYNC = * * @type TGraphClientVariant: null if no variant, 'near' if native token payments detection on Near */ -export type TheGraphClient = +export type TheGraphClient = (TChain extends ChainTypes.INearChain ? ReturnType : ReturnType) & { @@ -64,8 +63,12 @@ const extractClientOptions = ( return [clientOptions, queryOptions]; }; -export const getTheGraphClient = (network: string, url: string, options?: TheGraphClientOptions) => - NearChains.isChainSupported(network) +export const getTheGraphClient = ( + chain: ChainTypes.IChain, + url: string, + options?: TheGraphClientOptions, +) => + chain.ecosystem === 'near' ? getTheGraphNearClient(url, options) : getTheGraphEvmClient(url, options); @@ -86,18 +89,21 @@ export const getTheGraphNearClient = (url: string, options?: TheGraphClientOptio }; export const defaultGetTheGraphClient = ( - network: ChainTypes.IChain, + chain: ChainTypes.IChain, options?: TheGraphClientOptions, ) => { - return network === 'private' + return chain.name === 'private' ? undefined - : NearChains.isChainSupported(network) - ? getTheGraphNearClient(`${HOSTED_THE_GRAPH_URL}${network.replace('aurora', 'near')}`, options) - : network === 'mantle' + : chain.ecosystem === 'near' + ? getTheGraphNearClient( + `${HOSTED_THE_GRAPH_URL}${chain.name.replace('aurora', 'near')}`, + options, + ) + : chain.name === 'mantle' ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE, options) - : network === 'mantle-testnet' + : chain.name === 'mantle-testnet' ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE_TESTNET, options) - : network === 'zksyncera' + : chain.name === 'zksyncera' ? getTheGraphEvmClient(THE_GRAPH_URL_STUDIO_ZKSYNC, options) - : getTheGraphEvmClient(`${HOSTED_THE_GRAPH_URL}${network}`, options); + : getTheGraphEvmClient(`${HOSTED_THE_GRAPH_URL}${chain}`, options); }; diff --git a/packages/payment-detection/src/types.ts b/packages/payment-detection/src/types.ts index 484548cebc..fb6e0308be 100644 --- a/packages/payment-detection/src/types.ts +++ b/packages/payment-detection/src/types.ts @@ -25,7 +25,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: ChainTypes.VMChain; + paymentChain: ChainTypes.IVmChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The list of ERC20 tokens addresses accepted for payments and refunds OR undefined for native tokens (e.g. ETH) */ @@ -96,7 +96,7 @@ export interface ISupportedPaymentNetworkByCurrency< export type TGetSubGraphClient = ( network: ChainTypes.IChain, -) => TChain extends ChainTypes.VMChain ? TheGraphClient | undefined : undefined; +) => TChain extends ChainTypes.IVmChain ? TheGraphClient | undefined : undefined; export type PaymentNetworkOptions = { /** override default bitcoin detection provider */ diff --git a/packages/payment-detection/src/utils.ts b/packages/payment-detection/src/utils.ts index 4120b45753..7131539cc5 100644 --- a/packages/payment-detection/src/utils.ts +++ b/packages/payment-detection/src/utils.ts @@ -63,7 +63,7 @@ const getChainlinkPaddingSize = ({ export type DeploymentInformationWithVersion = DeploymentInformation & { contractVersion: string }; export type GetDeploymentInformation = ( - network: ChainTypes.VMChain, + network: ChainTypes.IVmChain, paymentNetworkVersion: string, ) => TAllowUndefined extends false ? DeploymentInformationWithVersion 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 d211d9af3f..1af1a5adb1 100644 --- a/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts +++ b/packages/payment-detection/test/erc20/fee-proxy-contract.test.ts @@ -10,7 +10,7 @@ import { CurrencyManager } from '@requestnetwork/currency'; import { ERC20FeeProxyPaymentDetector } from '../../src/erc20/fee-proxy-contract'; import { mockAdvancedLogicBase } from '../utils'; -let erc20FeeProxyContract: ERC20FeeProxyPaymentDetector; +let erc20FeeProxyContract: ERC20FeeProxyPaymentDetector; const createAddPaymentAddressAction = jest.fn(); const createAddRefundAddressAction = jest.fn(); diff --git a/packages/payment-processor/src/payment/index.ts b/packages/payment-processor/src/payment/index.ts index 342e2213de..b9472fc5d6 100644 --- a/packages/payment-processor/src/payment/index.ts +++ b/packages/payment-processor/src/payment/index.ts @@ -16,7 +16,7 @@ import { payAnyToErc20ProxyRequest } from './any-to-erc20-proxy'; import { payAnyToEthProxyRequest } from './any-to-eth-proxy'; import { WalletConnection } from 'near-api-js'; import { isNearAccountSolvent } from './utils-near'; -import { ICurrencyManager, NearChains } from '@requestnetwork/currency'; +import { CurrencyManager, ICurrencyManager } from '@requestnetwork/currency'; import { encodeRequestErc20Approval } from './encoder-approval'; import { encodeRequestPayment } from './encoder-payment'; import { IPreparedTransaction } from './prepared-transaction'; @@ -260,7 +260,12 @@ export async function isSolvent({ needsGas?: boolean; }): Promise { // Near case - if (NearChains.isChainSupported(currency.network) && providerOptions?.nearWalletConnection) { + if ( + CurrencyManager.getDefault().chainManager.ecosystems['near'].isChainSupported( + currency.network, + ) && + providerOptions?.nearWalletConnection + ) { return isNearAccountSolvent(amount, providerOptions.nearWalletConnection, currency); } // Main case (EVM) @@ -343,7 +348,12 @@ export function _getPaymentUrl(request: ClientTypes.IRequestData, amount?: BigNu // FIXME: should also compare the signer.chainId with the request.currencyInfo.network... const throwIfNotWeb3 = (request: ClientTypes.IRequestData) => { // FIXME: there is a near web3Provider equivalent: https://github.com/aurora-is-near/near-web3-provider - if (request.currencyInfo?.network && NearChains.isChainSupported(request.currencyInfo.network)) { + if ( + request.currencyInfo?.network && + CurrencyManager.getDefault().chainManager.ecosystems['near'].isChainSupported( + request.currencyInfo.network, + ) + ) { throw new UnsupportedPaymentChain(request.currencyInfo.network); } }; diff --git a/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts b/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts index 3c83e8e066..d65d23187e 100644 --- a/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts +++ b/packages/smart-contracts/deploy/deploy-zk-batch-contracts.ts @@ -1,7 +1,6 @@ import { erc20FeeProxyArtifact, ethereumFeeProxyArtifact } from '../src/lib'; import { deployContract } from './utils-zk'; import * as hre from 'hardhat'; -import { CurrencyTypes } from '@requestnetwork/types'; /** * Deploys Batch payments contracts to zkSync network. @@ -11,8 +10,8 @@ import { CurrencyTypes } from '@requestnetwork/types'; export default async function () { const [deployer] = await hre.ethers.getSigners(); const constructorArguments = [ - erc20FeeProxyArtifact.getAddress(hre.network.name as ChainTypes.IEvmChain), - ethereumFeeProxyArtifact.getAddress(hre.network.name as ChainTypes.IEvmChain), + erc20FeeProxyArtifact.getAddress(hre.network.name), + ethereumFeeProxyArtifact.getAddress(hre.network.name), hre.ethers.constants.AddressZero, hre.ethers.constants.AddressZero, hre.ethers.constants.AddressZero, diff --git a/packages/smart-contracts/scripts-create2/compute-one-address.ts b/packages/smart-contracts/scripts-create2/compute-one-address.ts index 2996f1ca96..f8277ea669 100644 --- a/packages/smart-contracts/scripts-create2/compute-one-address.ts +++ b/packages/smart-contracts/scripts-create2/compute-one-address.ts @@ -2,7 +2,6 @@ import { HardhatRuntimeEnvironmentExtended, IDeploymentParams } from './types'; import { requestDeployer } from '../src/lib'; import { create2ContractDeploymentList } from './utils'; import { getConstructorArgs } from './constructor-args'; -import { EvmChains } from '@requestnetwork/currency'; // Deploys, set up the contracts export async function computeCreate2DeploymentAddress( @@ -48,7 +47,6 @@ export const computeCreate2DeploymentAddressesFromList = async ( hre: HardhatRuntimeEnvironmentExtended, ): Promise => { const chain = hre.network.name; - EvmChains.assertChainSupported(chain); await Promise.all( create2ContractDeploymentList.map(async (contract) => { let address: string; diff --git a/packages/smart-contracts/scripts-create2/constructor-args.ts b/packages/smart-contracts/scripts-create2/constructor-args.ts index 09ea1ab38b..722e6d0a0b 100644 --- a/packages/smart-contracts/scripts-create2/constructor-args.ts +++ b/packages/smart-contracts/scripts-create2/constructor-args.ts @@ -1,5 +1,4 @@ import * as artifacts from '../src/lib'; -import { CurrencyTypes } from '@requestnetwork/types'; const getAdminWalletAddress = (contract: string): string => { if (!process.env.ADMIN_WALLET_ADDRESS) { @@ -8,7 +7,7 @@ const getAdminWalletAddress = (contract: string): string => { return process.env.ADMIN_WALLET_ADDRESS; }; -export const getConstructorArgs = (contract: string, network?: ChainTypes.IEvmChain): string[] => { +export const getConstructorArgs = (contract: string, network?: string): string[] => { switch (contract) { case 'ChainlinkConversionPath': { return ['0x0000000000000000000000000000000000000000', getAdminWalletAddress(contract)]; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts index 3cb511e1a9..eb42f9eef8 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts @@ -10,7 +10,7 @@ import { getDefaultProvider, normalizeGasFees, } from '@requestnetwork/utils'; -import { CurrencyTypes } from '@requestnetwork/types'; + import { suggestFeesEip1559 } from '../fee-suggestion'; import { executeContractMethod } from './execute-contract-method'; @@ -34,7 +34,7 @@ const BATCH_FEE_AMOUNT_USD_LIMIT = parseUnits('150', 8); */ export const updateChainlinkConversionPath = async ( contract: Contract, - network: ChainTypes.IEvmChain, + network: string, txOverrides: Overrides, signer: Wallet, signWithEoa: boolean, @@ -195,7 +195,7 @@ export const updateBatchPaymentFeeAmountUSDLimit = async ( */ export const updatePaymentFeeProxyAddress = async ( contract: Contract, - network: ChainTypes.IEvmChain, + network: string, txOverrides: Overrides, proxyType: 'native' | 'erc20', signer: Wallet, @@ -239,7 +239,7 @@ export const updatePaymentFeeProxyAddress = async ( */ export const updateBatchConversionProxy = async ( contract: Contract, - network: ChainTypes.IEvmChain, + network: string, txOverrides: Overrides, proxyName: string, signer: Wallet, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts b/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts index 0ade5735a9..9af540252f 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/execute-contract-method.ts @@ -3,7 +3,6 @@ import { Contract, Overrides, Wallet } from 'ethers'; import { safeAdminArtifact } from '../../src/lib/'; import Safe, { EthersAdapter, EthersAdapterConfig } from '@safe-global/protocol-kit'; import { ethers } from 'ethers'; -import { CurrencyTypes } from '@requestnetwork/types'; const txServiceUrls: Record = { mainnet: 'https://safe-transaction-mainnet.safe.global/', @@ -36,7 +35,7 @@ export const executeContractMethod = async ({ signer: Wallet; signWithEoa?: boolean; }): Promise => { - const safeAddress = safeAdminArtifact.getAddress(network as ChainTypes.VMChain); + const safeAddress = safeAdminArtifact.getAddress(network); const txServiceUrl = txServiceUrls[network]; if (!signWithEoa && !!safeAddress && !!txServiceUrl) { const ethAdapter = new EthersAdapter({ diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts index 60f408c003..a17b263325 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts @@ -7,8 +7,8 @@ import { updateBatchPaymentFees, updateNativeAndUSDAddress, } from './adminTasks'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyManager } from '@requestnetwork/currency'; +import { RequestLogicTypes } from '@requestnetwork/types'; /** * Updates the values of the batch fees of the BatchConversionPayments contract, if needed. @@ -31,7 +31,7 @@ export const setupBatchConversionPayments = async ({ // constants related to chainlink and conversion rate const currencyManager = CurrencyManager.getDefault(); - const setUpActions = async (network: ChainTypes.IEvmChain) => { + const setUpActions = async (network: string) => { console.log(`Setup BatchConversionPayments on ${network}`); if (!contractAddress) { @@ -93,7 +93,6 @@ export const setupBatchConversionPayments = async ({ }; for (const network of hre.config.xdeploy.networks) { try { - EvmChains.assertChainSupported(network); await setUpActions(network); } catch (err) { console.warn(`An error occurred during the setup of BatchConversion on ${network}`); diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupChainlinkConversionPath.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupChainlinkConversionPath.ts index 4986562a1f..9dd8546af2 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupChainlinkConversionPath.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupChainlinkConversionPath.ts @@ -1,4 +1,4 @@ -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { RequestLogicTypes } from '@requestnetwork/types'; import { chainlinkConversionPath } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; @@ -24,7 +24,6 @@ export const setupChainlinkConversionPath = async ({ await Promise.all( hre.config.xdeploy.networks.map(async (network: string) => { try { - EvmChains.assertChainSupported(network); if (!contractAddress) { contractAddress = chainlinkConversionPath.getAddress(network); } diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts index f655e138a6..5df7f8ab2d 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts @@ -6,7 +6,6 @@ import { updateRequestSwapFees, updateSwapRouter, } from './adminTasks'; -import { EvmChains } from '@requestnetwork/currency'; /** * Updates the values of the chainlinkConversionPath and swap router of the ERC20SwapToConversion contract @@ -27,7 +26,6 @@ export const setupERC20SwapToConversion = async ({ await Promise.all( hre.config.xdeploy.networks.map(async (network: string) => { try { - EvmChains.assertChainSupported(network); if (!contractAddress) { contractAddress = erc20SwapConversionArtifact.getAddress(network); } diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToPay.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToPay.ts index 2b153190f9..4cc9e0ee0a 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToPay.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToPay.ts @@ -1,4 +1,3 @@ -import { EvmChains } from '@requestnetwork/currency'; import { erc20SwapToPayArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { getSignerAndGasFees, updateRequestSwapFees, updateSwapRouter } from './adminTasks'; @@ -22,7 +21,6 @@ export const setupERC20SwapToPay = async ({ await Promise.all( hre.config.xdeploy.networks.map(async (network: string) => { try { - EvmChains.assertChainSupported(network); if (!contractAddress) { contractAddress = erc20SwapToPayArtifact.getAddress(network); } diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts index 097d4e627b..e760127d94 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts @@ -1,4 +1,4 @@ -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { RequestLogicTypes } from '@requestnetwork/types'; import { ethConversionArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; @@ -28,7 +28,6 @@ export const setupETHConversionProxy = async ({ await Promise.all( hre.config.xdeploy.networks.map(async (network: string) => { try { - EvmChains.assertChainSupported(network); if (!contractAddress) { contractAddress = ethConversionArtifact.getAddress(network); } diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts index 5d372d11ae..0d553e0f37 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts @@ -5,7 +5,6 @@ import { updateChainlinkConversionPath, updatePaymentFeeProxyAddress, } from './adminTasks'; -import { EvmChains } from '@requestnetwork/currency'; const ERC20ConversionVersion = '0.1.2'; @@ -28,7 +27,6 @@ export const setupErc20ConversionProxy = async ({ await Promise.all( hre.config.xdeploy.networks.map(async (network: string) => { try { - EvmChains.assertChainSupported(network); if (!contractAddress) { contractAddress = erc20ConversionProxy.getAddress(network); } diff --git a/packages/smart-contracts/scripts-create2/contract-setup/update-owner.ts b/packages/smart-contracts/scripts-create2/contract-setup/update-owner.ts index 22e20a5b9e..ee60429096 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/update-owner.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/update-owner.ts @@ -2,7 +2,6 @@ import { safeAdminArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { getArtifact } from '../utils'; import { getSignerAndGasFees } from './adminTasks'; -import { EvmChains } from '@requestnetwork/currency'; import { executeContractMethod } from './execute-contract-method'; import { Contract } from 'ethers'; @@ -23,7 +22,6 @@ export const updateOwner = async ({ }): Promise => { for (const network of hre.config.xdeploy.networks) { try { - EvmChains.assertChainSupported(network); const contractArtifact = getArtifact(contract); const contractAddress = contractArtifact.getAddress(network); const { signer, txOverrides } = await getSignerAndGasFees(network, hre); diff --git a/packages/smart-contracts/scripts-create2/contract-setup/update-whitelisted-role.ts b/packages/smart-contracts/scripts-create2/contract-setup/update-whitelisted-role.ts index 3a0b2c72d5..7a213a43e2 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/update-whitelisted-role.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/update-whitelisted-role.ts @@ -2,7 +2,6 @@ import { safeAdminArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { getArtifact } from '../utils'; import { getSignerAndGasFees } from './adminTasks'; -import { EvmChains } from '@requestnetwork/currency'; import { executeContractMethod } from './execute-contract-method'; import { Contract } from 'ethers'; @@ -65,7 +64,6 @@ export const updateWhitelistedRole = async ({ }): Promise => { for (const network of hre.config.xdeploy.networks) { try { - EvmChains.assertChainSupported(network); const contractArtifact = getArtifact(contract); const contractAddress = contractArtifact.getAddress(network); const { signer, txOverrides } = await getSignerAndGasFees(network, hre); diff --git a/packages/smart-contracts/scripts-create2/deploy.ts b/packages/smart-contracts/scripts-create2/deploy.ts index 4eee974b57..522a561abf 100644 --- a/packages/smart-contracts/scripts-create2/deploy.ts +++ b/packages/smart-contracts/scripts-create2/deploy.ts @@ -2,7 +2,6 @@ import { create2ContractDeploymentList, isContractDeployed } from './utils'; import { HardhatRuntimeEnvironmentExtended, IDeploymentParams } from './types'; import { xdeploy } from './xdeployer'; import { getConstructorArgs } from './constructor-args'; -import { EvmChains } from '@requestnetwork/currency'; import { setupContract } from './contract-setup/setups'; /** @@ -55,7 +54,6 @@ export const deployWithCreate2FromList = async ( ): Promise => { for (const contract of create2ContractDeploymentList) { const network = hre.config.xdeploy.networks[0]; - EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); const address = await deployOneWithCreate2({ contract, constructorArgs }, hre); await setupContract({ diff --git a/packages/smart-contracts/scripts-create2/tenderly.ts b/packages/smart-contracts/scripts-create2/tenderly.ts index b60a019a1f..105d4356e0 100644 --- a/packages/smart-contracts/scripts-create2/tenderly.ts +++ b/packages/smart-contracts/scripts-create2/tenderly.ts @@ -3,8 +3,8 @@ import * as artifacts from '../src/lib/artifacts'; import { ContractArtifact } from '../src/lib'; import { Contract } from 'ethers'; import * as console from 'console'; -import { EvmChains } from '@requestnetwork/currency'; -import { CurrencyTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; +import { ChainManager } from '@requestnetwork/chain/src'; const tenderlyBaseURL = 'https://api.tenderly.co'; const makeTenderlyClient = @@ -39,7 +39,7 @@ const supportedTenderlyChains: ChainTypes.IEvmChain[] = [ 'optimism', 'rinkeby', 'xdai', -]; +].map((chainName: string) => ChainManager.getDefault().fromName(chainName, ['evm'])); type TenderlyContract = { address: string; chainId: number }; @@ -58,13 +58,17 @@ export const tenderlyImportAll = async (hre: HardhatRuntimeEnvironmentExtended): const deployments = artifact.getAllAddressesFromAllNetworks(); for (const deployment of deployments) { const { networkName, address, version } = deployment; + let deploymentChain: ChainTypes.IEvmChain; try { - EvmChains.assertChainSupported(networkName); + deploymentChain = ChainManager.getDefault().fromName(networkName, ['evm']); } catch { continue; } - if (!supportedTenderlyChains.includes(networkName)) continue; - const chainId = EvmChains.getChainId(networkName); + const chain = supportedTenderlyChains.find((tenderlyChain) => + tenderlyChain.eq(deploymentChain), + ); + if (!chain) continue; + const chainId = parseInt(chain.id); const contract: TenderlyContract = { address, chainId, @@ -76,7 +80,7 @@ export const tenderlyImportAll = async (hre: HardhatRuntimeEnvironmentExtended): }; versions[version] ??= new Set(); versions[version].add(contractId); - (EvmChains.isTestnet(networkName) ? testnetContracts : mainnetContracts).add(contractId); + (chain.testnet ? testnetContracts : mainnetContracts).add(contractId); } } console.log(`> Retrieved ${Object.keys(contracts).length} contracts from protocol artifacts`); diff --git a/packages/smart-contracts/scripts-create2/transfer-ownership.ts b/packages/smart-contracts/scripts-create2/transfer-ownership.ts index 8e114d6af7..716e002a14 100644 --- a/packages/smart-contracts/scripts-create2/transfer-ownership.ts +++ b/packages/smart-contracts/scripts-create2/transfer-ownership.ts @@ -1,6 +1,5 @@ import { HardhatRuntimeEnvironmentExtended } from './types'; import { create2ContractDeploymentList } from './utils'; -import { EvmChains } from '@requestnetwork/currency'; import { updateOwner } from './contract-setup/update-owner'; import { updateWhitelistedRole } from './contract-setup/update-whitelisted-role'; @@ -8,8 +7,6 @@ export const transferOwnership = async ( hre: HardhatRuntimeEnvironmentExtended, signWithEoa: boolean, ): Promise => { - const chain = hre.network.name; - EvmChains.assertChainSupported(chain); await Promise.all( create2ContractDeploymentList.map(async (contract) => { switch (contract) { diff --git a/packages/smart-contracts/scripts-create2/utils.ts b/packages/smart-contracts/scripts-create2/utils.ts index 2e624cc04e..ff34b49302 100644 --- a/packages/smart-contracts/scripts-create2/utils.ts +++ b/packages/smart-contracts/scripts-create2/utils.ts @@ -1,6 +1,5 @@ import { Contract } from 'ethers'; import * as artifacts from '../src/lib'; -import { EvmChains } from '@requestnetwork/currency'; /** * List of smart contract that we deploy using the CREATE2 scheme through the Request Deployer contract @@ -74,7 +73,6 @@ export const isContractDeployed = ( computedAddress: string, ): boolean => { try { - EvmChains.assertChainSupported(network); const contractArtifact = getArtifact(contract); const addresses = contractArtifact.getAllAddresses(network); return addresses.some((x) => x.address === computedAddress); diff --git a/packages/smart-contracts/scripts-create2/verify.ts b/packages/smart-contracts/scripts-create2/verify.ts index b128b711f9..3d2c66e570 100644 --- a/packages/smart-contracts/scripts-create2/verify.ts +++ b/packages/smart-contracts/scripts-create2/verify.ts @@ -2,7 +2,6 @@ import { computeCreate2DeploymentAddress } from './compute-one-address'; import { getConstructorArgs } from './constructor-args'; import { HardhatRuntimeEnvironmentExtended, IDeploymentParams } from './types'; import { create2ContractDeploymentList } from './utils'; -import { EvmChains } from '@requestnetwork/currency'; export const verifyOne = async ( contractAddress: string, @@ -49,7 +48,6 @@ export async function VerifyCreate2FromList(hre: HardhatRuntimeEnvironmentExtend case 'BatchConversionPayments': case 'ERC20TransferableReceivable': { const network = hre.config.xdeploy.networks[0]; - EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); address = await computeCreate2DeploymentAddress({ contract, constructorArgs }, hre); await verifyOne(address, { contract, constructorArgs }, hre); diff --git a/packages/smart-contracts/scripts/deploy-one.ts b/packages/smart-contracts/scripts/deploy-one.ts index 1bfb1f04d1..06ab69e806 100644 --- a/packages/smart-contracts/scripts/deploy-one.ts +++ b/packages/smart-contracts/scripts/deploy-one.ts @@ -2,8 +2,6 @@ import '@nomiclabs/hardhat-ethers'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; import { Contract } from 'ethers'; import { ContractArtifact } from '../src/lib'; -import { EvmChains } from '@requestnetwork/currency'; - export interface DeploymentResult { address: string; contractName: string; @@ -61,7 +59,6 @@ export async function deployOne( if (options?.artifact) { try { const chain = hre.network.name; - EvmChains.assertChainSupported(chain); address = options.artifact.getAddress(chain, options.version); const action = args.force ? '(forcing deployment)' : '(skipping)'; console.log( diff --git a/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts b/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts index 2cb168930f..d8abdd0324 100644 --- a/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts +++ b/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts @@ -11,7 +11,7 @@ import { ethConversionArtifact, ethereumFeeProxyArtifact, } from '../src/lib'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { deployAddressChecking } from './utils'; import { BigNumber } from 'ethers'; import { PRECISION_RATE } from './test-deploy_chainlink_contract'; @@ -26,7 +26,6 @@ export async function deployBatchConversionPayment( try { console.log('Deploy BatchConversionPayments'); const chain = hre.network.name; - EvmChains.assertChainSupported(chain); const _ERC20FeeProxyAddress = erc20FeeProxyArtifact.getAddress('private'); const _EthereumFeeProxyAddress = ethereumFeeProxyArtifact.getAddress('private'); const _paymentErc20ConversionFeeProxy = erc20ConversionProxy.getAddress('private'); diff --git a/packages/smart-contracts/scripts/test-deploy-batch-erc-eth-deployment.ts b/packages/smart-contracts/scripts/test-deploy-batch-erc-eth-deployment.ts index 2d115a3f07..19db1e45d8 100644 --- a/packages/smart-contracts/scripts/test-deploy-batch-erc-eth-deployment.ts +++ b/packages/smart-contracts/scripts/test-deploy-batch-erc-eth-deployment.ts @@ -4,13 +4,11 @@ import { deployOne } from '../scripts/deploy-one'; import { batchPaymentsArtifact } from '../src/lib'; import { deployAddressChecking } from './utils'; -import { EvmChains } from '@requestnetwork/currency'; // Deploys, set up the contracts export async function deployBatchPayment(args: any, hre: HardhatRuntimeEnvironment): Promise { try { const chain = hre.network.name; - EvmChains.assertChainSupported(chain); const ERC20FeeProxyAddress = '0x75c35C980C0d37ef46DF04d31A140b65503c0eEd'; const EthereumFeeProxyAddress = '0x3d49d1eF2adE060a33c6E6Aa213513A7EE9a6241'; diff --git a/packages/smart-contracts/src/lib/ContractArtifact.ts b/packages/smart-contracts/src/lib/ContractArtifact.ts index fd605b49ee..80402e7a26 100644 --- a/packages/smart-contracts/src/lib/ContractArtifact.ts +++ b/packages/smart-contracts/src/lib/ContractArtifact.ts @@ -1,6 +1,5 @@ import { Contract, providers, Signer } from 'ethers'; import type { JsonFragment } from '@ethersproject/abi'; -import type { CurrencyTypes } from '@requestnetwork/types'; /** * Contract information specific to a network @@ -13,16 +12,16 @@ export type ArtifactNetworkInfo = { }; /** Deployment information and ABI per network */ -export type ArtifactDeploymentInfo = { +export type ArtifactDeploymentInfo = { abi: JsonFragment[]; - deployment: Partial>; + deployment: Partial>; }; /** Deployment information and ABI per version and network */ -export type ArtifactInfo< - TVersion extends string = string, - TNetwork extends ChainTypes.VMChain = ChainTypes.VMChain, -> = Record>; +export type ArtifactInfo = Record< + TVersion, + ArtifactDeploymentInfo +>; export type DeploymentInformation = { address: string; @@ -52,7 +51,7 @@ export class ContractArtifact { * Returns an ethers contract instance for the given `networkName` */ connect( - networkName: ChainTypes.IEvmChain, + networkName: string, signerOrProvider: Signer | providers.Provider, version: string = this.lastVersion, ): TContract { @@ -81,7 +80,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns the address of the deployed contract */ - getAddress(networkName: ChainTypes.VMChain, version = this.lastVersion): string { + getAddress(networkName: string, version = this.lastVersion): string { return this.getDeploymentInformation(networkName, version).address; } @@ -90,9 +89,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns the addresses of the deployed contract and the associated version. */ - getAllAddresses( - networkName: ChainTypes.VMChain, - ): { version: string; address: string | undefined }[] { + getAllAddresses(networkName: string): { version: string; address: string | undefined }[] { const entries = Object.entries(this.info); return entries.map(([version, { deployment }]) => ({ version, @@ -107,11 +104,11 @@ export class ContractArtifact { getAllAddressesFromAllNetworks(): { version: string; address: string; - networkName: ChainTypes.VMChain; + networkName: string; }[] { const deployments = []; for (const version in this.info) { - let networkName: ChainTypes.VMChain; + let networkName: string; for (networkName in this.info[version].deployment) { const address = this.info[version].deployment[networkName]?.address; if (!address) continue; @@ -131,7 +128,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns the number of the block where the contract was deployed */ - getCreationBlockNumber(networkName: ChainTypes.VMChain, version = this.lastVersion): number { + getCreationBlockNumber(networkName: string, version = this.lastVersion): number { return this.getDeploymentInformation(networkName, version).creationBlockNumber; } @@ -141,10 +138,7 @@ export class ContractArtifact { * @param networkName the name of the network where the contract is deployed * @returns The address and the number of the creation block */ - getDeploymentInformation( - networkName: ChainTypes.VMChain, - version = this.lastVersion, - ): DeploymentInformation { + getDeploymentInformation(networkName: string, version = this.lastVersion): DeploymentInformation { const versionInfo = this.info[version]; if (!versionInfo) { throw Error(`No deployment for version: ${version}.`); @@ -164,7 +158,7 @@ export class ContractArtifact { * @returns The address and the number of the creation block, or null if not found */ getOptionalDeploymentInformation( - networkName: ChainTypes.VMChain, + networkName: string, version = this.lastVersion, ): DeploymentInformation | null { return this.info[version]?.deployment[networkName] || null; diff --git a/packages/smart-contracts/test/contracts/BatchConversionPayments.test.ts b/packages/smart-contracts/test/contracts/BatchConversionPayments.test.ts index c2b630c61e..ad5808f2eb 100644 --- a/packages/smart-contracts/test/contracts/BatchConversionPayments.test.ts +++ b/packages/smart-contracts/test/contracts/BatchConversionPayments.test.ts @@ -13,7 +13,7 @@ import { import { PaymentTypes } from '@requestnetwork/types'; import { BigNumber, ContractTransaction, Signer } from 'ethers'; import { expect } from 'chai'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { chainlinkConversionPath } from '../../src/lib'; import { FAU_USD_RATE } from '../../scripts/test-deploy-batch-conversion-deployment'; import { localERC20AlphaArtifact, secondLocalERC20AlphaArtifact } from './localArtifacts'; @@ -29,7 +29,6 @@ const BATCH_PAYMENT_NETWORK_ID = PaymentTypes.BATCH_PAYMENT_NETWORK_ID; describe('contract: BatchConversionPayments', async () => { const networkConfig = network.config as HttpNetworkConfig; - EvmChains.assertChainSupported(network.name); const provider = new ethers.providers.JsonRpcProvider(networkConfig.url); let adminAddress: string; @@ -124,7 +123,6 @@ describe('contract: BatchConversionPayments', async () => { [adminAddress, from, to, feeAddress] = (await ethers.getSigners()).map((s) => s.address); [adminSigner, fromSigner, , , signer4] = await ethers.getSigners(); - EvmChains.assertChainSupported(network.name); chainlinkPath = chainlinkConversionPath.connect(network.name, fromSigner); const erc20FeeProxy = await new ERC20FeeProxy__factory(adminSigner).deploy(); diff --git a/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts b/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts index 7807c93903..0820fea5e3 100644 --- a/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts +++ b/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts @@ -12,7 +12,7 @@ import { TestERC20__factory, } from '../../src/types'; import { chainlinkConversionPath } from '../../src/lib'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { PaymentTypes } from '@requestnetwork/types'; const logGasInfos = false; @@ -67,7 +67,6 @@ describe('contract: batchNoConversionPayments: ERC20', () => { erc20FeeProxy = await new ERC20FeeProxy__factory(owner).deploy(); const ethFeeProxy = await new EthereumFeeProxy__factory(owner).deploy(); - EvmChains.assertChainSupported(network.name); chainlinkPath = chainlinkConversionPath.connect(network.name, owner); batch = await new BatchNoConversionPayments__factory(owner).deploy( erc20FeeProxy.address, diff --git a/packages/smart-contracts/test/contracts/BatchNoConversionEthPayments.test.ts b/packages/smart-contracts/test/contracts/BatchNoConversionEthPayments.test.ts index 6b9b2a48c3..a72937472a 100644 --- a/packages/smart-contracts/test/contracts/BatchNoConversionEthPayments.test.ts +++ b/packages/smart-contracts/test/contracts/BatchNoConversionEthPayments.test.ts @@ -12,7 +12,7 @@ import { EthereumFeeProxy, BatchNoConversionPayments } from '../../src/types'; import { chainlinkConversionPath } from '../../src/lib'; import { HttpNetworkConfig } from 'hardhat/types'; import { PaymentTypes } from '@requestnetwork/types'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; const logGasInfos = false; @@ -65,7 +65,6 @@ describe('contract: batchNoConversionPayments: Ethereum', () => { const erc20FeeProxy = await new ERC20FeeProxy__factory(owner).deploy(); ethFeeProxy = await new EthereumFeeProxy__factory(owner).deploy(); - EvmChains.assertChainSupported(network.name); chainlinkPath = chainlinkConversionPath.connect(network.name, owner); batch = await new BatchNoConversionPayments__factory(owner).deploy( erc20FeeProxy.address, diff --git a/packages/smart-contracts/test/contracts/ChainlinkConversionPath.test.ts b/packages/smart-contracts/test/contracts/ChainlinkConversionPath.test.ts index 1a8806e68b..e62d36c7c9 100644 --- a/packages/smart-contracts/test/contracts/ChainlinkConversionPath.test.ts +++ b/packages/smart-contracts/test/contracts/ChainlinkConversionPath.test.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { ethers, network } from 'hardhat'; import '@nomiclabs/hardhat-ethers'; import { chainlinkConversionPath as chainlinkConvArtifact } from '../../src/lib'; @@ -25,7 +25,6 @@ let conversionPathInstance: ChainlinkConversionPath; describe('contract: ChainlinkConversionPath', () => { before(async () => { const [signer] = await ethers.getSigners(); - EvmChains.assertChainSupported(network.name); conversionPathInstance = chainlinkConvArtifact.connect(network.name, signer); USDT_address = localUSDTArtifact.getAddress(network.name); DAI_address = localERC20AlphaArtifact.getAddress(network.name); diff --git a/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts b/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts index 768f7987b3..67dcb76591 100644 --- a/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts +++ b/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts @@ -2,7 +2,7 @@ import { ethers, network } from 'hardhat'; import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { AggregatorMock__factory, ChainlinkConversionPath, @@ -49,7 +49,6 @@ describe('contract: ERC20SwapToConversion', () => { const erc20Liquidity = erc20Decimal.mul(100); before(async () => { - EvmChains.assertChainSupported(network.name); [, from, to, builder] = (await ethers.getSigners()).map((s) => s.address); [adminSigner, signer] = await ethers.getSigners(); chainlinkConversion = chainlinkConvArtifact.connect(network.name, adminSigner); diff --git a/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts b/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts index 072ed2bfde..21e0b20b11 100644 --- a/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts +++ b/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts @@ -13,7 +13,6 @@ import { TestERC20__factory, } from '../../src/types'; import { erc20FeeProxyArtifact, erc20SwapToPayArtifact } from '../../src/lib'; -import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -39,7 +38,6 @@ describe('contract: SwapToPay', () => { const erc20Liquidity = erc20Decimal.mul(100); before(async () => { - EvmChains.assertChainSupported(network.name); [, from, to, builder] = (await ethers.getSigners()).map((s) => s.address); [adminSigner, signer] = await ethers.getSigners(); erc20FeeProxy = erc20FeeProxyArtifact.connect(network.name, adminSigner); diff --git a/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts b/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts index 68d8b38891..51b289f746 100644 --- a/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts +++ b/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts @@ -11,7 +11,7 @@ import { import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { chainlinkConversionPath } from '../../src/lib'; import { localERC20AlphaArtifact } from './localArtifacts'; @@ -41,7 +41,6 @@ describe('contract: Erc20ConversionProxy', () => { let chainlinkPath: ChainlinkConversionPath; before(async () => { - EvmChains.assertChainSupported(network.name); [from, to, feeAddress] = (await ethers.getSigners()).map((s) => s.address); [signer] = await ethers.getSigners(); chainlinkPath = chainlinkConversionPath.connect(network.name, signer); diff --git a/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts b/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts index e902d86815..8d3dd1637e 100644 --- a/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts +++ b/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts @@ -15,7 +15,7 @@ import { import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; import { chainlinkConversionPath } from '../../src/lib'; import { HttpNetworkConfig } from 'hardhat/types'; @@ -45,7 +45,6 @@ describe('contract: EthConversionProxy', () => { const provider = new ethers.providers.JsonRpcProvider(networkConfig.url); before(async () => { - EvmChains.assertChainSupported(network.name); [from, to, feeAddress] = (await ethers.getSigners()).map((s) => s.address); [signer] = await ethers.getSigners(); chainlinkPath = chainlinkConversionPath.connect(network.name, signer); diff --git a/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts b/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts index 395a5b3827..261c310002 100644 --- a/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts +++ b/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts @@ -11,7 +11,6 @@ import { } from '../../src/types'; import { ethereumFeeProxyArtifact } from '../../src/lib/'; import { HttpNetworkConfig } from 'hardhat/types'; -import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -29,7 +28,6 @@ describe('contract: EthereumFeeProxy', () => { const feeAddress = '0xF4255c5e53a08f72b0573D1b8905C5a50aA9c2De'; before(async () => { - EvmChains.assertChainSupported(network.name); [, to] = (await ethers.getSigners()).map((s) => s.address); [signer] = await ethers.getSigners(); ethFeeProxy = ethereumFeeProxyArtifact.connect(network.name, signer); diff --git a/packages/smart-contracts/test/contracts/EthereumProxy.test.ts b/packages/smart-contracts/test/contracts/EthereumProxy.test.ts index 5946e0c3fd..17d0f19d14 100644 --- a/packages/smart-contracts/test/contracts/EthereumProxy.test.ts +++ b/packages/smart-contracts/test/contracts/EthereumProxy.test.ts @@ -11,7 +11,6 @@ import { } from '../../src/types'; import { ethereumProxyArtifact } from '../../src/lib/'; import { HttpNetworkConfig } from 'hardhat/types'; -import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -29,7 +28,6 @@ describe('contract: EthereumProxy', () => { const provider = new ethers.providers.JsonRpcProvider(networkConfig.url); before(async () => { - EvmChains.assertChainSupported(network.name); [from, to] = (await ethers.getSigners()).map((s) => s.address); [signer] = await ethers.getSigners(); ethProxy = ethereumProxyArtifact.connect(network.name, signer); diff --git a/packages/smart-contracts/test/lib/artifact.test.ts b/packages/smart-contracts/test/lib/artifact.test.ts index e16e7fcd40..0c47a510ca 100644 --- a/packages/smart-contracts/test/lib/artifact.test.ts +++ b/packages/smart-contracts/test/lib/artifact.test.ts @@ -1,7 +1,6 @@ import { BigNumber, providers } from 'ethers'; import { RequestOpenHashSubmitter } from '../../src/types'; import { erc20FeeProxyArtifact, erc20ProxyArtifact } from '../../src/lib'; -import { CurrencyTypes } from '@requestnetwork/types'; describe('Artifact', () => { it('can get the contract info for latest version', () => { diff --git a/packages/types/src/advanced-logic-types.ts b/packages/types/src/advanced-logic-types.ts index 95d09f5d22..6682549da3 100644 --- a/packages/types/src/advanced-logic-types.ts +++ b/packages/types/src/advanced-logic-types.ts @@ -1,6 +1,7 @@ import * as Extension from './extension-types'; import * as Identity from './identity-types'; import * as RequestLogic from './request-logic-types'; +import { IChain } from './chain-types'; /** Advanced Logic extensions */ export interface IAdvancedLogicExtensions { @@ -32,13 +33,13 @@ export interface IAdvancedLogic { timestamp: number, ) => RequestLogic.IExtensionStates; getNativeTokenExtensionForNetwork: ( - network: string, + chain: IChain, ) => Extension.IExtension | undefined; getAnyToNativeTokenExtensionForNetwork: ( - network: string, + chain: IChain, ) => Extension.IExtension | undefined; getFeeProxyContractErc20ForNetwork: ( - network?: string, + chain?: IChain, ) => Extension.PnFeeReferenceBased.IFeeReferenceBased | undefined; extensions: IAdvancedLogicExtensions; } diff --git a/packages/types/src/chain-types.ts b/packages/types/src/chain-types.ts index 3b3f73cc63..8e97a8daf8 100644 --- a/packages/types/src/chain-types.ts +++ b/packages/types/src/chain-types.ts @@ -1,30 +1,32 @@ import { RequestLogicTypes } from './index'; -interface IChainCommon { +export interface IChainCommon { id: string; name: string; testnet: boolean; ecosystem: ChainEcosystem; + currencyType: RequestLogicTypes.CURRENCY; + eq(chain: IChainCommon): boolean; } export interface IBtcChain extends IChainCommon { ecosystem: 'btc'; - currenciesType: RequestLogicTypes.CURRENCY.BTC; + currencyType: RequestLogicTypes.CURRENCY.BTC; } export interface IDeclarativeChain extends IChainCommon { ecosystem: 'declarative'; - currenciesType: RequestLogicTypes.CURRENCY.ETH; + currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface IEvmChain extends IChainCommon { ecosystem: 'evm'; - currenciesType: RequestLogicTypes.CURRENCY.ETH; + currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface INearChain extends IChainCommon { ecosystem: 'near'; - currenciesType: RequestLogicTypes.CURRENCY.ETH; + currencyType: RequestLogicTypes.CURRENCY.ETH; } /** diff --git a/packages/utils/src/providers.ts b/packages/utils/src/providers.ts index 19ac3ff8b2..65ad81160c 100644 --- a/packages/utils/src/providers.ts +++ b/packages/utils/src/providers.ts @@ -1,4 +1,4 @@ -import { LogTypes } from '@requestnetwork/types'; +import { ChainTypes, LogTypes } from '@requestnetwork/types'; import { providers, constants, utils } from 'ethers'; @@ -132,8 +132,11 @@ const setProviderFactory = (providerFactory?: CurrentProviderFactory): void => { * * @param network the blockchain network. See https://chainid.network/chains.json `network` field for reference */ -const getDefaultProvider = (network?: string): providers.Provider => { - const provider = currentProviderFactory(network, defaultProviderFactory); +const getDefaultProvider = (network?: ChainTypes.IChain | string): providers.Provider => { + const provider = currentProviderFactory( + typeof network === 'string' ? network : network?.name, + defaultProviderFactory, + ); if (typeof provider === 'string') { return new providers.StaticJsonRpcProvider(provider); } From 7cc2bcb918d43e40a7f38b07775f6da2bdc32e2f Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 15 Feb 2024 20:58:35 +0100 Subject: [PATCH 03/14] WIP --- packages/advanced-logic/src/advanced-logic.ts | 86 ++++++++++++++----- .../src/extensions/abstract-extension.ts | 8 +- .../payment-network/address-based.ts | 2 +- .../payment-network/any-to-erc20-proxy.ts | 2 +- .../bitcoin/mainnet-address-based.ts | 4 +- .../bitcoin/testnet-address-based.ts | 4 +- .../erc20/fee-proxy-contract.ts | 23 +++-- .../near/any-to-near-testnet.ts | 7 +- .../payment-network/near/any-to-near.ts | 6 +- .../payment-network/near/near-native.ts | 6 +- .../near/near-testnet-native.ts | 7 +- packages/chain/src/chain-manager.ts | 64 +++++++------- packages/chain/src/chains/btc/btc-chain.ts | 4 +- .../chain/src/chains/btc/btc-ecosystem.ts | 7 +- packages/chain/src/chains/chain-abstract.ts | 3 +- .../chains/declarative/declarative-chain.ts | 2 +- .../declarative/declarative-ecosystem.ts | 7 +- .../chain/src/chains/ecosystem-abstract.ts | 2 +- packages/chain/src/chains/evm/evm-chain.ts | 2 +- .../chain/src/chains/evm/evm-ecosystem.ts | 2 +- packages/chain/src/chains/near/near-chain.ts | 2 +- .../chain/src/chains/near/near-ecosystem.ts | 2 +- packages/currency/src/currency-manager.ts | 5 +- packages/ethereum-storage/src/config.ts | 4 +- .../src/ethereum-tx-submitter.ts | 4 +- .../src/any-to-any-detector.ts | 5 +- .../src/any-to-native-detector.ts | 4 +- .../src/any/any-to-erc20-proxy.ts | 15 +--- .../src/any/any-to-eth-proxy.ts | 13 +-- .../src/any/retrievers/any-to-any-proxy.ts | 4 +- .../payment-detection/src/erc20/currency.ts | 2 - .../src/erc20/escrow-info-retriever.ts | 4 +- .../src/erc20/fee-proxy-contract.ts | 74 ++++++++-------- .../src/erc20/proxy-contract.ts | 8 +- .../src/erc20/transferable-receivable.ts | 8 +- .../src/erc777/superfluid-detector.ts | 1 + .../src/eth/fee-proxy-detector.ts | 8 +- .../src/eth/info-retriever.ts | 8 +- .../payment-detection/src/eth/input-data.ts | 12 +-- .../src/eth/proxy-info-retriever.ts | 4 +- .../src/fee-reference-based-detector.ts | 5 +- .../src/native-token-detector.ts | 4 +- .../src/near/near-conversion-detector.ts | 22 ++--- .../src/near/near-detector.ts | 13 +-- .../near-conversion-info-retriever.ts | 10 +-- .../near/retrievers/near-info-retriever.ts | 2 +- .../src/payment-network-factory.ts | 21 +++-- .../src/reference-based-detector.ts | 6 +- .../payment-detection/src/thegraph/client.ts | 6 +- packages/payment-detection/src/types.ts | 9 +- packages/payment-detection/src/utils.ts | 18 ++-- .../test/payment-network-factory.test.ts | 26 ++++++ .../payment-processor/src/payment/index.ts | 14 +-- .../payment-processor/src/payment/utils.ts | 11 +-- packages/request-client.js/package.json | 1 + .../src/api/request-network.ts | 7 +- packages/request-client.js/src/api/request.ts | 8 +- .../src/http-metamask-data-access.ts | 23 ++--- packages/request-node/package.json | 1 + packages/request-node/src/dataAccess.ts | 8 +- .../src/request/confirmedTransactionStore.ts | 6 +- packages/request-node/src/server.ts | 16 ++-- .../scripts-create2/tenderly.ts | 8 +- .../src/chainlinkConversionPathTools.ts | 10 +-- packages/types/src/chain-types.ts | 39 ++++++--- .../pn-any-to-any-conversion-types.ts | 3 +- .../src/extensions/pn-any-to-erc20-types.ts | 3 +- packages/types/src/payment-types.ts | 3 +- 68 files changed, 405 insertions(+), 333 deletions(-) diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index 2b49c128f5..b65aa42f88 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -27,11 +27,34 @@ import NativeToken from './extensions/payment-network/native-token'; import AnyToNative from './extensions/payment-network/any-to-native'; import Erc20TransferableReceivablePaymentNetwork from './extensions/payment-network/erc20/transferable-receivable'; +const { ECOSYSTEM, VM_ECOSYSTEMS } = ChainTypes; + /** * Module to manage Advanced logic extensions * Package to route the format and parsing of extensions following their id */ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic { + public static supportedEcosystemsForExtension: Record< + ExtensionTypes.ID, + readonly ChainTypes.ECOSYSTEM[] + > = { + [ExtensionTypes.ID.CONTENT_DATA]: [ECOSYSTEM.EVM], + [ExtensionTypes.PAYMENT_NETWORK_ID.BITCOIN_ADDRESS_BASED]: [ECOSYSTEM.BTC], + [ExtensionTypes.PAYMENT_NETWORK_ID.TESTNET_BITCOIN_ADDRESS_BASED]: [ECOSYSTEM.BTC], + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_DECLARATIVE]: [ECOSYSTEM.BTC], + [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_ADDRESS_BASED]: VM_ECOSYSTEMS, + [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_PROXY_CONTRACT]: VM_ECOSYSTEMS, + [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT]: VM_ECOSYSTEMS, + [ExtensionTypes.PAYMENT_NETWORK_ID.ERC777_STREAM]: [ECOSYSTEM.EVM], + [ExtensionTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA]: [ECOSYSTEM.EVM], + [ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN]: [ECOSYSTEM.NEAR], + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY]: VM_ECOSYSTEMS, + [ExtensionTypes.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT]: [ECOSYSTEM.EVM], + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY]: [ECOSYSTEM.EVM], + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN]: [ECOSYSTEM.NEAR], + [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE]: [ECOSYSTEM.EVM], + }; + /** Give access to the functions specific of the extensions supported */ public extensions: { addressBasedBtc: AddressBasedBtc; @@ -108,8 +131,23 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic requestState: RequestLogicTypes.IRequest, ): ExtensionTypes.IExtension { const id: ExtensionTypes.ID = extensionAction.id; - const chain = this.getChain(extensionAction, requestState); - const extension: ExtensionTypes.IExtension | undefined = { + const ecosystems = AdvancedLogic.supportedEcosystemsForExtension[id]; + if (!ecosystems) { + throw Error(`chain ecosystem not recognized for extension: ${id}`); + } + const chain = this.getChainForActionAndState(extensionAction, requestState, ecosystems); + const extensions = this.getExtensionsForChain(chain); + const extension = extensions[id]; + if (!extension) { + throw Error(`extension with id: ${id} not found for network: ${chain}`); + } + return extension; + } + + public getExtensionsForChain( + chain?: ChainTypes.IChain, + ): Record { + const extensions: Record = { [ExtensionTypes.ID.CONTENT_DATA]: this.extensions.contentData, [ExtensionTypes.PAYMENT_NETWORK_ID.BITCOIN_ADDRESS_BASED]: this.extensions.addressBasedBtc, [ExtensionTypes.PAYMENT_NETWORK_ID.TESTNET_BITCOIN_ADDRESS_BASED]: @@ -131,19 +169,19 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic this.getAnyToNativeTokenExtensionForNetwork(chain), [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE]: this.extensions.erc20TransferableReceivable, - }[id]; - - if (!extension) { - if ( - id === ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN || - id === ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN - ) { - throw Error(`extension with id: ${id} not found for network: ${chain}`); - } - - throw Error(`extension not recognized, id: ${id}`); - } - return extension; + }; + // filter-out unsupported extensions for this chain ecosystem + return (Object.keys(extensions) as ExtensionTypes.ID[]).reduce( + (filteredExtensions, extensionId) => { + filteredExtensions[extensionId] = + chain && + AdvancedLogic.supportedEcosystemsForExtension[extensionId].includes(chain.ecosystem) + ? extensions[extensionId] + : undefined; + return filteredExtensions; + }, + {} as Record, + ); } public getNativeTokenExtensionForNetwork( @@ -167,23 +205,30 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic } public getFeeProxyContractErc20ForNetwork(network?: ChainTypes.IChain): FeeProxyContractErc20 { - return this.currencyManager.chainManager.ecosystems.near.isChainSupported(network) + return this.currencyManager.chainManager.ecosystems[ECOSYSTEM.NEAR].isChainSupported(network) ? new FeeProxyContractErc20(this.currencyManager, undefined, undefined, network) : this.extensions.feeProxyContractErc20; } - private getChain( + private getChainForActionAndState( extensionAction: ExtensionTypes.IAction, requestState: RequestLogicTypes.IRequest, + ecosystems: readonly ChainTypes.ECOSYSTEM[], ): ChainTypes.IChain | undefined { + // This check is only used for the "native-token" extension + // (notice the "extensionAction.parameters.paymentNetworkName" property). + // This is important because "isSameChain" throws an error + // when "extensionAction.parameters.paymentNetworkName" + // and the chain supporting "requestState.currency" + // are not part of the same ecosystem. + // This should not happen in this case. if ( requestState.currency.network && - requestState.currency.type && extensionAction.parameters.paymentNetworkName && !this.currencyManager.chainManager.isSameChain( requestState.currency.network, extensionAction.parameters.paymentNetworkName, - this.currencyManager.chainManager.getEcosystemsByCurrencyType(requestState.currency.type), + ecosystems, ) ) { throw new Error( @@ -198,6 +243,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic ?.network) || requestState.currency.network; if (!chainName) return; - return this.currencyManager.chainManager.fromName(chainName); + + return this.currencyManager.chainManager.fromName(chainName, ecosystems); } } diff --git a/packages/advanced-logic/src/extensions/abstract-extension.ts b/packages/advanced-logic/src/extensions/abstract-extension.ts index 1b545a4543..32a49522fa 100644 --- a/packages/advanced-logic/src/extensions/abstract-extension.ts +++ b/packages/advanced-logic/src/extensions/abstract-extension.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, IdentityTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + ChainTypes, + ExtensionTypes, + IdentityTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; /** @@ -6,6 +11,7 @@ import { deepCopy } from '@requestnetwork/utils'; */ export abstract class AbstractExtension implements ExtensionTypes.IExtension { protected actions: ExtensionTypes.SupportedActions; + static supportedEcosystems: ChainTypes.ECOSYSTEM[] = [ChainTypes.ECOSYSTEM.EVM]; protected constructor( public readonly extensionType: ExtensionTypes.TYPE, diff --git a/packages/advanced-logic/src/extensions/payment-network/address-based.ts b/packages/advanced-logic/src/extensions/payment-network/address-based.ts index 9441ea18dd..46b0ba653e 100644 --- a/packages/advanced-logic/src/extensions/payment-network/address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/address-based.ts @@ -154,7 +154,7 @@ export default abstract class AddressBasedPaymentNetwork< return this.isValidAddressForSymbolAndNetwork( address, 'ETH', - this.currencyManager.chainManager.fromName('mainnet', ['evm']), + this.currencyManager.chainManager.fromName('mainnet', [ChainTypes.ECOSYSTEM.EVM]), ); default: throw new Error( diff --git a/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts b/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts index 7111aca317..5a17ef2253 100644 --- a/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts +++ b/packages/advanced-logic/src/extensions/payment-network/any-to-erc20-proxy.ts @@ -42,7 +42,7 @@ export default class AnyToErc20ProxyPaymentNetwork extends Erc20FeeProxyPaymentN if (!acceptedCurrency) { throw new UnsupportedCurrencyError({ value: address, - network: network?.name, + network, }); } if (!network || !this.currencyManager.supportsConversion(acceptedCurrency, network)) { diff --git a/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts b/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts index 707e36ed63..008d7d937d 100644 --- a/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/bitcoin/mainnet-address-based.ts @@ -1,4 +1,4 @@ -import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import AddressBasedPaymentNetwork from '../address-based'; import { ICurrencyManager } from '@requestnetwork/currency'; @@ -24,7 +24,7 @@ export default class BitcoinAddressBasedPaymentNetwork extends AddressBasedPayme return this.isValidAddressForSymbolAndNetwork( address, 'BTC', - this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, ['btc']), + this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, [ChainTypes.ECOSYSTEM.BTC]), ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts b/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts index 0478879d6f..31d55c4e17 100644 --- a/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/bitcoin/testnet-address-based.ts @@ -1,5 +1,5 @@ import BitcoinAddressBasedPaymentNetwork from './mainnet-address-based'; -import { ExtensionTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes } from '@requestnetwork/types'; import { ICurrencyManager } from '@requestnetwork/currency'; const BITCOIN_NETWORK = 'testnet'; @@ -20,7 +20,7 @@ export default class BitcoinTestnetAddressBasedPaymentNetwork extends BitcoinAdd return this.isValidAddressForSymbolAndNetwork( address, 'BTC-testnet', - this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, ['btc']), + this.currencyManager.chainManager.fromName(BITCOIN_NETWORK, [ChainTypes.ECOSYSTEM.BTC]), ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts index c93211cbaf..27572f3352 100644 --- a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts +++ b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts @@ -40,12 +40,12 @@ export default class Erc20FeeProxyPaymentNetwork< chainManager: ChainManager, network?: ChainTypes.IChain | undefined, ): string { - return chainManager.ecosystems.near.isChainSupported(network) + return chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(network) ? NEAR_CURRENT_VERSION : EVM_CURRENT_VERSION; } - // Override `validate` to account for network-specific instanciation (non-EVM only) + // Override `validate` to account for network-specific instantiation (non-EVM only) protected validate( request: RequestLogicTypes.IRequest, extensionAction: ExtensionTypes.IAction, @@ -53,10 +53,11 @@ export default class Erc20FeeProxyPaymentNetwork< if ( this.network && request.currency.network && - !this.currencyManager.chainManager.isSameChain(this.network, request.currency.network, [ - 'evm', - 'near', - ]) + !this.currencyManager.chainManager.isSameChain( + this.network, + request.currency.network, + ChainTypes.VM_ECOSYSTEMS, + ) ) { throw new UnsupportedNetworkError(this.constructor.name, request.currency.network, [ this.network.name, @@ -67,18 +68,22 @@ export default class Erc20FeeProxyPaymentNetwork< // Override `isValidAddress` to account for network-specific instanciation (non-EVM only) protected isValidAddress(address: string): boolean { - if (this.currencyManager.chainManager.ecosystems['near'].isChainSupported(this.network)) { + if ( + this.currencyManager.chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported( + this.network, + ) + ) { if (this.network?.testnet) { return this.isValidAddressForSymbolAndNetwork( address, 'NEAR-testnet', - this.currencyManager.chainManager.fromName('near-testnet', ['near']), + this.currencyManager.chainManager.fromName('near-testnet', [ChainTypes.ECOSYSTEM.NEAR]), ); } else { return this.isValidAddressForSymbolAndNetwork( address, 'NEAR', - this.currencyManager.chainManager.fromName('near', ['near']), + this.currencyManager.chainManager.fromName('near', [ChainTypes.ECOSYSTEM.NEAR]), ); } } else { diff --git a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts index 791eb89589..1eda99fc1d 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near-testnet.ts @@ -1,10 +1,13 @@ import { ICurrencyManager } from '@requestnetwork/currency'; import AnyToNearPaymentNetwork from './any-to-near'; +import { ChainTypes } from '@requestnetwork/types'; export default class AnyToNearTestnetPaymentNetwork extends AnyToNearPaymentNetwork { public constructor(currencyManager: ICurrencyManager) { // testnet PN version is the same as mainnet, can be overridden here if needed - super(currencyManager, [currencyManager.chainManager.fromName('aurora-testnet', ['near'])]); + super(currencyManager, [ + currencyManager.chainManager.fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]), + ]); } /** @@ -17,7 +20,7 @@ export default class AnyToNearTestnetPaymentNetwork extends AnyToNearPaymentNetw return this.isValidAddressForSymbolAndNetwork( address, 'NEAR-testnet', - this.currencyManager.chainManager.fromName('aurora-testnet', ['near']), + this.currencyManager.chainManager.fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]), ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts index d195a185ad..f558da8594 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts @@ -19,7 +19,9 @@ export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetw currencyManager, ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_NATIVE_TOKEN, currentVersion, - supportedNetworks ?? [currencyManager.chainManager.fromName('aurora', ['near'])], + supportedNetworks ?? [ + currencyManager.chainManager.fromName('aurora', [ChainTypes.ECOSYSTEM.NEAR]), + ], ); } @@ -33,7 +35,7 @@ export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetw return this.isValidAddressForSymbolAndNetwork( address, 'NEAR', - this.currencyManager.chainManager.fromName('aurora', ['near']), + this.currencyManager.chainManager.fromName('aurora', [ChainTypes.ECOSYSTEM.NEAR]), ); } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts index d740899fd9..226d6a9fec 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/near-native.ts @@ -17,7 +17,9 @@ export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork currencyManager, ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN, currentVersion, - supportedNetworks ?? [currencyManager.chainManager.fromName('aurora', ['near'])], + supportedNetworks ?? [ + currencyManager.chainManager.fromName('aurora', [ChainTypes.ECOSYSTEM.NEAR]), + ], ); } @@ -31,7 +33,7 @@ export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork return this.isValidAddressForSymbolAndNetwork( address, 'NEAR', - this.currencyManager.chainManager.fromName('aurora', ['near']), + this.currencyManager.chainManager.fromName('aurora', [ChainTypes.ECOSYSTEM.NEAR]), ); } } diff --git a/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts b/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts index 8dd7bce066..ab7237e0a3 100644 --- a/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts +++ b/packages/advanced-logic/src/extensions/payment-network/near/near-testnet-native.ts @@ -1,5 +1,6 @@ import NearNativePaymentNetwork from './near-native'; import { ICurrencyManager } from '@requestnetwork/currency'; +import { ChainTypes } from '@requestnetwork/types'; /** * Implementation of the payment network to pay in Near on testnet based on input data. @@ -7,7 +8,9 @@ import { ICurrencyManager } from '@requestnetwork/currency'; export default class NearTestnetNativeNativePaymentNetwork extends NearNativePaymentNetwork { public constructor(currencyManager: ICurrencyManager) { // testnet PN version is the same as mainnet, can be overridden here if needed - super(currencyManager, [currencyManager.chainManager.fromName('aurora-testnet', ['near'])]); + super(currencyManager, [ + currencyManager.chainManager.fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]), + ]); } /** @@ -20,7 +23,7 @@ export default class NearTestnetNativeNativePaymentNetwork extends NearNativePay return this.isValidAddressForSymbolAndNetwork( address, 'NEAR-testnet', - this.currencyManager.chainManager.fromName('aurora-testnet', ['near']), + this.currencyManager.chainManager.fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]), ); } } diff --git a/packages/chain/src/chain-manager.ts b/packages/chain/src/chain-manager.ts index 66b5e59055..70db52fe73 100644 --- a/packages/chain/src/chain-manager.ts +++ b/packages/chain/src/chain-manager.ts @@ -10,17 +10,17 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class ChainManager { private static defaultInstance: ChainManager; - public ecosystems: Record> = { - btc: BtcEcosystem, - declarative: DeclarativeEcosystem, - evm: EvmEcosystem, - near: NearEcosystem, + public ecosystems: Record> = { + [ChainTypes.ECOSYSTEM.BTC]: BtcEcosystem, + [ChainTypes.ECOSYSTEM.DECLARATIVE]: DeclarativeEcosystem, + [ChainTypes.ECOSYSTEM.EVM]: EvmEcosystem, + [ChainTypes.ECOSYSTEM.NEAR]: NearEcosystem, }; - constructor(inputChains?: Record>) { + constructor(inputChains?: Record>) { if (!inputChains) return; for (const ecosystemName in this.ecosystems) { - const ecosystem = this.ecosystems[ecosystemName as ChainTypes.ChainEcosystem]; + const ecosystem = this.ecosystems[ecosystemName as ChainTypes.ECOSYSTEM]; if (!inputChains[ecosystem.name]) continue; const chainDefinitions = inputChains[ecosystem.name]; const chains = initializeChains(ecosystem.chainClass, chainDefinitions); @@ -34,15 +34,13 @@ export class ChainManager { get chains(): ChainTypes.IChain[] { return Object.keys(this.ecosystems).reduce((chains, ecosystemName) => { return chains.concat( - Object.values(this.ecosystems[ecosystemName as ChainTypes.ChainEcosystem].chains), + Object.values(this.ecosystems[ecosystemName as ChainTypes.ECOSYSTEM].chains), ); }, [] as ChainTypes.IChain[]); } - getEcosystemsByCurrencyType( - currencyType: RequestLogicTypes.CURRENCY, - ): ChainTypes.ChainEcosystem[] { - return (Object.keys(this.ecosystems) as ChainTypes.ChainEcosystem[]).filter((ecosystemName) => + getEcosystemsByCurrencyType(currencyType: RequestLogicTypes.CURRENCY): ChainTypes.ECOSYSTEM[] { + return (Object.keys(this.ecosystems) as ChainTypes.ECOSYSTEM[]).filter((ecosystemName) => this.ecosystems[ecosystemName].currencyType.includes(currencyType), ); } @@ -53,51 +51,49 @@ export class ChainManager { } /** - * Gets a supported chain from its name + * Gets a supported chain from its name or ID */ - fromName( - chainName: string, + protected fromGeneric( + propertyName: 'id' | 'name', + propertyValue: string, ecosystemsFilter?: T, ): ChainTypes.ChainTypeByEcosystem[T[number]] { const chains = this.chains.filter( (chain) => - chain.name === chainName && + chain[propertyName] === propertyValue && (ecosystemsFilter ? ecosystemsFilter.includes(chain.ecosystem) : true), ); if (chains.length < 1) { throw new Error( - `No chain found with name "${chainName}" for ecosystem(s) "${ecosystemsFilter}"`, + `No chain found with "${propertyName}=${propertyValue}" for ecosystem(s) "${ecosystemsFilter}"`, ); } if (chains.length > 1) { throw new Error( - `There is more than one chain named "${chainName}" for ecosystem(s) "${ecosystemsFilter}"`, + `There is more than one chain with "${propertyName}=${propertyValue}" for ecosystem(s) "${ecosystemsFilter}"`, ); } return chains[0] as ChainTypes.ChainTypeByEcosystem[T[number]]; } + /** + * Gets a supported chain from its name + */ + fromName( + chainName: string, + ecosystemsFilter?: T, + ): ChainTypes.ChainTypeByEcosystem[T[number]] { + return this.fromGeneric('name', chainName, ecosystemsFilter); + } + /** * Gets a supported chain from its ID */ - fromId( + fromId( chainId: string, ecosystemsFilter?: T, ): ChainTypes.ChainTypeByEcosystem[T[number]] { - const chains = this.chains.filter( - (chain) => - chain.id === chainId && - (ecosystemsFilter ? ecosystemsFilter.includes(chain.ecosystem) : true), - ); - if (chains.length < 1) { - throw new Error(`No chain found with ID "${chainId}" for ecosystem(s) "${ecosystemsFilter}"`); - } - if (chains.length > 1) { - throw new Error( - `There is more than one chain with ID "${chainId}" for ecosystem(s) "${ecosystemsFilter}"`, - ); - } - return chains[0] as ChainTypes.ChainTypeByEcosystem[T[number]]; + return this.fromGeneric('id', chainId, ecosystemsFilter); } static getDefault(): ChainManager { @@ -114,7 +110,7 @@ export class ChainManager { isSameChain = ( chain1: string | ChainTypes.IChain, chain2: string | ChainTypes.IChain, - chainsEcosystem?: ChainTypes.ChainEcosystem[], + chainsEcosystem?: readonly ChainTypes.ECOSYSTEM[], ): boolean => { const chain1Object = typeof chain1 === 'string' ? this.fromName(chain1, chainsEcosystem) : chain1; diff --git a/packages/chain/src/chains/btc/btc-chain.ts b/packages/chain/src/chains/btc/btc-chain.ts index b54c4778d4..87fd5bb7c0 100644 --- a/packages/chain/src/chains/btc/btc-chain.ts +++ b/packages/chain/src/chains/btc/btc-chain.ts @@ -1,7 +1,7 @@ import { ChainAbstract } from '../chain-abstract'; -import { RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class BtcChain extends ChainAbstract { - public readonly ecosystem = 'btc'; + public readonly ecosystem = ChainTypes.ECOSYSTEM.BTC; public readonly currencyType = RequestLogicTypes.CURRENCY.BTC; } diff --git a/packages/chain/src/chains/btc/btc-ecosystem.ts b/packages/chain/src/chains/btc/btc-ecosystem.ts index 2129139f75..51d12882bf 100644 --- a/packages/chain/src/chains/btc/btc-ecosystem.ts +++ b/packages/chain/src/chains/btc/btc-ecosystem.ts @@ -4,4 +4,9 @@ import { chains } from './index'; import { BtcChain } from './btc-chain'; class BtcEcosystem extends EcosystemAbstract {} -export default new BtcEcosystem('btc', BtcChain, chains, RequestLogicTypes.CURRENCY.BTC); +export default new BtcEcosystem( + ChainTypes.ECOSYSTEM.BTC, + BtcChain, + chains, + RequestLogicTypes.CURRENCY.BTC, +); diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts index dbbba8aad5..8ba2601b6d 100644 --- a/packages/chain/src/chains/chain-abstract.ts +++ b/packages/chain/src/chains/chain-abstract.ts @@ -1,9 +1,8 @@ import { ChainTypes } from '@requestnetwork/types'; -import { IChainCommon } from '@requestnetwork/types/src/chain-types'; import { RequestLogicTypes } from '@requestnetwork/types/src'; export abstract class ChainAbstract implements ChainTypes.IChainCommon { - public declare readonly ecosystem: ChainTypes.ChainEcosystem; + public declare readonly ecosystem: ChainTypes.ECOSYSTEM; public declare readonly currencyType: RequestLogicTypes.CURRENCY; constructor( diff --git a/packages/chain/src/chains/declarative/declarative-chain.ts b/packages/chain/src/chains/declarative/declarative-chain.ts index be34b05ccf..483b407aa7 100644 --- a/packages/chain/src/chains/declarative/declarative-chain.ts +++ b/packages/chain/src/chains/declarative/declarative-chain.ts @@ -2,6 +2,6 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { ChainAbstract } from '../chain-abstract'; export class DeclarativeChain extends ChainAbstract implements ChainTypes.IDeclarativeChain { - public readonly ecosystem = 'declarative'; + public readonly ecosystem = ChainTypes.ECOSYSTEM.DECLARATIVE; public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/declarative/declarative-ecosystem.ts b/packages/chain/src/chains/declarative/declarative-ecosystem.ts index b3efbb7f1a..cd9e816157 100644 --- a/packages/chain/src/chains/declarative/declarative-ecosystem.ts +++ b/packages/chain/src/chains/declarative/declarative-ecosystem.ts @@ -5,7 +5,12 @@ import { chains } from './index'; class DeclarativeEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super('declarative', DeclarativeChain, chains, RequestLogicTypes.CURRENCY.ETH); + super( + ChainTypes.ECOSYSTEM.DECLARATIVE, + DeclarativeChain, + chains, + RequestLogicTypes.CURRENCY.ETH, + ); } } diff --git a/packages/chain/src/chains/ecosystem-abstract.ts b/packages/chain/src/chains/ecosystem-abstract.ts index 7129c52886..f200d11d7f 100644 --- a/packages/chain/src/chains/ecosystem-abstract.ts +++ b/packages/chain/src/chains/ecosystem-abstract.ts @@ -3,7 +3,7 @@ import { ChainAbstract } from './chain-abstract'; export abstract class EcosystemAbstract { constructor( - public name: ChainTypes.ChainEcosystem, + public name: ChainTypes.ECOSYSTEM, public chainClass: new (id: string, name: string, testnet?: boolean) => CHAIN, public chains: Record, public currencyType: RequestLogicTypes.CURRENCY, diff --git a/packages/chain/src/chains/evm/evm-chain.ts b/packages/chain/src/chains/evm/evm-chain.ts index 7a45f5e190..af7cc60ff2 100644 --- a/packages/chain/src/chains/evm/evm-chain.ts +++ b/packages/chain/src/chains/evm/evm-chain.ts @@ -2,6 +2,6 @@ import { ChainAbstract } from '../chain-abstract'; import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class EvmChain extends ChainAbstract implements ChainTypes.IEvmChain { - public readonly ecosystem = 'evm'; + public readonly ecosystem = ChainTypes.ECOSYSTEM.EVM; public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/evm/evm-ecosystem.ts b/packages/chain/src/chains/evm/evm-ecosystem.ts index 4c3e2f9e26..7e14a23cef 100644 --- a/packages/chain/src/chains/evm/evm-ecosystem.ts +++ b/packages/chain/src/chains/evm/evm-ecosystem.ts @@ -5,7 +5,7 @@ import { EvmChain } from './evm-chain'; class EvmEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super('evm', EvmChain, chains, RequestLogicTypes.CURRENCY.ETH); + super(ChainTypes.ECOSYSTEM.EVM, EvmChain, chains, RequestLogicTypes.CURRENCY.ETH); } } diff --git a/packages/chain/src/chains/near/near-chain.ts b/packages/chain/src/chains/near/near-chain.ts index 34a2bdf9b7..c23e8e4dce 100644 --- a/packages/chain/src/chains/near/near-chain.ts +++ b/packages/chain/src/chains/near/near-chain.ts @@ -2,6 +2,6 @@ import { ChainAbstract } from '../chain-abstract'; import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; export class NearChain extends ChainAbstract implements ChainTypes.INearChain { - public readonly ecosystem = 'near'; + public readonly ecosystem = ChainTypes.ECOSYSTEM.NEAR; public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/near/near-ecosystem.ts b/packages/chain/src/chains/near/near-ecosystem.ts index d019bad618..d6744a8e3b 100644 --- a/packages/chain/src/chains/near/near-ecosystem.ts +++ b/packages/chain/src/chains/near/near-ecosystem.ts @@ -5,7 +5,7 @@ import { NearChain } from './near-chain'; class NearEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super('near', NearChain, chains, RequestLogicTypes.CURRENCY.ETH); + super(ChainTypes.ECOSYSTEM.NEAR, NearChain, chains, RequestLogicTypes.CURRENCY.ETH); } } diff --git a/packages/currency/src/currency-manager.ts b/packages/currency/src/currency-manager.ts index 813be48d85..8cb894125b 100644 --- a/packages/currency/src/currency-manager.ts +++ b/packages/currency/src/currency-manager.ts @@ -264,7 +264,9 @@ export class CurrencyManager implements ICurrencyManager case RequestLogicTypes.CURRENCY.ETH: case RequestLogicTypes.CURRENCY.ERC20: case RequestLogicTypes.CURRENCY.ERC777: - if (this.chainManager.ecosystems.near.isChainSupported(currency.network)) { + if ( + this.chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(currency.network) + ) { return isValidNearAddress(address, currency.network); } else if (currency.network === 'tron' || currency.network === 'solana') { return addressValidator.validate(address, currency.network); @@ -306,7 +308,6 @@ export class CurrencyManager implements ICurrencyManager */ static getDefaultList(): CurrencyDefinition[] { return ([] as CurrencyInput[]) - .concat(getSupportedNativeCurrencies()) .concat(getSupportedNativeCurrencies()) .concat(getSupportedERC20Currencies()) .concat(getSupportedERC777Currencies()) diff --git a/packages/ethereum-storage/src/config.ts b/packages/ethereum-storage/src/config.ts index a8a1144670..e597909e0a 100644 --- a/packages/ethereum-storage/src/config.ts +++ b/packages/ethereum-storage/src/config.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, StorageTypes } from '@requestnetwork/types'; +import { StorageTypes } from '@requestnetwork/types'; import { BigNumber } from 'ethers'; // This contains default values used to use Ethereum Network and IPFS @@ -63,7 +63,7 @@ export function getDefaultEthereumProviderTimeout(): number { * Retrieve from config the default name of the network for Ethereum * @returns the name of the network */ -export function getDefaultEthereumNetwork(): ChainTypes.IEvmChain { +export function getDefaultEthereumNetwork(): string { return config.ethereum.default; } diff --git a/packages/ethereum-storage/src/ethereum-tx-submitter.ts b/packages/ethereum-storage/src/ethereum-tx-submitter.ts index 2665f43b8a..b6b4f7c30a 100644 --- a/packages/ethereum-storage/src/ethereum-tx-submitter.ts +++ b/packages/ethereum-storage/src/ethereum-tx-submitter.ts @@ -1,5 +1,5 @@ import { BigNumber, ContractTransaction, providers, Signer, utils } from 'ethers'; -import { CurrencyTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; +import { LogTypes, StorageTypes } from '@requestnetwork/types'; import { requestHashSubmitterArtifact } from '@requestnetwork/smart-contracts'; import { RequestOpenHashSubmitter } from '@requestnetwork/smart-contracts/types'; import { GasFeeDefiner } from './gas-fee-definer'; @@ -22,7 +22,7 @@ export type SubmitterProps = { * The default is 100, which does not change the value (100 is equal to x1, 200 is equal to x2). */ gasPriceMultiplier?: number; - network: ChainTypes.IEvmChain; + network: string; logger?: LogTypes.ILogger; debugProvider?: boolean; }; diff --git a/packages/payment-detection/src/any-to-any-detector.ts b/packages/payment-detection/src/any-to-any-detector.ts index 1e135712fc..67ea8ce20e 100644 --- a/packages/payment-detection/src/any-to-any-detector.ts +++ b/packages/payment-detection/src/any-to-any-detector.ts @@ -1,4 +1,4 @@ -import { ExtensionTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes } from '@requestnetwork/types'; import { FeeReferenceBasedDetector } from './fee-reference-based-detector'; import { ICurrencyManager } from '@requestnetwork/currency'; import { generate8randomBytes } from '@requestnetwork/utils'; @@ -17,8 +17,9 @@ export abstract class AnyToAnyDetector< paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, extension: TExtension, currencyManager: ICurrencyManager, + allowedEcosystems: ChainTypes.ECOSYSTEM[], ) { - super(paymentNetworkId, extension, currencyManager); + super(paymentNetworkId, extension, currencyManager, allowedEcosystems); } /** diff --git a/packages/payment-detection/src/any-to-native-detector.ts b/packages/payment-detection/src/any-to-native-detector.ts index 1174431174..95d45c9921 100644 --- a/packages/payment-detection/src/any-to-native-detector.ts +++ b/packages/payment-detection/src/any-to-native-detector.ts @@ -1,4 +1,4 @@ -import { ExtensionTypes, PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes } from '@requestnetwork/types'; import { AnyToAnyDetector } from './any-to-any-detector'; import { NativeDetectorOptions } from './types'; @@ -18,6 +18,6 @@ export abstract class AnyToNativeDetector extends AnyToAnyDetector< if (!extension) { throw new Error(`the ${extensionId} extension is not supported for the network ${network}`); } - super(extensionId, extension, currencyManager); + super(extensionId, extension, currencyManager, [ChainTypes.ECOSYSTEM.NEAR]); } } diff --git a/packages/payment-detection/src/any/any-to-erc20-proxy.ts b/packages/payment-detection/src/any/any-to-erc20-proxy.ts index d55c6b3a1b..28709e13c2 100644 --- a/packages/payment-detection/src/any/any-to-erc20-proxy.ts +++ b/packages/payment-detection/src/any/any-to-erc20-proxy.ts @@ -1,17 +1,11 @@ import { erc20ConversionProxy } from '@requestnetwork/smart-contracts'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { ERC20FeeProxyPaymentDetectorBase } from '../erc20/fee-proxy-contract'; import { AnyToErc20InfoRetriever } from './retrievers/any-to-erc20-proxy'; import { TheGraphConversionInfoRetriever } from '../thegraph/conversion-info-retriever'; import { makeGetDeploymentInformation } from '../utils'; import { PaymentNetworkOptions, ReferenceBasedDetectorOptions, TGetSubGraphClient } from '../types'; import { generate8randomBytes } from '@requestnetwork/utils'; -import { EvmChains } from '@requestnetwork/currency'; const PROXY_CONTRACT_ADDRESS_MAP = { ['0.1.0']: '0.1.0', @@ -26,10 +20,6 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< > { private readonly getSubgraphClient: TGetSubGraphClient; - /** - * @param extension The advanced logic payment network extensions - */ - public constructor({ advancedLogic, currencyManager, @@ -146,8 +136,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } - EvmChains.assertChainSupported(network); - return network; + return this.currencyManager.chainManager.fromName(network, [ChainTypes.ECOSYSTEM.EVM]); } public static getDeploymentInformation = makeGetDeploymentInformation( diff --git a/packages/payment-detection/src/any/any-to-eth-proxy.ts b/packages/payment-detection/src/any/any-to-eth-proxy.ts index e3b14c6573..e7b3ff62d8 100644 --- a/packages/payment-detection/src/any/any-to-eth-proxy.ts +++ b/packages/payment-detection/src/any/any-to-eth-proxy.ts @@ -1,12 +1,7 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { UnsupportedCurrencyError } from '@requestnetwork/currency'; import { AnyToEthInfoRetriever } from './retrievers/any-to-eth-proxy'; import { AnyToAnyDetector } from '../any-to-any-detector'; @@ -45,6 +40,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY, advancedLogic.extensions.anyToEthProxy, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); this.getSubgraphClient = getSubgraphClient; } @@ -132,8 +128,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } - EvmChains.assertChainSupported(network); - return network; + return this.currencyManager.chainManager.fromName(network, [ChainTypes.ECOSYSTEM.EVM]); } /* diff --git a/packages/payment-detection/src/any/retrievers/any-to-any-proxy.ts b/packages/payment-detection/src/any/retrievers/any-to-any-proxy.ts index 3963d2949a..2f665ac516 100644 --- a/packages/payment-detection/src/any/retrievers/any-to-any-proxy.ts +++ b/packages/payment-detection/src/any/retrievers/any-to-any-proxy.ts @@ -1,5 +1,5 @@ import { CurrencyDefinition } from '@requestnetwork/currency'; -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { BigNumber, ethers } from 'ethers'; import { parseLogArgs, unpadAmountFromChainlink } from '../../utils'; import type { JsonFragment } from '@ethersproject/abi'; @@ -48,7 +48,7 @@ export abstract class ConversionInfoRetriever { protected conversionProxyContractAbiFragment: JsonFragment[], protected toAddress: string, protected eventName: PaymentTypes.EVENTS_NAMES, - protected network: string, + protected network: ChainTypes.IChain, protected acceptedTokens?: string[], protected maxRateTimespan: number = 0, ) { diff --git a/packages/payment-detection/src/erc20/currency.ts b/packages/payment-detection/src/erc20/currency.ts index a8d938a673..f14fc47e54 100644 --- a/packages/payment-detection/src/erc20/currency.ts +++ b/packages/payment-detection/src/erc20/currency.ts @@ -1,7 +1,6 @@ import { CurrencyDefinition, CurrencyManager, - EvmChains, getCurrencyHash, StorageCurrency, } from '@requestnetwork/currency'; @@ -20,7 +19,6 @@ export const loadCurrencyFromContract = async ( if (!network || !isAddress(value)) { return null; } - EvmChains.assertChainSupported(network); const contract = ERC20__factory.connect(value, getDefaultProvider(network)); const decimals = await contract.decimals(); diff --git a/packages/payment-detection/src/erc20/escrow-info-retriever.ts b/packages/payment-detection/src/erc20/escrow-info-retriever.ts index 2f128d97e8..30c647260a 100644 --- a/packages/payment-detection/src/erc20/escrow-info-retriever.ts +++ b/packages/payment-detection/src/erc20/escrow-info-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { erc20EscrowToPayArtifact } from '@requestnetwork/smart-contracts'; import { BigNumber, ethers } from 'ethers'; import { IEventRetriever } from '../types'; @@ -51,7 +51,7 @@ export class EscrowERC20InfoRetriever private escrowCreationBlockNumber: number, private tokenContractAddress: string, private toAddress: string, - private network: string, + private network: ChainTypes.IEvmChain, private eventName?: PaymentTypes.ESCROW_EVENTS_NAMES, ) { // Creates a local or default provider. diff --git a/packages/payment-detection/src/erc20/fee-proxy-contract.ts b/packages/payment-detection/src/erc20/fee-proxy-contract.ts index ffec1e5576..7640db8c6b 100644 --- a/packages/payment-detection/src/erc20/fee-proxy-contract.ts +++ b/packages/payment-detection/src/erc20/fee-proxy-contract.ts @@ -7,7 +7,11 @@ import { loadCurrencyFromContract } from './currency'; import { FeeReferenceBasedDetector } from '../fee-reference-based-detector'; import { makeGetDeploymentInformation } from '../utils'; import { TheGraphClient, TheGraphInfoRetriever } from '../thegraph'; -import { ReferenceBasedDetectorOptions, TGetSubGraphClient } from '../types'; +import { + ITheGraphBaseInfoRetriever, + ReferenceBasedDetectorOptions, + TGetSubGraphClient, +} from '../types'; import { NearInfoRetriever } from '../near'; import { NetworkNotSupported } from '../balance-error'; @@ -33,7 +37,7 @@ export abstract class ERC20FeeProxyPaymentDetectorBase< extension: TExtension, currencyManager: ICurrencyManager, ) { - super(paymentNetworkId, extension, currencyManager); + super(paymentNetworkId, extension, currencyManager, ChainTypes.VM_ECOSYSTEMS); } protected async getCurrency( @@ -77,6 +81,7 @@ export class ERC20FeeProxyPaymentDetector< > { private readonly getSubgraphClient: TGetSubGraphClient; protected readonly network: TChain | undefined; + constructor({ advancedLogic, currencyManager, @@ -121,54 +126,49 @@ export class ERC20FeeProxyPaymentDetector< const { address: proxyContractAddress, creationBlockNumber: proxyCreationBlockNumber } = ERC20FeeProxyPaymentDetector.getDeploymentInformation(paymentChain, paymentNetwork.version); - const subgraphClient = this.getSubgraphClient(paymentChain); - if (subgraphClient) { - const graphInfoRetriever = this.getTheGraphInfoRetriever(paymentChain, subgraphClient); + // with TheGraph + const graphInfoRetriever = this.getTheGraphInfoRetriever(paymentChain); + if (graphInfoRetriever) { return graphInfoRetriever.getTransferEvents({ eventName, paymentReference, toAddress, contractAddress: proxyContractAddress, - paymentChain, acceptedTokens: [requestCurrency.value], - }); - } else { - if (paymentChain.ecosystem !== 'evm') { - throw new Error( - `Could not get a TheGraph-based info retriever for chain ${paymentChain} and RPC-based info retrievers are only compatible with EVM chains.`, - ); - } - const proxyInfoRetriever = new ProxyInfoRetriever( - paymentReference, - proxyContractAddress, - proxyCreationBlockNumber, - requestCurrency.value, - toAddress, - eventName, paymentChain, + }); + } + + if (paymentChain.ecosystem !== ChainTypes.ECOSYSTEM.EVM) { + throw new Error( + `Could not get a TheGraph-based info retriever for chain ${paymentChain} and RPC-based info retrievers are only compatible with EVM chains.`, ); - const paymentEvents = await proxyInfoRetriever.getTransferEvents(); - return { - paymentEvents, - }; } + + // without TheGraph + const proxyInfoRetriever = new ProxyInfoRetriever( + paymentReference, + proxyContractAddress, + proxyCreationBlockNumber, + requestCurrency.value, + toAddress, + eventName, + paymentChain, + ); + const paymentEvents = await proxyInfoRetriever.getTransferEvents(); + return { + paymentEvents, + }; } protected getTheGraphInfoRetriever( paymentChain: TChain, - subgraphClient: TheGraphClient | TheGraphClient, - ): TheGraphInfoRetriever | NearInfoRetriever { - const graphInfoRetriever = - paymentChain.ecosystem === 'evm' - ? new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager) - : paymentChain.ecosystem === 'near' && this.network + ): ITheGraphBaseInfoRetriever | undefined { + const subgraphClient = this.getSubgraphClient(paymentChain); + return subgraphClient + ? paymentChain.ecosystem === ChainTypes.ECOSYSTEM.NEAR ? new NearInfoRetriever(subgraphClient as TheGraphClient) - : undefined; - if (!graphInfoRetriever) { - throw new Error( - `Could not find graphInfoRetriever for chain ${paymentChain} in payment detector`, - ); - } - return graphInfoRetriever; + : new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager) + : undefined; } } diff --git a/packages/payment-detection/src/erc20/proxy-contract.ts b/packages/payment-detection/src/erc20/proxy-contract.ts index 8076c61ff2..4e3b7e05c9 100644 --- a/packages/payment-detection/src/erc20/proxy-contract.ts +++ b/packages/payment-detection/src/erc20/proxy-contract.ts @@ -1,9 +1,4 @@ -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { erc20ProxyArtifact } from '@requestnetwork/smart-contracts'; import ProxyInfoRetriever from './proxy-info-retriever'; import { TheGraphInfoRetriever } from '../thegraph'; @@ -37,6 +32,7 @@ export class ERC20ProxyPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_PROXY_CONTRACT, advancedLogic.extensions.proxyContractErc20, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); this.getSubgraphClient = getSubgraphClient; } diff --git a/packages/payment-detection/src/erc20/transferable-receivable.ts b/packages/payment-detection/src/erc20/transferable-receivable.ts index 88ab4e62c9..7ae5b56a31 100644 --- a/packages/payment-detection/src/erc20/transferable-receivable.ts +++ b/packages/payment-detection/src/erc20/transferable-receivable.ts @@ -1,9 +1,4 @@ -import { - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, - CurrencyTypes, -} from '@requestnetwork/types'; +import { ExtensionTypes, PaymentTypes, RequestLogicTypes, ChainTypes } from '@requestnetwork/types'; import { TheGraphInfoRetriever } from '../thegraph'; import { erc20TransferableReceivableArtifact } from '@requestnetwork/smart-contracts'; @@ -39,6 +34,7 @@ export class ERC20TransferableReceivablePaymentDetector extends FeeReferenceBase ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE, advancedLogic.extensions.erc20TransferableReceivable, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); this.getSubgraphClient = getSubgraphClient; } diff --git a/packages/payment-detection/src/erc777/superfluid-detector.ts b/packages/payment-detection/src/erc777/superfluid-detector.ts index fb7eebfe7f..109367a151 100644 --- a/packages/payment-detection/src/erc777/superfluid-detector.ts +++ b/packages/payment-detection/src/erc777/superfluid-detector.ts @@ -19,6 +19,7 @@ export class SuperFluidPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PAYMENT_NETWORK_ID.ERC777_STREAM, advancedLogic.extensions.erc777Stream, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); } diff --git a/packages/payment-detection/src/eth/fee-proxy-detector.ts b/packages/payment-detection/src/eth/fee-proxy-detector.ts index e07edec462..2805e8de2d 100644 --- a/packages/payment-detection/src/eth/fee-proxy-detector.ts +++ b/packages/payment-detection/src/eth/fee-proxy-detector.ts @@ -1,10 +1,5 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { EthProxyInfoRetriever } from './proxy-info-retriever'; import { FeeReferenceBasedDetector } from '../fee-reference-based-detector'; @@ -43,6 +38,7 @@ export class EthFeeProxyPaymentDetector extends FeeReferenceBasedDetector< ExtensionTypes.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT, advancedLogic.extensions.feeProxyContractEth, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); this.getSubgraphClient = getSubgraphClient; } diff --git a/packages/payment-detection/src/eth/info-retriever.ts b/packages/payment-detection/src/eth/info-retriever.ts index 689ab80802..24f56b921b 100644 --- a/packages/payment-detection/src/eth/info-retriever.ts +++ b/packages/payment-detection/src/eth/info-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { IPaymentRetriever } from '../types'; import { MultichainExplorerApiProvider } from './multichainExplorerApiProvider'; @@ -18,18 +18,18 @@ export class EthInputDataInfoRetriever constructor( private toAddress: string, private eventName: PaymentTypes.EVENTS_NAMES, - private network: string, + private network: ChainTypes.IChain, private paymentReference: string, private explorerApiKey?: string, ) {} public async getTransferEvents(): Promise { - if (this.network === 'private') { + if (this.network.name === 'private') { throw new Error( 'ETH input data info-retriever works with etherscan and cannot work on a local network', ); } - const provider = new MultichainExplorerApiProvider(this.network, this.explorerApiKey); + const provider = new MultichainExplorerApiProvider(this.network.name, this.explorerApiKey); const history = await provider.getHistory(this.toAddress); const events = history diff --git a/packages/payment-detection/src/eth/input-data.ts b/packages/payment-detection/src/eth/input-data.ts index f6bcc2f1ff..c4d3aea52e 100644 --- a/packages/payment-detection/src/eth/input-data.ts +++ b/packages/payment-detection/src/eth/input-data.ts @@ -1,10 +1,5 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { EthInputDataInfoRetriever } from './info-retriever'; import { EthProxyInfoRetriever } from './proxy-info-retriever'; import { ReferenceBasedDetector } from '../reference-based-detector'; @@ -31,7 +26,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PnReferenceBased.IReferenceBased, PaymentTypes.IETHPaymentEventParameters > { - private explorerApiKeys: Partial>; + private explorerApiKeys: Partial>; private readonly getSubgraphClient: TGetSubGraphClient; /** @@ -48,6 +43,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA, advancedLogic.extensions.ethereumInputData, currencyManager, + [ChainTypes.ECOSYSTEM.EVM], ); this.explorerApiKeys = explorerApiKeys || {}; this.getSubgraphClient = getSubgraphClient; @@ -85,7 +81,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< eventName, paymentChain, paymentReference, - this.explorerApiKeys[paymentChain], + this.explorerApiKeys[paymentChain.name], ); const events = await infoRetriever.getTransferEvents(); const proxyContractArtifact = EthInputDataPaymentDetector.getDeploymentInformation( diff --git a/packages/payment-detection/src/eth/proxy-info-retriever.ts b/packages/payment-detection/src/eth/proxy-info-retriever.ts index 789cefdd23..6b4ba92fb3 100644 --- a/packages/payment-detection/src/eth/proxy-info-retriever.ts +++ b/packages/payment-detection/src/eth/proxy-info-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { IPaymentRetriever } from '../types'; import { BigNumber, ethers } from 'ethers'; import { parseLogArgs } from '../utils'; @@ -46,7 +46,7 @@ export class EthProxyInfoRetriever private proxyCreationBlockNumber: number, private toAddress: string, private eventName: PaymentTypes.EVENTS_NAMES, - private network: string, + private network: ChainTypes.IChain, ) { // Creates a local or default provider this.provider = getDefaultProvider(this.network); diff --git a/packages/payment-detection/src/fee-reference-based-detector.ts b/packages/payment-detection/src/fee-reference-based-detector.ts index 1922c65633..40d56b3601 100644 --- a/packages/payment-detection/src/fee-reference-based-detector.ts +++ b/packages/payment-detection/src/fee-reference-based-detector.ts @@ -1,5 +1,5 @@ import { BigNumber } from 'ethers'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { ICurrencyManager } from '@requestnetwork/currency'; import { ReferenceBasedDetector } from './reference-based-detector'; import { generate8randomBytes } from '@requestnetwork/utils'; @@ -22,8 +22,9 @@ export abstract class FeeReferenceBasedDetector< paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, extension: TExtension, currencyManager: ICurrencyManager, + allowedEcosystems: readonly ChainTypes.ECOSYSTEM[], ) { - super(paymentNetworkId, extension, currencyManager); + super(paymentNetworkId, extension, currencyManager, allowedEcosystems); } /** diff --git a/packages/payment-detection/src/native-token-detector.ts b/packages/payment-detection/src/native-token-detector.ts index 13a1cb6791..1bdcd226dd 100644 --- a/packages/payment-detection/src/native-token-detector.ts +++ b/packages/payment-detection/src/native-token-detector.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, ExtensionTypes, PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes } from '@requestnetwork/types'; import { ReferenceBasedDetector } from './reference-based-detector'; import { NativeDetectorOptions } from './types'; @@ -25,7 +25,7 @@ export abstract class NativeTokenPaymentDetector extends ReferenceBasedDetector< if (!extension) { throw new Error(`the ${extensionId} extension is not supported for the network ${network}`); } - super(extensionId, extension, currencyManager); + super(extensionId, extension, currencyManager, [ChainTypes.ECOSYSTEM.NEAR]); this.getSubgraphClient = getSubgraphClient; this.network = network; } diff --git a/packages/payment-detection/src/near/near-conversion-detector.ts b/packages/payment-detection/src/near/near-conversion-detector.ts index b5ea01888b..8d1dc014b4 100644 --- a/packages/payment-detection/src/near/near-conversion-detector.ts +++ b/packages/payment-detection/src/near/near-conversion-detector.ts @@ -1,10 +1,5 @@ -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; -import { NearChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { UnsupportedCurrencyError } from '@requestnetwork/currency'; import { NearConversionInfoRetriever } from './retrievers/near-conversion-info-retriever'; import { AnyToNativeDetector } from '../any-to-native-detector'; import { NetworkNotSupported } from '../balance-error'; @@ -31,12 +26,12 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto } public static getContractName = ( - chainName: ChainTypes.INearChain, + chain: ChainTypes.INearChain, paymentNetworkVersion = '0.1.0', ): string => { const version = NearConversionNativeTokenPaymentDetector.getVersionOrThrow(paymentNetworkVersion); - const versionMap: Record> = { + const versionMap: Record> = { aurora: { '0.1.0': 'native.conversion.reqnetwork.near' }, near: { '0.1.0': 'native.conversion.reqnetwork.near' }, 'aurora-testnet': { @@ -46,11 +41,11 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto '0.1.0': 'native.conversion.reqnetwork.testnet', }, }; - if (versionMap[chainName]?.[version]) { - return versionMap[chainName][version]; + if (versionMap[chain.name]?.[version]) { + return versionMap[chain.name][version]; } throw new NetworkNotSupported( - `Unconfigured near-conversion-detector chain '${chainName}' and version '${version}'`, + `Unconfigured near-conversion-detector chain '${chain.name}' and version '${version}'`, ); }; @@ -109,8 +104,7 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } - NearChains.assertChainSupported(network); - return network; + return this.currencyManager.chainManager.fromName(network, [ChainTypes.ECOSYSTEM.NEAR]); } protected static getVersionOrThrow = (paymentNetworkVersion: string): string => { diff --git a/packages/payment-detection/src/near/near-detector.ts b/packages/payment-detection/src/near/near-detector.ts index 3d26154ffc..5a547129ed 100644 --- a/packages/payment-detection/src/near/near-detector.ts +++ b/packages/payment-detection/src/near/near-detector.ts @@ -1,9 +1,4 @@ -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { NearInfoRetriever } from './retrievers/near-info-retriever'; import { NativeTokenPaymentDetector } from '../native-token-detector'; import { NetworkNotSupported } from '../balance-error'; @@ -33,7 +28,7 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { paymentNetworkVersion = '0.2.0', ): string => { const version = NearNativeTokenPaymentDetector.getVersionOrThrow(paymentNetworkVersion); - const versionMap: Record> = { + const versionMap: Record> = { aurora: { '0.1.0': 'requestnetwork.near', '0.2.0': 'requestnetwork.near' }, near: { '0.1.0': 'requestnetwork.near', '0.2.0': 'requestnetwork.near' }, 'aurora-testnet': { @@ -45,8 +40,8 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { '0.2.0': 'dev-1631521265288-35171138540673', }, }; - if (versionMap[chainName]?.[version]) { - return versionMap[chainName][version]; + if (versionMap[chainName.name]?.[version]) { + return versionMap[chainName.name][version]; } throw new NetworkNotSupported( `Unconfigured near-detector chain '${chainName}' and version '${version}'`, diff --git a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts index dd83ba3169..5315e58215 100644 --- a/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-conversion-info-retriever.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, PaymentTypes } from '@requestnetwork/types'; +import { ChainTypes, PaymentTypes } from '@requestnetwork/types'; import { CurrencyDefinition } from '@requestnetwork/currency'; import { NearInfoRetriever, NearPaymentEvent } from './near-info-retriever'; import { TheGraphClient } from '../../thegraph'; @@ -13,7 +13,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: ChainTypes.IVmChain; + paymentChain: ChainTypes.INearChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The maximum span between the time the rate was fetched and the payment */ @@ -24,12 +24,6 @@ export type TransferEventsParams = { * Gets a list of transfer events for a set of Near payment details */ export class NearConversionInfoRetriever extends NearInfoRetriever { - /** - * @param paymentReference The reference to identify the payment - * @param toAddress Address to check - * @param eventName Indicate if it is an address for payment or refund - * @param network The id of network we want to check - */ constructor(protected readonly client: TheGraphClient) { super(client); } diff --git a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts index 10d73868de..437e78da0b 100644 --- a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts @@ -16,7 +16,7 @@ export type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: ChainTypes.IVmChain; + paymentChain: ChainTypes.INearChain; /** Indicates if it is an address for payment or refund */ eventName: PaymentTypes.EVENTS_NAMES; /** The list of ERC20 tokens addresses accepted for payments and refunds. Set to `undefined` for payments in NEAR token. */ diff --git a/packages/payment-detection/src/payment-network-factory.ts b/packages/payment-detection/src/payment-network-factory.ts index 326536a723..61da3a4c27 100644 --- a/packages/payment-detection/src/payment-network-factory.ts +++ b/packages/payment-detection/src/payment-network-factory.ts @@ -1,6 +1,6 @@ import { AdvancedLogicTypes, - CurrencyTypes, + ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes, @@ -27,11 +27,13 @@ import { NearConversionNativeTokenPaymentDetector, NearNativeTokenPaymentDetecto import { getPaymentNetworkExtension } from './utils'; import { defaultGetTheGraphClient } from './thegraph'; import { getDefaultProvider } from 'ethers'; +import { AdvancedLogic } from '@requestnetwork/advanced-logic'; const PN_ID = ExtensionTypes.PAYMENT_NETWORK_ID; /** Register the payment network by currency and type */ const supportedPaymentNetwork: ISupportedPaymentNetworkByCurrency = { + ISO4217: {}, BTC: { mainnet: { [PN_ID.BITCOIN_ADDRESS_BASED]: BtcMainnetAddressBasedDetector, @@ -117,18 +119,21 @@ export class PaymentNetworkFactory { * * @param paymentNetworkId the ID of the payment network to instantiate * @param currencyType the currency type of the request - * @param paymentChain Different from request.currency.network for on-chain conversion payment networks (any-to-something) + * @param paymentChainName Different from request.currency.network for on-chain conversion payment networks (any-to-something) * @returns the module to handle the payment network */ public createPaymentNetwork( paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, currencyType: RequestLogicTypes.CURRENCY, - paymentChain?: ChainTypes.IChain, + paymentChainName?: string, paymentNetworkVersion?: string, ): PaymentTypes.IPaymentNetwork { - const network = paymentChain ?? 'mainnet'; + const paymentChain = this.currencyManager.chainManager.fromName( + paymentChainName ?? 'mainnet', + AdvancedLogic.supportedEcosystemsForExtension[paymentNetworkId], + ); const currencyPaymentMap = - supportedPaymentNetwork[currencyType]?.[network] || + supportedPaymentNetwork[currencyType]?.[paymentChain.name] || supportedPaymentNetwork[currencyType]?.['*'] || {}; const paymentNetworkMap = { @@ -140,12 +145,12 @@ export class PaymentNetworkFactory { if (!detectorClass) { throw new Error( - `the payment network id: ${paymentNetworkId} is not supported for the currency: ${currencyType} on network ${network}`, + `the extension id: ${paymentNetworkId} is not supported for the currency: ${currencyType} on network ${paymentChain.name}`, ); } const detector = new detectorClass({ - network, + network: paymentChain, advancedLogic: this.advancedLogic, currencyManager: this.currencyManager, ...this.options, @@ -154,7 +159,7 @@ export class PaymentNetworkFactory { if (detector.extension && 'getDeploymentInformation' in detectorClass) { // this throws when the contract isn't deployed and was mandatory for payment detection (detectorClass as ContractBasedDetector).getDeploymentInformation( - network as ChainTypes.IVmChain, + paymentChain as ChainTypes.IVmChain, paymentNetworkVersion || detector.extension.currentVersion, ); } diff --git a/packages/payment-detection/src/reference-based-detector.ts b/packages/payment-detection/src/reference-based-detector.ts index 580c162196..c65aae41ac 100644 --- a/packages/payment-detection/src/reference-based-detector.ts +++ b/packages/payment-detection/src/reference-based-detector.ts @@ -1,5 +1,5 @@ import { - CurrencyTypes, + ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes, @@ -25,11 +25,13 @@ export abstract class ReferenceBasedDetector< * @param paymentNetworkId Example : ExtensionTypes.PAYMENT_NETWORK_ID.ETH_INPUT_DATA * @param extension The advanced logic payment network extension, reference based * @param currencyManager The currency manager + * @param allowedEcosystems The ecosystems that this payment detector supports */ protected constructor( paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, extension: TExtension, protected readonly currencyManager: ICurrencyManager, + protected readonly allowedEcosystems: readonly ChainTypes.ECOSYSTEM[], ) { super(paymentNetworkId, extension); if (!TypesUtils.isPaymentNetworkId(paymentNetworkId)) { @@ -162,7 +164,7 @@ export abstract class ReferenceBasedDetector< if (!network) { throw Error(`request.currency.network must be defined for ${this.paymentNetworkId}`); } - return network; + return this.currencyManager.chainManager.fromName(network, this.allowedEcosystems); } protected getPaymentReference(request: RequestLogicTypes.IRequest): string { diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index 9b0428768d..e302b57e11 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { GraphQLClient } from 'graphql-request'; -import { Block_Height, Maybe, getSdk } from './generated/graphql'; +import { Block_Height, getSdk, Maybe } from './generated/graphql'; import { getSdk as getNearSdk } from './generated/graphql-near'; import { RequestConfig } from 'graphql-request/src/types'; import { ChainTypes } from '@requestnetwork/types'; @@ -68,7 +68,7 @@ export const getTheGraphClient = ( url: string, options?: TheGraphClientOptions, ) => - chain.ecosystem === 'near' + chain.ecosystem === ChainTypes.ECOSYSTEM.NEAR ? getTheGraphNearClient(url, options) : getTheGraphEvmClient(url, options); @@ -94,7 +94,7 @@ export const defaultGetTheGraphClient = ( ) => { return chain.name === 'private' ? undefined - : chain.ecosystem === 'near' + : chain.ecosystem === ChainTypes.ECOSYSTEM.NEAR ? getTheGraphNearClient( `${HOSTED_THE_GRAPH_URL}${chain.name.replace('aurora', 'near')}`, options, diff --git a/packages/payment-detection/src/types.ts b/packages/payment-detection/src/types.ts index fb6e0308be..ed39a71ac7 100644 --- a/packages/payment-detection/src/types.ts +++ b/packages/payment-detection/src/types.ts @@ -3,6 +3,7 @@ import { ChainTypes, ExtensionTypes, PaymentTypes, + RequestLogicTypes, } from '@requestnetwork/types'; import { PaymentDetectorBase } from './payment-detector-base'; import { GetDeploymentInformation } from './utils'; @@ -87,12 +88,12 @@ export interface ISupportedPaymentNetworkByNetwork< } /** Object interface to list the payment network id and its module by currency */ -export interface ISupportedPaymentNetworkByCurrency< +export type ISupportedPaymentNetworkByCurrency< TPaymentEventParameters extends PaymentTypes.GenericEventParameters = PaymentTypes.GenericEventParameters, -> { - [currency: string]: ISupportedPaymentNetworkByNetwork; -} +> = { + [key in RequestLogicTypes.CURRENCY]: ISupportedPaymentNetworkByNetwork; +}; export type TGetSubGraphClient = ( network: ChainTypes.IChain, diff --git a/packages/payment-detection/src/utils.ts b/packages/payment-detection/src/utils.ts index 7131539cc5..40464b7467 100644 --- a/packages/payment-detection/src/utils.ts +++ b/packages/payment-detection/src/utils.ts @@ -1,16 +1,10 @@ import { CurrencyDefinition, isValidNearAddress } from '@requestnetwork/currency'; -import { - CurrencyTypes, - ExtensionTypes, - PaymentTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { BigNumber, BigNumberish, Contract, errors, logger } from 'ethers'; import { getAddress, keccak256, LogDescription } from 'ethers/lib/utils'; import { ContractArtifact, DeploymentInformation } from '@requestnetwork/smart-contracts'; import { NetworkNotSupported, VersionNotSupported } from './balance-error'; import * as PaymentReferenceCalculator from './payment-reference-calculator'; -import { IReferenceBasedCreationParameters } from './types'; /** * Converts the Log's args from array to an object with keys being the name of the arguments @@ -88,15 +82,17 @@ export const makeGetDeploymentInformation = < `No contract matches payment network version: ${paymentNetworkVersion}.`, ); } - const info = artifact.getOptionalDeploymentInformation(network, contractVersion); + const info = artifact.getOptionalDeploymentInformation(network.name, contractVersion); if (!info) { if (!allowUndefined) { - if (artifact.getOptionalDeploymentInformation(network)) { + if (artifact.getOptionalDeploymentInformation(network.name)) { throw new VersionNotSupported( `Payment network version not supported: ${paymentNetworkVersion}`, ); } - throw new NetworkNotSupported(`Network not supported for this payment network: ${network}`); + throw new NetworkNotSupported( + `Network not supported for this payment network: ${network.name}`, + ); } return null as ReturnType>; } @@ -141,7 +137,7 @@ export function getPaymentNetworkExtension( ) as ExtensionTypes.IPaymentNetworkState; } -type PaymentParameters = IReferenceBasedCreationParameters & +type PaymentParameters = PaymentTypes.IReferenceBasedCreationParameters & PaymentTypes.IDeclarativePaymentEventParameters; /** Gets the payment info based on parameters, for payment reference calculation */ diff --git a/packages/payment-detection/test/payment-network-factory.test.ts b/packages/payment-detection/test/payment-network-factory.test.ts index acd60a1da4..dee4342fca 100644 --- a/packages/payment-detection/test/payment-network-factory.test.ts +++ b/packages/payment-detection/test/payment-network-factory.test.ts @@ -2,12 +2,14 @@ import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyManager } from '@requestnetwork/currency'; import { BtcMainnetAddressBasedDetector } from '../src/btc'; import { + AnyToERC20PaymentDetector, DeclarativePaymentDetector, EthInputDataPaymentDetector, PaymentNetworkFactory, } from '../src'; import { AdvancedLogic } from '@requestnetwork/advanced-logic'; import { ERC20FeeProxyPaymentDetector } from '../src/erc20/fee-proxy-contract'; +import { IRequest } from '@requestnetwork/types/src/request-logic-types'; const currencyManager = CurrencyManager.getDefault(); const advancedLogic = new AdvancedLogic(currencyManager); @@ -81,6 +83,30 @@ describe('api/payment-network/payment-network-factory', () => { BtcMainnetAddressBasedDetector, ); }); + + it('can getPaymentNetworkFromRequest for payment with conversion', async () => { + const request: any = { + currency: { + type: RequestLogicTypes.CURRENCY.ISO4217, + value: 'USD', + }, + extensions: { + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY as string]: { + id: ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ERC20_PROXY, + type: ExtensionTypes.TYPE.PAYMENT_NETWORK, + values: { + network: 'mainnet', + }, + }, + }, + }; + + // 'createPayment createPaymentNetwork' + expect(paymentNetworkFactory.getPaymentNetworkFromRequest(request)).toBeInstanceOf( + AnyToERC20PaymentDetector, + ); + }); + it('can getPaymentNetworkFromRequest with a request without payment network', async () => { const request: any = { currency: { diff --git a/packages/payment-processor/src/payment/index.ts b/packages/payment-processor/src/payment/index.ts index b9472fc5d6..7ff2f7c83e 100644 --- a/packages/payment-processor/src/payment/index.ts +++ b/packages/payment-processor/src/payment/index.ts @@ -1,6 +1,6 @@ import { ContractTransaction, Signer, BigNumber, BigNumberish, providers } from 'ethers'; -import { ClientTypes, ExtensionTypes, TypesUtils } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, ExtensionTypes, TypesUtils } from '@requestnetwork/types'; import { getBtcPaymentUrl } from './btc-address-based'; import { _getErc20PaymentUrl, getAnyErc20Balance } from './erc20'; @@ -261,9 +261,9 @@ export async function isSolvent({ }): Promise { // Near case if ( - CurrencyManager.getDefault().chainManager.ecosystems['near'].isChainSupported( - currency.network, - ) && + CurrencyManager.getDefault().chainManager.ecosystems[ + ChainTypes.ECOSYSTEM.NEAR + ].isChainSupported(currency.network) && providerOptions?.nearWalletConnection ) { return isNearAccountSolvent(amount, providerOptions.nearWalletConnection, currency); @@ -350,9 +350,9 @@ const throwIfNotWeb3 = (request: ClientTypes.IRequestData) => { // FIXME: there is a near web3Provider equivalent: https://github.com/aurora-is-near/near-web3-provider if ( request.currencyInfo?.network && - CurrencyManager.getDefault().chainManager.ecosystems['near'].isChainSupported( - request.currencyInfo.network, - ) + CurrencyManager.getDefault().chainManager.ecosystems[ + ChainTypes.ECOSYSTEM.NEAR + ].isChainSupported(request.currencyInfo.network) ) { throw new UnsupportedPaymentChain(request.currencyInfo.network); } diff --git a/packages/payment-processor/src/payment/utils.ts b/packages/payment-processor/src/payment/utils.ts index 505932c7e4..ce6ae66247 100644 --- a/packages/payment-processor/src/payment/utils.ts +++ b/packages/payment-processor/src/payment/utils.ts @@ -1,13 +1,8 @@ import { ethers, Signer, providers, BigNumber, BigNumberish, ContractTransaction } from 'ethers'; import { getDefaultProvider, getPaymentReference } from '@requestnetwork/payment-detection'; -import { - ClientTypes, - CurrencyTypes, - ExtensionTypes, - RequestLogicTypes, -} from '@requestnetwork/types'; -import { EvmChains, getCurrencyHash } from '@requestnetwork/currency'; +import { ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { getCurrencyHash } from '@requestnetwork/currency'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { getPaymentNetworkExtension } from '@requestnetwork/payment-detection'; import { getReceivableTokenIdForRequest } from './erc20-transferable-receivable'; @@ -79,7 +74,7 @@ export function getRequestPaymentValues(request: ClientTypes.IRequestData): { expectedStartDate?: string; acceptedTokens?: string[]; maxRateTimespan?: string; - network?: ChainTypes.IChain; + network?: string; version: string; } { const extension = getPaymentNetworkExtension(request); diff --git a/packages/request-client.js/package.json b/packages/request-client.js/package.json index c90dcc67f5..6783e4086a 100644 --- a/packages/request-client.js/package.json +++ b/packages/request-client.js/package.json @@ -43,6 +43,7 @@ }, "dependencies": { "@requestnetwork/advanced-logic": "0.39.0", + "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/data-access": "0.31.0", "@requestnetwork/data-format": "0.14.0", diff --git a/packages/request-client.js/src/api/request-network.ts b/packages/request-client.js/src/api/request-network.ts index b06220ab0a..43a68f8f13 100644 --- a/packages/request-client.js/src/api/request-network.ts +++ b/packages/request-client.js/src/api/request-network.ts @@ -398,9 +398,10 @@ export default class RequestNetwork { copiedRequestParameters.extensionsData = []; const detectionChain = - parameters?.paymentNetwork?.parameters && 'network' in parameters.paymentNetwork.parameters - ? parameters.paymentNetwork.parameters.network ?? requestParameters.currency.network - : requestParameters.currency.network; + (parameters?.paymentNetwork?.parameters && + 'network' in parameters.paymentNetwork.parameters && + parameters.paymentNetwork.parameters.network) || + requestParameters.currency.network; const paymentNetwork = parameters.paymentNetwork ? this.paymentNetworkFactory.createPaymentNetwork( diff --git a/packages/request-client.js/src/api/request.ts b/packages/request-client.js/src/api/request.ts index 41d27f4921..269b55cd83 100644 --- a/packages/request-client.js/src/api/request.ts +++ b/packages/request-client.js/src/api/request.ts @@ -4,7 +4,7 @@ import { EscrowERC20InfoRetriever, } from '@requestnetwork/payment-detection'; import { - CurrencyTypes, + ChainTypes, EncryptionTypes, IdentityTypes, PaymentTypes, @@ -709,16 +709,16 @@ export default class Request { public async getEscrowData( paymentReference: string, - network: ChainTypes.IEvmChain, + chain: ChainTypes.IEvmChain, ): Promise { - const escrowContractAddress = erc20EscrowToPayArtifact.getAddress(network); + const escrowContractAddress = erc20EscrowToPayArtifact.getAddress(chain.name); const escrowInfoRetriever = new EscrowERC20InfoRetriever( paymentReference, escrowContractAddress, 0, '', '', - network, + chain, ); return await escrowInfoRetriever.getEscrowRequestMapping(); } diff --git a/packages/request-client.js/src/http-metamask-data-access.ts b/packages/request-client.js/src/http-metamask-data-access.ts index 4a45df8bbb..7194f85055 100644 --- a/packages/request-client.js/src/http-metamask-data-access.ts +++ b/packages/request-client.js/src/http-metamask-data-access.ts @@ -1,9 +1,10 @@ import { Block } from '@requestnetwork/data-access'; import { requestHashSubmitterArtifact } from '@requestnetwork/smart-contracts'; -import { ClientTypes, CurrencyTypes, DataAccessTypes, StorageTypes } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, DataAccessTypes, StorageTypes } from '@requestnetwork/types'; import { ethers } from 'ethers'; import { EventEmitter } from 'events'; import HttpDataAccess, { NodeConnectionConfig } from './http-data-access'; +import { ChainManager } from '@requestnetwork/chain'; /** * Exposes a Data-Access module over HTTP @@ -20,7 +21,9 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { } = {}; private provider: ethers.providers.JsonRpcProvider | ethers.providers.Web3Provider; - private networkName: ChainTypes.IEvmChain = 'private'; + private storageChain: ChainTypes.IEvmChain = ChainManager.getDefault().fromName('private', [ + ChainTypes.ECOSYSTEM.EVM, + ]); /** * Creates an instance of HttpDataAccess. @@ -73,14 +76,14 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { channelId: string, topics?: string[], ): Promise { - if (!this.networkName) { + if (!this.storageChain) { const network = await this.provider.getNetwork(); - - this.networkName = - network.chainId === 1 ? 'mainnet' : network.chainId === 4 ? 'rinkeby' : 'private'; + this.storageChain = ChainManager.getDefault().fromId(network.chainId.toString(), [ + ChainTypes.ECOSYSTEM.EVM, + ]); } const submitterContract = requestHashSubmitterArtifact.connect( - this.networkName, + this.storageChain.name, this.provider.getSigner(), ); @@ -94,7 +97,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { topics, ); - // store the block on ipfs and get the the ipfs hash and size + // store the block on ipfs and get the ipfs hash and size const { ipfsHash, ipfsSize } = await this.fetch<{ ipfsHash: string; ipfsSize: number }>( 'POST', '/ipfsAdd', @@ -120,7 +123,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { blockNumber: tx.blockNumber ?? -1, blockTimestamp: ethBlock.timestamp, fee: fee.toString(), - networkName: this.networkName, + networkName: this.storageChain.name, smartContractAddress: tx.to ?? '', transactionHash: tx.hash, }; @@ -157,7 +160,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { blockNumber: txConfirmed.blockNumber, blockTimestamp: ethBlock.timestamp, fee: fee.toString(), - networkName: this.networkName, + networkName: this.storageChain.name, smartContractAddress: txConfirmed.to, transactionHash: txConfirmed.transactionHash, }, diff --git a/packages/request-node/package.json b/packages/request-node/package.json index d51a5e8aba..5c2b21e871 100644 --- a/packages/request-node/package.json +++ b/packages/request-node/package.json @@ -42,6 +42,7 @@ }, "dependencies": { "@ethersproject/experimental": "5.5.0", + "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/data-access": "0.31.0", "@requestnetwork/ethereum-storage": "0.31.0", diff --git a/packages/request-node/src/dataAccess.ts b/packages/request-node/src/dataAccess.ts index 4fb98a4636..292a788f5d 100644 --- a/packages/request-node/src/dataAccess.ts +++ b/packages/request-node/src/dataAccess.ts @@ -1,6 +1,6 @@ import { providers, Wallet } from 'ethers'; import { NonceManager } from '@ethersproject/experimental'; -import { CurrencyTypes, DataAccessTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; +import { ChainTypes, DataAccessTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; import * as config from './config'; import { TheGraphDataAccess } from '@requestnetwork/thegraph-data-access'; @@ -8,7 +8,7 @@ import { PendingStore } from '@requestnetwork/data-access'; import { EthereumStorage, EthereumTransactionSubmitter } from '@requestnetwork/ethereum-storage'; export function getDataAccess( - network: ChainTypes.IEvmChain, + chain: ChainTypes.IEvmChain, ipfsStorage: StorageTypes.IIpfsStorage, logger: LogTypes.ILogger, ): DataAccessTypes.IDataAccess { @@ -25,7 +25,7 @@ export function getDataAccess( const gasPriceMultiplier = config.getGasPriceMultiplier(); const blockConfirmations = config.getBlockConfirmations(); const txSubmitter = new EthereumTransactionSubmitter({ - network, + network: chain.name, logger, gasPriceMin, gasPriceMax, @@ -42,7 +42,7 @@ export function getDataAccess( return new TheGraphDataAccess({ graphql: { url: graphNodeUrl }, storage, - network, + network: chain.name, logger, pendingStore, }); diff --git a/packages/request-node/src/request/confirmedTransactionStore.ts b/packages/request-node/src/request/confirmedTransactionStore.ts index 85a9ac14d7..09f1c33149 100644 --- a/packages/request-node/src/request/confirmedTransactionStore.ts +++ b/packages/request-node/src/request/confirmedTransactionStore.ts @@ -1,4 +1,4 @@ -import { DataAccessTypes, StorageTypes } from '@requestnetwork/types'; +import { ChainTypes, DataAccessTypes, StorageTypes } from '@requestnetwork/types'; import { SubgraphClient } from '@requestnetwork/thegraph-data-access'; /** @@ -13,7 +13,7 @@ export default class ConfirmedTransactionStore { */ constructor( private readonly subgraphClient: SubgraphClient, - private readonly networkName: string, + private readonly storageChain: ChainTypes.IEvmChain, ) {} public async getConfirmedTransaction( @@ -37,7 +37,7 @@ export default class ConfirmedTransactionStore { blockConfirmation: blockNumber - transaction.blockNumber, blockTimestamp: transaction.blockTimestamp, blockNumber: transaction.blockNumber, - networkName: this.networkName, + networkName: this.storageChain.name, smartContractAddress: transaction.smartContractAddress, transactionHash: transaction.transactionHash, }, diff --git a/packages/request-node/src/server.ts b/packages/request-node/src/server.ts index 2422492cfd..cf807bdf42 100755 --- a/packages/request-node/src/server.ts +++ b/packages/request-node/src/server.ts @@ -5,33 +5,33 @@ import { RequestNode } from './requestNode'; import { getDataAccess } from './dataAccess'; import { getDataStorage } from './dataStorage'; import ConfirmedTransactionStore from './request/confirmedTransactionStore'; -import { EvmChains } from '@requestnetwork/currency'; import { getEthereumStorageNetworkNameFromId } from '@requestnetwork/ethereum-storage'; import { SubgraphClient } from '@requestnetwork/thegraph-data-access'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainTypes } from '@requestnetwork/types'; // Initialize the node logger const logger = new Logger(config.getLogLevel(), config.getLogMode()); -const getNetwork = () => { - const network = getEthereumStorageNetworkNameFromId(config.getStorageNetworkId()) as any; +const getStorageChain = (): ChainTypes.IEvmChain => { + const network = getEthereumStorageNetworkNameFromId(config.getStorageNetworkId()); if (!network) { throw new Error(`Storage network not supported: ${config.getStorageNetworkId()}`); } - EvmChains.assertChainSupported(network); - return network; + return ChainManager.getDefault().fromName(network, [ChainTypes.ECOSYSTEM.EVM]); }; export const getRequestNode = (): RequestNode => { - const network = getNetwork(); + const storageChain = getStorageChain(); const storage = getDataStorage(logger); - const dataAccess = getDataAccess(network, storage, logger); + const dataAccess = getDataAccess(storageChain, storage, logger); // we access the subgraph client directly, not through the data access, // because this feature is specific to RN use with Request Node. Without a node, // the confirmation process would be different, so this doesn't fit in the data access layer const confirmedTransactionStore = new ConfirmedTransactionStore( new SubgraphClient(config.getGraphNodeUrl()), - network, + storageChain, ); return new RequestNode(dataAccess, storage, confirmedTransactionStore, logger); diff --git a/packages/smart-contracts/scripts-create2/tenderly.ts b/packages/smart-contracts/scripts-create2/tenderly.ts index 105d4356e0..8c8d116056 100644 --- a/packages/smart-contracts/scripts-create2/tenderly.ts +++ b/packages/smart-contracts/scripts-create2/tenderly.ts @@ -39,7 +39,9 @@ const supportedTenderlyChains: ChainTypes.IEvmChain[] = [ 'optimism', 'rinkeby', 'xdai', -].map((chainName: string) => ChainManager.getDefault().fromName(chainName, ['evm'])); +].map((chainName: string) => + ChainManager.getDefault().fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]), +); type TenderlyContract = { address: string; chainId: number }; @@ -60,7 +62,9 @@ export const tenderlyImportAll = async (hre: HardhatRuntimeEnvironmentExtended): const { networkName, address, version } = deployment; let deploymentChain: ChainTypes.IEvmChain; try { - deploymentChain = ChainManager.getDefault().fromName(networkName, ['evm']); + deploymentChain = ChainManager.getDefault().fromName(networkName, [ + ChainTypes.ECOSYSTEM.EVM, + ]); } catch { continue; } diff --git a/packages/toolbox/src/chainlinkConversionPathTools.ts b/packages/toolbox/src/chainlinkConversionPathTools.ts index e23e09e475..0d122ecd42 100644 --- a/packages/toolbox/src/chainlinkConversionPathTools.ts +++ b/packages/toolbox/src/chainlinkConversionPathTools.ts @@ -5,9 +5,9 @@ import { ChainlinkConversionPath, ChainlinkConversionPath__factory, } from '@requestnetwork/smart-contracts/types'; -import { CurrencyManager, EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { retry } from '@requestnetwork/utils'; -import { CurrencyTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; export interface IOptions { network?: string; @@ -48,11 +48,11 @@ class ChainlinkConversionPathTools { // Setup the conversion proxy contract interface this.chainLinkConversionPath = ChainlinkConversionPath__factory.connect( - chainlinkConversionPath.getAddress(network), + chainlinkConversionPath.getAddress(network.name), this.provider, ); - this.creationBlockNumber = chainlinkConversionPath.getCreationBlockNumber(this.network); + this.creationBlockNumber = chainlinkConversionPath.getCreationBlockNumber(this.network.name); this.maxRange = options?.maxRange || 1000000; } @@ -139,7 +139,7 @@ const getCurrency = (symbol: string) => { }; export const listAggregators = async (options?: IOptions): Promise => { - let networks: ChainTypes.IEvmChain[] = ['private', 'rinkeby', 'mainnet']; + let networks = ['private', 'rinkeby', 'mainnet']; if (options?.network) { EvmChains.assertChainSupported(options.network); networks = [options.network]; diff --git a/packages/types/src/chain-types.ts b/packages/types/src/chain-types.ts index 8e97a8daf8..48c5567d20 100644 --- a/packages/types/src/chain-types.ts +++ b/packages/types/src/chain-types.ts @@ -1,31 +1,47 @@ import { RequestLogicTypes } from './index'; +/** + * List of ecosystems supported by the Request Network protocol + */ +export enum ECOSYSTEM { + BTC = 'BTC', + DECLARATIVE = 'DECLARATIVE', + EVM = 'EVM', + NEAR = 'NEAR', +} + +/** + * List of ecosystems supported by TheGraph + */ +export const VM_ECOSYSTEMS = [ECOSYSTEM.EVM, ECOSYSTEM.NEAR] as const; +export type VmChainEcosystem = (typeof VM_ECOSYSTEMS)[number]; + export interface IChainCommon { id: string; name: string; testnet: boolean; - ecosystem: ChainEcosystem; + ecosystem: ECOSYSTEM; currencyType: RequestLogicTypes.CURRENCY; eq(chain: IChainCommon): boolean; } export interface IBtcChain extends IChainCommon { - ecosystem: 'btc'; + ecosystem: ECOSYSTEM.BTC; currencyType: RequestLogicTypes.CURRENCY.BTC; } export interface IDeclarativeChain extends IChainCommon { - ecosystem: 'declarative'; + ecosystem: ECOSYSTEM.DECLARATIVE; currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface IEvmChain extends IChainCommon { - ecosystem: 'evm'; + ecosystem: ECOSYSTEM.EVM; currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface INearChain extends IChainCommon { - ecosystem: 'near'; + ecosystem: ECOSYSTEM.NEAR; currencyType: RequestLogicTypes.CURRENCY.ETH; } @@ -33,18 +49,17 @@ export interface INearChain extends IChainCommon { * List of ecosystems supported by the Request Network protocol */ export type ChainTypeByEcosystem = { - btc: IBtcChain; - declarative: IDeclarativeChain; - evm: IEvmChain; - near: INearChain; + [ECOSYSTEM.BTC]: IBtcChain; + [ECOSYSTEM.DECLARATIVE]: IDeclarativeChain; + [ECOSYSTEM.EVM]: IEvmChain; + [ECOSYSTEM.NEAR]: INearChain; }; -export type ChainEcosystem = keyof ChainTypeByEcosystem; -export type IChain = ChainTypeByEcosystem[ChainEcosystem]; +export type IChain = ChainTypeByEcosystem[ECOSYSTEM]; /** * VmChains are Virtual Machine chains supported by TheGraph */ -export type IVmChain = IEvmChain | INearChain; +export type IVmChain = ChainTypeByEcosystem[VmChainEcosystem]; // export interface IChainManager { // chains: IChain[]; diff --git a/packages/types/src/extensions/pn-any-to-any-conversion-types.ts b/packages/types/src/extensions/pn-any-to-any-conversion-types.ts index b2fd13e4ec..abd5da04b3 100644 --- a/packages/types/src/extensions/pn-any-to-any-conversion-types.ts +++ b/packages/types/src/extensions/pn-any-to-any-conversion-types.ts @@ -1,5 +1,4 @@ import { PnFeeReferenceBased } from '../extension-types'; -import { IChain } from '../chain-types'; export { IAddPaymentAddressParameters, IAddRefundAddressParameters, @@ -13,5 +12,5 @@ export type IConversionReferenceBased /** Parameters for the creation action */ export interface ICreationParameters extends PnFeeReferenceBased.ICreationParameters { maxRateTimespan?: number; - network?: IChain; + network?: string; } diff --git a/packages/types/src/extensions/pn-any-to-erc20-types.ts b/packages/types/src/extensions/pn-any-to-erc20-types.ts index daf88bd5d5..3ab6fe403f 100644 --- a/packages/types/src/extensions/pn-any-to-erc20-types.ts +++ b/packages/types/src/extensions/pn-any-to-erc20-types.ts @@ -1,12 +1,11 @@ import * as PnAnyToAnyConversion from './pn-any-to-any-conversion-types'; -import { IEvmChain } from '../chain-types'; /** Any to ERC20 reference-based payment network extension interface */ export type IAnyToERC20 = PnAnyToAnyConversion.IConversionReferenceBased; /** Parameters for the creation action */ export interface ICreationParameters extends PnAnyToAnyConversion.ICreationParameters { - network?: IEvmChain; + network?: string; // FIXME: should be mandatory according to AnyToErc20ProxyPaymentNetwork createCreationAction() logic acceptedTokens?: string[]; } diff --git a/packages/types/src/payment-types.ts b/packages/types/src/payment-types.ts index d9f44c4ea3..12b5df2c4c 100644 --- a/packages/types/src/payment-types.ts +++ b/packages/types/src/payment-types.ts @@ -3,7 +3,6 @@ import * as RequestLogic from './request-logic-types'; import * as ExtensionTypes from './extension-types'; import { ICreationParameters } from './extensions/pn-any-declarative-types'; import { ICreationParameters as ICreationParametersAnyToAny } from './extensions/pn-any-to-any-conversion-types'; -import { IEvmChain } from './chain-types'; /** Interface for payment network extensions state and interpretation */ export interface IPaymentNetwork< @@ -37,7 +36,7 @@ export interface IFeeReferenceBasedCreationParameters extends IReferenceBasedCre /** Parameters to create a request with "any to erc20" payment network */ export interface IAnyToErc20CreationParameters extends ICreationParametersAnyToAny { acceptedTokens?: string[]; - network?: IEvmChain; + network?: string; } /** From 86d1c7281e40674145457063e4c79c0978c5e868 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Mon, 19 Feb 2024 17:15:33 +0100 Subject: [PATCH 04/14] fix payment processor --- packages/advanced-logic/package.json | 1 - .../erc20/fee-proxy-contract.ts | 3 +- packages/chain/src/chain-manager.ts | 33 +++++---- packages/chain/src/chains/btc/btc-chain.ts | 2 +- .../chain/src/chains/btc/btc-ecosystem.ts | 2 +- packages/chain/src/chains/chain-abstract.ts | 4 +- .../declarative/declarative-ecosystem.ts | 2 +- .../chain/src/chains/ecosystem-abstract.ts | 42 ++++------- .../chain/src/chains/evm/evm-ecosystem.ts | 2 +- .../chain/src/chains/near/near-ecosystem.ts | 2 +- packages/currency/src/currency-manager.ts | 11 +-- packages/currency/src/erc777/index.ts | 3 +- packages/currency/src/types.ts | 3 +- packages/payment-processor/package.json | 1 + .../src/payment/any-to-eth-proxy.ts | 13 ++-- .../src/payment/batch-conversion-proxy.ts | 6 +- .../src/payment/batch-proxy.ts | 6 +- .../src/payment/erc20-escrow-payment.ts | 4 +- .../src/payment/erc20-fee-proxy.ts | 9 ++- .../src/payment/near-conversion.ts | 18 +++-- .../src/payment/near-fungible.ts | 13 ++-- .../src/payment/near-input-data.ts | 17 +++-- .../src/payment/swap-any-to-erc20.ts | 5 +- .../src/payment/swap-erc20-fee-proxy.ts | 6 +- .../src/payment/swap-erc20.ts | 10 +-- .../src/payment/utils-near.ts | 4 +- .../payment-processor/src/payment/utils.ts | 31 ++++---- .../src/http-metamask-data-access.ts | 4 +- packages/request-node/src/server.ts | 4 +- packages/smart-contracts/package.json | 1 + .../scripts-create2/tenderly.ts | 6 +- packages/types/src/chain-types.ts | 71 +++++++++---------- 32 files changed, 173 insertions(+), 166 deletions(-) diff --git a/packages/advanced-logic/package.json b/packages/advanced-logic/package.json index 0b854fc74f..efcd5cb32d 100644 --- a/packages/advanced-logic/package.json +++ b/packages/advanced-logic/package.json @@ -39,7 +39,6 @@ "test:watch": "yarn test --watch" }, "dependencies": { - "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/types": "0.40.0", "@requestnetwork/utils": "0.40.0", diff --git a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts index 27572f3352..3973e9e0a0 100644 --- a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts +++ b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts @@ -2,7 +2,6 @@ import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/t import { ICurrencyManager } from '@requestnetwork/currency'; import { UnsupportedNetworkError } from '../address-based'; import { FeeReferenceBasedPaymentNetwork } from '../fee-reference-based'; -import { ChainManager } from '@requestnetwork/chain'; const EVM_CURRENT_VERSION = '0.2.0'; const NEAR_CURRENT_VERSION = 'NEAR-0.1.0'; @@ -37,7 +36,7 @@ export default class Erc20FeeProxyPaymentNetwork< } protected static getDefaultCurrencyVersion( - chainManager: ChainManager, + chainManager: ChainTypes.IChainManager, network?: ChainTypes.IChain | undefined, ): string { return chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(network) diff --git a/packages/chain/src/chain-manager.ts b/packages/chain/src/chain-manager.ts index 70db52fe73..fcd09ee8d0 100644 --- a/packages/chain/src/chain-manager.ts +++ b/packages/chain/src/chain-manager.ts @@ -1,16 +1,18 @@ import { ChainDefinition } from './types'; -import { EcosystemAbstract } from './chains/ecosystem-abstract'; import BtcEcosystem from './chains/btc/btc-ecosystem'; import DeclarativeEcosystem from './chains/declarative/declarative-ecosystem'; import EvmEcosystem from './chains/evm/evm-ecosystem'; import NearEcosystem from './chains/near/near-ecosystem'; import { initializeChains } from './chains/utils'; import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainAbstract } from './chains/chain-abstract'; -export class ChainManager { - private static defaultInstance: ChainManager; +export class ChainManager implements ChainTypes.IChainManager { + private static instance: ChainTypes.IChainManager; - public ecosystems: Record> = { + public readonly ecosystems: { + [E in ChainTypes.ECOSYSTEM]: ChainTypes.IEcosystem; + } = { [ChainTypes.ECOSYSTEM.BTC]: BtcEcosystem, [ChainTypes.ECOSYSTEM.DECLARATIVE]: DeclarativeEcosystem, [ChainTypes.ECOSYSTEM.EVM]: EvmEcosystem, @@ -23,7 +25,7 @@ export class ChainManager { const ecosystem = this.ecosystems[ecosystemName as ChainTypes.ECOSYSTEM]; if (!inputChains[ecosystem.name]) continue; const chainDefinitions = inputChains[ecosystem.name]; - const chains = initializeChains(ecosystem.chainClass, chainDefinitions); + const chains = initializeChains(ecosystem.chainClass, chainDefinitions); Object.assign(ecosystem.chains, chains); } } @@ -32,11 +34,11 @@ export class ChainManager { * Returns the list of supported chains */ get chains(): ChainTypes.IChain[] { - return Object.keys(this.ecosystems).reduce((chains, ecosystemName) => { - return chains.concat( - Object.values(this.ecosystems[ecosystemName as ChainTypes.ECOSYSTEM].chains), - ); - }, [] as ChainTypes.IChain[]); + return Object.keys(this.ecosystems).reduce( + (chains, ecosystemName) => + chains.concat(Object.values(this.ecosystems[ecosystemName as ChainTypes.ECOSYSTEM].chains)), + [] as ChainTypes.IChain[], + ); } getEcosystemsByCurrencyType(currencyType: RequestLogicTypes.CURRENCY): ChainTypes.ECOSYSTEM[] { @@ -96,11 +98,14 @@ export class ChainManager { return this.fromGeneric('id', chainId, ecosystemsFilter); } - static getDefault(): ChainManager { - if (this.defaultInstance) return this.defaultInstance; + static setCurrent(chainManager: ChainTypes.IChainManager): void { + this.instance = chainManager; + } - this.defaultInstance = new ChainManager(); - return this.defaultInstance; + static current(): ChainTypes.IChainManager { + if (this.instance) return this.instance; + this.instance = new ChainManager(); + return this.instance; } /** diff --git a/packages/chain/src/chains/btc/btc-chain.ts b/packages/chain/src/chains/btc/btc-chain.ts index 87fd5bb7c0..9f6dc20b02 100644 --- a/packages/chain/src/chains/btc/btc-chain.ts +++ b/packages/chain/src/chains/btc/btc-chain.ts @@ -1,7 +1,7 @@ import { ChainAbstract } from '../chain-abstract'; import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; -export class BtcChain extends ChainAbstract { +export class BtcChain extends ChainAbstract implements ChainTypes.IBtcChain { public readonly ecosystem = ChainTypes.ECOSYSTEM.BTC; public readonly currencyType = RequestLogicTypes.CURRENCY.BTC; } diff --git a/packages/chain/src/chains/btc/btc-ecosystem.ts b/packages/chain/src/chains/btc/btc-ecosystem.ts index 51d12882bf..cb61e8adbd 100644 --- a/packages/chain/src/chains/btc/btc-ecosystem.ts +++ b/packages/chain/src/chains/btc/btc-ecosystem.ts @@ -3,7 +3,7 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { chains } from './index'; import { BtcChain } from './btc-chain'; -class BtcEcosystem extends EcosystemAbstract {} +class BtcEcosystem extends EcosystemAbstract {} export default new BtcEcosystem( ChainTypes.ECOSYSTEM.BTC, BtcChain, diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts index 8ba2601b6d..b86358b353 100644 --- a/packages/chain/src/chains/chain-abstract.ts +++ b/packages/chain/src/chains/chain-abstract.ts @@ -9,7 +9,9 @@ export abstract class ChainAbstract implements ChainTypes.IChainCommon { public readonly id: string, public readonly name: string, public readonly testnet: boolean = false, - ) {} + ) { + this.name = this.name.toLowerCase(); + } public eq(chain: ChainTypes.IChain): boolean { return this === chain || (this.ecosystem === chain.ecosystem && this.id === chain.id); diff --git a/packages/chain/src/chains/declarative/declarative-ecosystem.ts b/packages/chain/src/chains/declarative/declarative-ecosystem.ts index cd9e816157..7bea696ffb 100644 --- a/packages/chain/src/chains/declarative/declarative-ecosystem.ts +++ b/packages/chain/src/chains/declarative/declarative-ecosystem.ts @@ -3,7 +3,7 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { DeclarativeChain } from './declarative-chain'; import { chains } from './index'; -class DeclarativeEcosystem extends EcosystemAbstract { +class DeclarativeEcosystem extends EcosystemAbstract { constructor(chains: Record) { super( ChainTypes.ECOSYSTEM.DECLARATIVE, diff --git a/packages/chain/src/chains/ecosystem-abstract.ts b/packages/chain/src/chains/ecosystem-abstract.ts index f200d11d7f..ccc907b0c3 100644 --- a/packages/chain/src/chains/ecosystem-abstract.ts +++ b/packages/chain/src/chains/ecosystem-abstract.ts @@ -1,43 +1,29 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { ChainAbstract } from './chain-abstract'; -export abstract class EcosystemAbstract { +export abstract class EcosystemAbstract + implements ChainTypes.IEcosystem +{ constructor( - public name: ChainTypes.ECOSYSTEM, - public chainClass: new (id: string, name: string, testnet?: boolean) => CHAIN, - public chains: Record, + public name: ECOSYSTEM, + public chainClass: new ( + id: string, + name: string, + testnet?: boolean, + ) => ChainTypes.ChainTypeByEcosystem[ECOSYSTEM], + public chains: Record, public currencyType: RequestLogicTypes.CURRENCY, - ) { - // this.addNativeCurrenciesToChains(currencyType); - } + ) {} get chainNames(): string[] { return Object.keys(this.chains); } - /** - * Adds the native currency to the list of currencies supported by each chain - */ - // private addNativeCurrenciesToChains( - // currencyType: RequestLogicTypes.CURRENCY.ETH | RequestLogicTypes.CURRENCY.BTC, - // ): void { - // this.chainNames.forEach((chainName) => { - // const nativeCurrency = ( - // nativeCurrencies[currencyType] as CurrencyTypes.NamedNativeCurrency[] - // ).find((currency) => currency.network === chainName); - // if (nativeCurrency) { - // const chainCurrencies: TokenMap = this.chains[chainName].currencies || {}; - // chainCurrencies.native = nativeCurrency; - // this.chains[chainName].currencies = chainCurrencies; - // } - // }); - // } - /** * Check if chainName lives amongst the list of supported chains by this chain type. * Throws in the case it's not supported. */ - public assertChainNameSupported(chainName?: string) { + public assertChainNameSupported(chainName?: string): asserts chainName is string { if (!this.isChainSupported(chainName)) throw new Error(`Unsupported chain ${chainName}`); } @@ -45,7 +31,9 @@ export abstract class EcosystemAbstract { * Check if chainName lives amongst the list of supported chains by this chain type. * Throws in the case it's not supported. */ - public assertChainSupported(chain?: ChainAbstract): asserts chain is CHAIN { + public assertChainSupported( + chain?: ChainTypes.IChain, + ): asserts chain is ChainTypes.ChainTypeByEcosystem[ECOSYSTEM] { if (!this.isChainSupported(chain)) throw new Error(`Unsupported chain ${chain?.name}`); } diff --git a/packages/chain/src/chains/evm/evm-ecosystem.ts b/packages/chain/src/chains/evm/evm-ecosystem.ts index 7e14a23cef..6558cec0f9 100644 --- a/packages/chain/src/chains/evm/evm-ecosystem.ts +++ b/packages/chain/src/chains/evm/evm-ecosystem.ts @@ -3,7 +3,7 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { chains } from './index'; import { EvmChain } from './evm-chain'; -class EvmEcosystem extends EcosystemAbstract { +class EvmEcosystem extends EcosystemAbstract { constructor(chains: Record) { super(ChainTypes.ECOSYSTEM.EVM, EvmChain, chains, RequestLogicTypes.CURRENCY.ETH); } diff --git a/packages/chain/src/chains/near/near-ecosystem.ts b/packages/chain/src/chains/near/near-ecosystem.ts index d6744a8e3b..ef24846bb9 100644 --- a/packages/chain/src/chains/near/near-ecosystem.ts +++ b/packages/chain/src/chains/near/near-ecosystem.ts @@ -3,7 +3,7 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { chains } from './index'; import { NearChain } from './near-chain'; -class NearEcosystem extends EcosystemAbstract { +class NearEcosystem extends EcosystemAbstract { constructor(chains: Record) { super(ChainTypes.ECOSYSTEM.NEAR, NearChain, chains, RequestLogicTypes.CURRENCY.ETH); } diff --git a/packages/currency/src/currency-manager.ts b/packages/currency/src/currency-manager.ts index 8cb894125b..785d414947 100644 --- a/packages/currency/src/currency-manager.ts +++ b/packages/currency/src/currency-manager.ts @@ -4,7 +4,6 @@ import addressValidator from 'multicoin-address-validator'; import { getSupportedERC20Currencies } from './erc20'; import { getSupportedERC777Currencies } from './erc777'; import { getHash } from './getHash'; -import { ChainManager } from '@requestnetwork/chain'; import { CurrencyDefinition, CurrencyInput, @@ -16,6 +15,7 @@ import { import { AggregatorsMap, defaultConversionPairs, getPath } from './conversion-aggregators'; import { isValidNearAddress } from './currency-utils'; import { getSupportedNativeCurrencies } from './native'; +import { ChainManager } from '@requestnetwork/chain'; const { BTC, ERC20, ERC777, ETH, ISO4217 } = RequestLogicTypes.CURRENCY; @@ -26,21 +26,21 @@ export class CurrencyManager implements ICurrencyManager private readonly knownCurrencies: CurrencyDefinition[]; private readonly legacyTokens: LegacyTokenMap; private readonly conversionPairs: AggregatorsMap; - public readonly chainManager: ChainManager; + public readonly chainManager: ChainTypes.IChainManager; private static defaultInstance: CurrencyManager; /** - * * @param inputCurrencies The list of currencies known by the Manager. * @param legacyTokens A mapping of legacy currency name or network name, in the format { "chainName": {"TOKEN": ["NEW_TOKEN","NEW_CHAIN"]}} * @param conversionPairs A mapping of possible conversions by network (network => currencyFrom => currencyTo => cost) + * @param chainManager A ChainManager instance that describes the supported underlying chains */ constructor( inputCurrencies: (CurrencyInput & { id?: string; meta?: TMeta })[], legacyTokens?: LegacyTokenMap, conversionPairs?: AggregatorsMap, - chainManager?: ChainManager, + chainManager?: ChainTypes.IChainManager, ) { this.knownCurrencies = []; for (const input of inputCurrencies) { @@ -52,7 +52,8 @@ export class CurrencyManager implements ICurrencyManager } this.legacyTokens = legacyTokens || CurrencyManager.getDefaultLegacyTokens(); this.conversionPairs = conversionPairs || CurrencyManager.getDefaultConversionPairs(); - this.chainManager = chainManager || ChainManager.getDefault(); + this.chainManager = chainManager || ChainManager.current(); + ChainManager.setCurrent(this.chainManager); } /** diff --git a/packages/currency/src/erc777/index.ts b/packages/currency/src/erc777/index.ts index cd41f42188..c0c8c73d44 100644 --- a/packages/currency/src/erc777/index.ts +++ b/packages/currency/src/erc777/index.ts @@ -1,6 +1,5 @@ -import { ERC777Currency, ERC777CurrencyInput, TokenMap } from '../types'; +import { ERC777CurrencyInput, TokenMap } from '../types'; import { supportedNetworks } from './chains'; -import { ChainManager } from '@requestnetwork/chain'; import { RequestLogicTypes } from '@requestnetwork/types'; /** diff --git a/packages/currency/src/types.ts b/packages/currency/src/types.ts index c3f6edf1f9..c4172f5f1c 100644 --- a/packages/currency/src/types.ts +++ b/packages/currency/src/types.ts @@ -1,5 +1,4 @@ import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { ChainManager } from '@requestnetwork/chain'; /** * Common types used in token configuration files @@ -107,7 +106,7 @@ export type StorageCurrency = RequestLogicTypes.ICurrency; * A Currency manager handles a list of currencies and provides utility to retrieve and change format */ export interface ICurrencyManager { - chainManager: ChainManager; + chainManager: ChainTypes.IChainManager; from( symbolOrAddress: string, network?: string | ChainTypes.IChain, diff --git a/packages/payment-processor/package.json b/packages/payment-processor/package.json index ea395525be..2b323b3a39 100644 --- a/packages/payment-processor/package.json +++ b/packages/payment-processor/package.json @@ -40,6 +40,7 @@ }, "dependencies": { "@openzeppelin/contracts": "4.9.5", + "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/payment-detection": "0.40.0", "@requestnetwork/smart-contracts": "0.33.0", diff --git a/packages/payment-processor/src/payment/any-to-eth-proxy.ts b/packages/payment-processor/src/payment/any-to-eth-proxy.ts index 6c311160d6..cb21d33dee 100644 --- a/packages/payment-processor/src/payment/any-to-eth-proxy.ts +++ b/packages/payment-processor/src/payment/any-to-eth-proxy.ts @@ -10,7 +10,13 @@ import { EthConversionProxy__factory } from '@requestnetwork/smart-contracts/typ import { ClientTypes, RequestLogicTypes } from '@requestnetwork/types'; import { ITransactionOverrides } from './transaction-overrides'; -import { getAmountToPay, getProvider, getRequestPaymentValues, getSigner } from './utils'; +import { + ensureEvmChain, + getAmountToPay, + getProvider, + getRequestPaymentValues, + getSigner, +} from './utils'; import { padAmountForChainlink } from '@requestnetwork/payment-detection'; import { IPreparedTransaction } from './prepared-transaction'; import { IConversionPaymentSettings } from './index'; @@ -117,10 +123,7 @@ export function getConversionPathForEthRequest( } const { network } = getRequestPaymentValues(request); - - if (!network) { - throw new Error(`missing network`); - } + ensureEvmChain(network); const paymentCurrency = currencyManager.getNativeCurrency( RequestLogicTypes.CURRENCY.ETH, diff --git a/packages/payment-processor/src/payment/batch-conversion-proxy.ts b/packages/payment-processor/src/payment/batch-conversion-proxy.ts index a52061745c..1345b0dc01 100644 --- a/packages/payment-processor/src/payment/batch-conversion-proxy.ts +++ b/packages/payment-processor/src/payment/batch-conversion-proxy.ts @@ -328,7 +328,7 @@ const getBatchTxValue = (enrichedRequests: EnrichedRequest[]) => { */ function getUSDPathsForFeeLimit( requestDetails: PaymentTypes.RequestDetail[], - network: string, + network: ChainTypes.IVmChain, skipFeeUSDLimit: boolean, currencyManager: ICurrencyManager, hasNativePayment: boolean, @@ -373,10 +373,10 @@ function getUSDPathsForFeeLimit( * @returns */ function getBatchDeploymentInformation( - network: ChainTypes.IEvmChain, + network: ChainTypes.IVmChain, version?: string, ): { address: string } | null { - return { address: batchConversionPaymentsArtifact.getAddress(network, version) }; + return { address: batchConversionPaymentsArtifact.getAddress(network.name, version) }; } /** diff --git a/packages/payment-processor/src/payment/batch-proxy.ts b/packages/payment-processor/src/payment/batch-proxy.ts index 7b3d750a57..fbcf4265db 100644 --- a/packages/payment-processor/src/payment/batch-proxy.ts +++ b/packages/payment-processor/src/payment/batch-proxy.ts @@ -1,4 +1,4 @@ -import { ContractTransaction, Signer, providers, constants, BigNumber } from 'ethers'; +import { BigNumber, constants, ContractTransaction, providers, Signer } from 'ethers'; import { batchPaymentsArtifact } from '@requestnetwork/smart-contracts'; import { BatchPayments__factory } from '@requestnetwork/smart-contracts/types'; import { ClientTypes } from '@requestnetwork/types'; @@ -6,6 +6,7 @@ import { getPaymentNetworkExtension } from '@requestnetwork/payment-detection'; import { ITransactionOverrides } from './transaction-overrides'; import { comparePnTypeAndVersion, + ensureEvmChain, getAmountToPay, getProvider, getRequestPaymentValues, @@ -15,7 +16,6 @@ import { import { validateEthFeeProxyRequest } from './eth-fee-proxy'; import { IPreparedTransaction } from './prepared-transaction'; import { checkErc20Allowance, encodeApproveAnyErc20 } from './erc20'; -import { EvmChains } from '@requestnetwork/currency'; /** * ERC20 Batch Proxy payment details: @@ -224,7 +224,7 @@ export function getBatchProxyAddress(request: ClientTypes.IRequestData, version: if (!network) { throw new Error('No currency network'); } - EvmChains.assertChainSupported(network); + ensureEvmChain(network); const proxyAddress = batchPaymentsArtifact.getAddress(network, version); diff --git a/packages/payment-processor/src/payment/erc20-escrow-payment.ts b/packages/payment-processor/src/payment/erc20-escrow-payment.ts index 4652b307be..ec049fef31 100644 --- a/packages/payment-processor/src/payment/erc20-escrow-payment.ts +++ b/packages/payment-processor/src/payment/erc20-escrow-payment.ts @@ -4,6 +4,7 @@ import { erc20EscrowToPayArtifact } from '@requestnetwork/smart-contracts'; import { ERC20EscrowToPay__factory } from '@requestnetwork/smart-contracts/types'; import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { + ensureEvmChain, getAmountToPay, getProvider, getRequestPaymentValues, @@ -13,7 +14,6 @@ import { import { ITransactionOverrides } from './transaction-overrides'; import { encodeApproveAnyErc20 } from './erc20'; import { IPreparedTransaction } from './prepared-transaction'; -import { EvmChains } from '@requestnetwork/currency'; /** * Returns the EscrowToPay contract address corresponding to the request payment network @@ -21,7 +21,7 @@ import { EvmChains } from '@requestnetwork/currency'; */ function getContractAddress(request: ClientTypes.IRequestData) { const { network } = request.currencyInfo; - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); return erc20EscrowToPayArtifact.getAddress(network); } diff --git a/packages/payment-processor/src/payment/erc20-fee-proxy.ts b/packages/payment-processor/src/payment/erc20-fee-proxy.ts index 9d21d4b45e..efcb3b8739 100644 --- a/packages/payment-processor/src/payment/erc20-fee-proxy.ts +++ b/packages/payment-processor/src/payment/erc20-fee-proxy.ts @@ -1,13 +1,13 @@ -import { constants, ContractTransaction, Signer, BigNumberish, providers, BigNumber } from 'ethers'; +import { BigNumber, BigNumberish, constants, ContractTransaction, providers, Signer } from 'ethers'; import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; import { ERC20FeeProxy__factory } from '@requestnetwork/smart-contracts/types'; import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { getPaymentNetworkExtension } from '@requestnetwork/payment-detection'; -import { EvmChains } from '@requestnetwork/currency'; import { ITransactionOverrides } from './transaction-overrides'; import { + ensureEvmChain, getAmountToPay, getProvider, getRequestPaymentValues, @@ -82,7 +82,7 @@ export function _getErc20FeeProxyPaymentUrl( validateRequest(request, ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT); const { paymentReference, paymentAddress, feeAddress, feeAmount, version, network } = getRequestPaymentValues(request); - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); const contractAddress = erc20FeeProxyArtifact.getAddress(network, version); const amountToPay = getAmountToPay(request, amount); const feeToPay = feeAmountOverride || BigNumber.from(feeAmount || 0); @@ -103,9 +103,8 @@ export function prepareErc20FeeProxyPaymentTransaction( feeAmountOverride?: BigNumberish, ): IPreparedTransaction { validateErc20FeeProxyRequest(request, amount, feeAmountOverride); - const { network } = request.currencyInfo; - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); const encodedTx = encodePayErc20FeeRequest(request, amount, feeAmountOverride); const pn = getPaymentNetworkExtension(request); const proxyAddress = erc20FeeProxyArtifact.getAddress(network, pn?.version); diff --git a/packages/payment-processor/src/payment/near-conversion.ts b/packages/payment-processor/src/payment/near-conversion.ts index a08b5c149f..c2ad64db8c 100644 --- a/packages/payment-processor/src/payment/near-conversion.ts +++ b/packages/payment-processor/src/payment/near-conversion.ts @@ -1,17 +1,18 @@ import { BigNumberish } from 'ethers'; import { WalletConnection } from 'near-api-js'; -import { ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { - getRequestPaymentValues, - validateRequest, getAmountToPay, getPaymentExtensionVersion, + getRequestPaymentValues, + validateRequest, } from './utils'; import { INearTransactionCallback, processNearPaymentWithConversion } from './utils-near'; import { IConversionPaymentSettings } from '.'; -import { CurrencyManager, NearChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { ChainManager } from '@requestnetwork/chain'; /** * Processes the transaction to pay a request in NEAR with on-chain conversion. @@ -41,17 +42,20 @@ export async function payNearConversionRequest( throw new Error('Cannot pay without a paymentReference'); } - if (!network || !NearChains.isChainSupported(network)) { + if ( + !network || + !ChainManager.current().ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(network) + ) { throw new Error('Should be a Near network'); } - NearChains.assertChainSupported(network); + const chain = ChainManager.current().fromName(network, [ChainTypes.ECOSYSTEM.NEAR]); const amountToPay = getAmountToPay(request, amount).toString(); const version = getPaymentExtensionVersion(request); return processNearPaymentWithConversion( walletConnection, - network, + chain, amountToPay, paymentAddress, paymentReference, diff --git a/packages/payment-processor/src/payment/near-fungible.ts b/packages/payment-processor/src/payment/near-fungible.ts index 938ca65285..14c8165884 100644 --- a/packages/payment-processor/src/payment/near-fungible.ts +++ b/packages/payment-processor/src/payment/near-fungible.ts @@ -2,7 +2,7 @@ import { BigNumberish } from 'ethers'; import { WalletConnection } from 'near-api-js'; import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; -import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { getRequestPaymentValues, validateRequest, getAmountToPay } from './utils'; import { @@ -10,7 +10,7 @@ import { isReceiverReady, processNearFungiblePayment, } from './utils-near'; -import { NearChains } from '@requestnetwork/currency'; +import { ChainManager } from '@requestnetwork/chain'; /** * Processes the transaction to pay a request in fungible token on NEAR with fee (Erc20FeeProxy). @@ -31,10 +31,13 @@ export async function payNearFungibleRequest( throw new Error('Cannot pay without a paymentReference'); } - if (!network || !NearChains.isChainSupported(network)) { + if ( + !network || + !ChainManager.current().ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(network) + ) { throw new Error('Should be a Near network'); } - NearChains.assertChainSupported(network); + const chain = ChainManager.current().fromName(network, [ChainTypes.ECOSYSTEM.NEAR]); const amountToPay = getAmountToPay(request, amount).toString(); @@ -50,7 +53,7 @@ export async function payNearFungibleRequest( return processNearFungiblePayment( walletConnection, - network, + chain, amountToPay, paymentAddress, paymentReference, diff --git a/packages/payment-processor/src/payment/near-input-data.ts b/packages/payment-processor/src/payment/near-input-data.ts index bbad8237b3..b0736939e7 100644 --- a/packages/payment-processor/src/payment/near-input-data.ts +++ b/packages/payment-processor/src/payment/near-input-data.ts @@ -1,7 +1,7 @@ import { BigNumberish } from 'ethers'; import { WalletConnection } from 'near-api-js'; -import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { getAmountToPay, @@ -10,7 +10,7 @@ import { validateRequest, } from './utils'; import { INearTransactionCallback, processNearPayment } from './utils-near'; -import { NearChains } from '@requestnetwork/currency'; +import { ChainManager } from '@requestnetwork/chain'; /** * processes the transaction to pay a Near request. @@ -24,11 +24,18 @@ export async function payNearInputDataRequest( amount?: BigNumberish, callback?: INearTransactionCallback, ): Promise { - if (!request.currencyInfo.network || !NearChains.isChainSupported(request.currencyInfo.network)) { + if ( + !request.currencyInfo.network || + !ChainManager.current().ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported( + request.currencyInfo.network, + ) + ) { throw new Error('request.currencyInfo should be a Near network'); } - NearChains.assertChainSupported(request.currencyInfo.network); + const chain = ChainManager.current().fromName(request.currencyInfo.network, [ + ChainTypes.ECOSYSTEM.NEAR, + ]); validateRequest(request, ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN); const { paymentReference, paymentAddress } = getRequestPaymentValues(request); @@ -40,7 +47,7 @@ export async function payNearInputDataRequest( return processNearPayment( walletConnection, - request.currencyInfo.network, + chain, amountToPay, paymentAddress, paymentReference, diff --git a/packages/payment-processor/src/payment/swap-any-to-erc20.ts b/packages/payment-processor/src/payment/swap-any-to-erc20.ts index 24e0ef2200..12885e1038 100644 --- a/packages/payment-processor/src/payment/swap-any-to-erc20.ts +++ b/packages/payment-processor/src/payment/swap-any-to-erc20.ts @@ -6,6 +6,7 @@ import { ERC20SwapToConversion__factory } from '@requestnetwork/smart-contracts/ import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { + ensureEvmChain, getAmountToPay, getProvider, getProxyAddress, @@ -13,7 +14,7 @@ import { getSigner, validateConversionFeeProxyRequest, } from './utils'; -import { CurrencyManager, EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { IRequestPaymentOptions } from '../types'; import { IPreparedTransaction } from './prepared-transaction'; @@ -91,7 +92,7 @@ export function encodeSwapToPayAnyToErc20Request( if (!network) { throw new Error(`Currency in conversion settings must have a network`); } - EvmChains.assertChainSupported(network); + ensureEvmChain(network); const requestCurrency = currencyManager.fromStorageCurrency(request.currencyInfo); if (!requestCurrency) { diff --git a/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts b/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts index 6adc58379b..4163a93815 100644 --- a/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts +++ b/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts @@ -6,6 +6,7 @@ import { ClientTypes } from '@requestnetwork/types'; import { ITransactionOverrides } from './transaction-overrides'; import { + ensureEvmChain, getAmountToPay, getProvider, getProxyAddress, @@ -15,7 +16,6 @@ import { } from './utils'; import { IPreparedTransaction } from './prepared-transaction'; import { Erc20PaymentNetwork } from '@requestnetwork/payment-detection'; -import { EvmChains } from '@requestnetwork/currency'; /** * Details required for a token swap: @@ -85,7 +85,7 @@ export function prepareSwapToPayErc20FeeRequest( options?: ISwapTransactionOptions, ): IPreparedTransaction { const { network } = request.currencyInfo; - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); const encodedTx = encodeSwapToPayErc20FeeRequest( request, signerOrProvider, @@ -116,7 +116,7 @@ export function encodeSwapToPayErc20FeeRequest( ): string { const { paymentReference, paymentAddress, feeAddress, feeAmount, network } = getRequestPaymentValues(request); - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); validateErc20FeeProxyRequest(request, options?.amount, options?.feeAmount); diff --git a/packages/payment-processor/src/payment/swap-erc20.ts b/packages/payment-processor/src/payment/swap-erc20.ts index 655078de51..3dc6a30cd1 100644 --- a/packages/payment-processor/src/payment/swap-erc20.ts +++ b/packages/payment-processor/src/payment/swap-erc20.ts @@ -4,10 +4,9 @@ import { erc20SwapToPayArtifact } from '@requestnetwork/smart-contracts'; import { ClientTypes } from '@requestnetwork/types'; import { ITransactionOverrides } from './transaction-overrides'; -import { getProvider, getSigner } from './utils'; +import { ensureEvmChain, getProvider, getSigner } from './utils'; import { checkErc20Allowance, encodeApproveAnyErc20 } from './erc20'; import { IPreparedTransaction } from './prepared-transaction'; -import { EvmChains } from '@requestnetwork/currency'; /** * Processes the approval transaction of a given payment ERC20 to be spent by the swap router, @@ -56,10 +55,7 @@ export async function hasApprovalErc20ForSwapToPay( minAmount: BigNumberish, ): Promise { const { network } = request.currencyInfo; - if (!network) { - throw new Error('Request currency network is missing'); - } - EvmChains.assertChainSupported(network); + ensureEvmChain(network); return checkErc20Allowance( ownerAddress, erc20SwapToPayArtifact.getAddress(network), @@ -108,7 +104,7 @@ export function prepareApprovalErc20ForSwapToPay( amount?: BigNumber, ): IPreparedTransaction { const { network } = request.currencyInfo; - EvmChains.assertChainSupported(network!); + ensureEvmChain(network); const encodedTx = encodeApproveAnyErc20( paymentTokenAddress, erc20SwapToPayArtifact.getAddress(network), diff --git a/packages/payment-processor/src/payment/utils-near.ts b/packages/payment-processor/src/payment/utils-near.ts index 6b6e83770f..d7f7d523f5 100644 --- a/packages/payment-processor/src/payment/utils-near.ts +++ b/packages/payment-processor/src/payment/utils-near.ts @@ -4,7 +4,7 @@ import { NearConversionNativeTokenPaymentDetector, NearNativeTokenPaymentDetector, } from '@requestnetwork/payment-detection'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; /** @@ -183,7 +183,7 @@ export const processNearFungiblePayment = async ( viewMethods: [], }) as any; - const proxyAddress = erc20FeeProxyArtifact.getAddress(network, 'near'); + const proxyAddress = erc20FeeProxyArtifact.getAddress(network.name, 'near'); await fungibleContract.ft_transfer_call({ args: { receiver_id: proxyAddress, diff --git a/packages/payment-processor/src/payment/utils.ts b/packages/payment-processor/src/payment/utils.ts index ce6ae66247..009f306556 100644 --- a/packages/payment-processor/src/payment/utils.ts +++ b/packages/payment-processor/src/payment/utils.ts @@ -1,11 +1,12 @@ import { ethers, Signer, providers, BigNumber, BigNumberish, ContractTransaction } from 'ethers'; import { getDefaultProvider, getPaymentReference } from '@requestnetwork/payment-detection'; -import { ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { getCurrencyHash } from '@requestnetwork/currency'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { getPaymentNetworkExtension } from '@requestnetwork/payment-detection'; import { getReceivableTokenIdForRequest } from './erc20-transferable-receivable'; +import { ChainManager } from '@requestnetwork/chain'; /** @constant MAX_ALLOWANCE set to the max uint256 value */ export const MAX_ALLOWANCE = BigNumber.from(2).pow(256).sub(1); @@ -104,14 +105,10 @@ export function getPaymentExtensionVersion(request: ClientTypes.IRequestData): s export const getProxyNetwork = ( pn: ExtensionTypes.IState, currency: RequestLogicTypes.ICurrency, -): string => { - if (pn.values.network) { - return pn.values.network; - } - if (currency.network) { - return currency.network; - } - throw new Error('Payment currency must have a network'); +): ChainTypes.IVmChain => { + const chainName = pn.values.network || currency.network; + if (!chainName) throw new Error('Payment currency must have a network'); + return ChainManager.current().fromName(chainName, ChainTypes.VM_ECOSYSTEMS); }; /** @@ -120,7 +117,7 @@ export const getProxyNetwork = ( */ export function getPnAndNetwork(request: ClientTypes.IRequestData): { paymentNetwork: ExtensionTypes.IState; - network: string; + network: ChainTypes.IVmChain; } { const pn = getPaymentNetworkExtension(request); if (!pn) { @@ -137,13 +134,12 @@ export function getPnAndNetwork(request: ClientTypes.IRequestData): { export const getProxyAddress = ( request: ClientTypes.IRequestData, getDeploymentInformation: ( - network: ChainTypes.IEvmChain, + network: ChainTypes.IVmChain, version: string, ) => { address: string } | null, version?: string, ): string => { const { paymentNetwork, network } = getPnAndNetwork(request); - EvmChains.assertChainSupported(network); const deploymentInfo = getDeploymentInformation(network, version || paymentNetwork.version); if (!deploymentInfo) { throw new Error( @@ -415,3 +411,14 @@ export async function revokeErc20Approval( const tx = await signer.sendTransaction(preparedTx); return tx; } + +/** + * Typescript assertions cannot be used directly from class methods at the moment, + * see: https://github.com/microsoft/TypeScript/issues/36931#issuecomment-589753014 + * We use this helper function to avoid repetitions. + */ +export function ensureEvmChain(chainName?: string): asserts chainName is string { + const ensureEvm: ChainTypes.IEcosystem['assertChainNameSupported'] = + ChainManager.current().ecosystems[ChainTypes.ECOSYSTEM.EVM].assertChainNameSupported; + ensureEvm(chainName); +} diff --git a/packages/request-client.js/src/http-metamask-data-access.ts b/packages/request-client.js/src/http-metamask-data-access.ts index 7194f85055..fe9d6f74f2 100644 --- a/packages/request-client.js/src/http-metamask-data-access.ts +++ b/packages/request-client.js/src/http-metamask-data-access.ts @@ -21,7 +21,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { } = {}; private provider: ethers.providers.JsonRpcProvider | ethers.providers.Web3Provider; - private storageChain: ChainTypes.IEvmChain = ChainManager.getDefault().fromName('private', [ + private storageChain: ChainTypes.IEvmChain = ChainManager.current().fromName('private', [ ChainTypes.ECOSYSTEM.EVM, ]); @@ -78,7 +78,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { ): Promise { if (!this.storageChain) { const network = await this.provider.getNetwork(); - this.storageChain = ChainManager.getDefault().fromId(network.chainId.toString(), [ + this.storageChain = ChainManager.current().fromId(network.chainId.toString(), [ ChainTypes.ECOSYSTEM.EVM, ]); } diff --git a/packages/request-node/src/server.ts b/packages/request-node/src/server.ts index cf807bdf42..e8048786c0 100755 --- a/packages/request-node/src/server.ts +++ b/packages/request-node/src/server.ts @@ -7,7 +7,7 @@ import { getDataStorage } from './dataStorage'; import ConfirmedTransactionStore from './request/confirmedTransactionStore'; import { getEthereumStorageNetworkNameFromId } from '@requestnetwork/ethereum-storage'; import { SubgraphClient } from '@requestnetwork/thegraph-data-access'; -import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainManager } from '@requestnetwork/chain'; import { ChainTypes } from '@requestnetwork/types'; // Initialize the node logger @@ -18,7 +18,7 @@ const getStorageChain = (): ChainTypes.IEvmChain => { if (!network) { throw new Error(`Storage network not supported: ${config.getStorageNetworkId()}`); } - return ChainManager.getDefault().fromName(network, [ChainTypes.ECOSYSTEM.EVM]); + return ChainManager.current().fromName(network, [ChainTypes.ECOSYSTEM.EVM]); }; export const getRequestNode = (): RequestNode => { diff --git a/packages/smart-contracts/package.json b/packages/smart-contracts/package.json index 3ba30d487e..9d1e9c88fb 100644 --- a/packages/smart-contracts/package.json +++ b/packages/smart-contracts/package.json @@ -65,6 +65,7 @@ "@nomiclabs/hardhat-web3": "2.0.0", "@openzeppelin/contracts": "4.9.5", "@rainbow-me/fee-suggestions": "2.1.0", + "@requestnetwork/chain": "0.13.0", "@requestnetwork/currency": "0.13.0", "@requestnetwork/types": "0.40.0", "@requestnetwork/utils": "0.40.0", diff --git a/packages/smart-contracts/scripts-create2/tenderly.ts b/packages/smart-contracts/scripts-create2/tenderly.ts index 8c8d116056..fee9d3253e 100644 --- a/packages/smart-contracts/scripts-create2/tenderly.ts +++ b/packages/smart-contracts/scripts-create2/tenderly.ts @@ -4,7 +4,7 @@ import { ContractArtifact } from '../src/lib'; import { Contract } from 'ethers'; import * as console from 'console'; import { ChainTypes } from '@requestnetwork/types'; -import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainManager } from '@requestnetwork/chain'; const tenderlyBaseURL = 'https://api.tenderly.co'; const makeTenderlyClient = @@ -40,7 +40,7 @@ const supportedTenderlyChains: ChainTypes.IEvmChain[] = [ 'rinkeby', 'xdai', ].map((chainName: string) => - ChainManager.getDefault().fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]), + ChainManager.current().fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]), ); type TenderlyContract = { address: string; chainId: number }; @@ -62,7 +62,7 @@ export const tenderlyImportAll = async (hre: HardhatRuntimeEnvironmentExtended): const { networkName, address, version } = deployment; let deploymentChain: ChainTypes.IEvmChain; try { - deploymentChain = ChainManager.getDefault().fromName(networkName, [ + deploymentChain = ChainManager.current().fromName(networkName, [ ChainTypes.ECOSYSTEM.EVM, ]); } catch { diff --git a/packages/types/src/chain-types.ts b/packages/types/src/chain-types.ts index 48c5567d20..1e5e2f12b1 100644 --- a/packages/types/src/chain-types.ts +++ b/packages/types/src/chain-types.ts @@ -61,42 +61,35 @@ export type IChain = ChainTypeByEcosystem[ECOSYSTEM]; */ export type IVmChain = ChainTypeByEcosystem[VmChainEcosystem]; -// export interface IChainManager { -// chains: IChain[]; -// -// /** -// * Gets the name of a chain -// */ -// getName(chain: string | IChain): string; -// -// /** -// * Gets a supported chain from its name -// */ -// fromName( -// chainName: string, -// ecosystemsFilter?: T, -// ): ChainTypeByEcosystem[T[number]]; -// -// /** -// * Gets a supported chain from its ID -// */ -// fromId( -// chainId: string, -// ecosystemsFilter?: T, -// ): ChainTypeByEcosystem[T[number]]; -// -// /** -// * Get default chain manager -// */ -// getDefault(): IChainManager; -// -// /** -// * Returns true if both chains are equal or aliases. -// * The third argument "chainsEcosystem" is only needed when comparing chains as strings. -// */ -// isSameChain( -// chain1: string | IChain, -// chain2: string | IChain, -// chainsEcosystem?: ChainEcosystem[], -// ): boolean; -// } +export interface IEcosystem { + name: E; + chainClass: new (id: string, name: string, testnet?: boolean) => ChainTypeByEcosystem[E]; + chains: Record; + currencyType: RequestLogicTypes.CURRENCY; + chainNames: string[]; + assertChainNameSupported(chainName?: string): asserts chainName is string; + assertChainSupported(chain?: IChain): asserts chain is ChainTypeByEcosystem[E]; + isChainSupported(chainName?: string | IChain): boolean; + isSameChainFromString(chain1: string, chain2: string): boolean; +} + +export interface IChainManager { + chains: IChain[]; + ecosystems: { + [E in ECOSYSTEM]: IEcosystem; + }; + getEcosystemsByCurrencyType(currencyType: RequestLogicTypes.CURRENCY): ECOSYSTEM[]; + fromName( + chainName: string, + ecosystemsFilter?: T, + ): ChainTypeByEcosystem[T[number]]; + fromId( + chainId: string, + ecosystemsFilter?: T, + ): ChainTypeByEcosystem[T[number]]; + isSameChain( + chain1: string | IChain, + chain2: string | IChain, + chainsEcosystem?: readonly ECOSYSTEM[], + ): boolean; +} From fe631c98dcda62dd2455bba4d047cc66123b1ec0 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Mon, 19 Feb 2024 18:21:48 +0100 Subject: [PATCH 05/14] fix build errors --- .../scheduled/any-to-erc20-detector.test.ts | 4 +- .../scheduled/any-to-eth-detector.test.ts | 4 +- .../test/scheduled/erc20-fee-proxy.test.ts | 4 +- .../test/scheduled/erc777-stream.test.ts | 8 ++-- packages/integration-test/test/utils.ts | 27 ++++++++------ .../src/chainlinkConversionPathTools.ts | 37 +++++++++++-------- .../src/commands/chainlink/addAggregator.ts | 12 +++--- .../src/commands/chainlink/addAggregators.ts | 15 ++++---- .../commands/chainlink/aggregatorsUtils.ts | 18 ++++----- .../src/commands/chainlink/contractUtils.ts | 8 ++-- .../commands/chainlink/getConversionPath.ts | 7 ++-- .../chainlink/listMissingAggregators.ts | 10 ++--- packages/toolbox/src/commands/hash/submit.ts | 7 ++-- .../toolbox/src/commands/transaction/nonce.ts | 7 +++- .../toolbox/src/commands/transaction/retry.ts | 5 ++- .../toolbox/src/commands/transaction/utils.ts | 18 ++++----- 16 files changed, 105 insertions(+), 86 deletions(-) diff --git a/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts b/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts index 93781d3ded..e1122f6e8e 100644 --- a/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts +++ b/packages/integration-test/test/scheduled/any-to-erc20-detector.test.ts @@ -1,5 +1,5 @@ import { PaymentNetworkFactory } from '@requestnetwork/payment-detection'; -import { CurrencyTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyManager } from '@requestnetwork/currency'; import { mockAdvancedLogic } from './mocks'; @@ -8,7 +8,7 @@ import { createMockConversionErc20Request } from '../utils'; const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidEURRequest = { - network: 'matic' as ChainTypes.IEvmChain, + network: 'matic', requestId: '0117d7a59a48e5031b3c56c92621453149e4a4462dba6eaeb3271a995c4201448b', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: '5ddb1c1645ac2daf', diff --git a/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts b/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts index 9525865ce3..d60a9bb1fa 100644 --- a/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts +++ b/packages/integration-test/test/scheduled/any-to-eth-detector.test.ts @@ -1,5 +1,5 @@ import { PaymentNetworkFactory } from '@requestnetwork/payment-detection'; -import { CurrencyTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyManager } from '@requestnetwork/currency'; import { mockAdvancedLogic } from './mocks'; @@ -8,7 +8,7 @@ import { createMockConversionEthTokenRequest } from '../utils'; const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidEURRequest = { - network: 'matic' as ChainTypes.IEvmChain, + network: 'matic', requestId: '01814304b39265cbf0c2abb4f3c7e8432d1e2c8779be6022e545d25f95144360e0', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: 'b3f2e478374bff64', diff --git a/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts b/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts index fb745d0302..9a5c4feb89 100644 --- a/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts +++ b/packages/integration-test/test/scheduled/erc20-fee-proxy.test.ts @@ -1,6 +1,6 @@ import { CurrencyManager } from '@requestnetwork/currency'; import { PaymentNetworkFactory } from '@requestnetwork/payment-detection'; -import { CurrencyTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; import { Types, Utils } from '@requestnetwork/request-client.js'; import { mockAdvancedLogic } from './mocks'; @@ -20,7 +20,7 @@ automine(); const pnFactory = new PaymentNetworkFactory(mockAdvancedLogic, CurrencyManager.getDefault()); const paidRequest = { - network: 'matic' as ChainTypes.IEvmChain, + network: 'matic', requestId: '014bcd076791fb915af457df1d3f26c81ff66f7e278e4a18f0e48a1705572a6306', paymentAddress: '0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93', salt: '8c5ea6f8b4a14fe0', diff --git a/packages/integration-test/test/scheduled/erc777-stream.test.ts b/packages/integration-test/test/scheduled/erc777-stream.test.ts index 9813d6f3a2..aca5430701 100644 --- a/packages/integration-test/test/scheduled/erc777-stream.test.ts +++ b/packages/integration-test/test/scheduled/erc777-stream.test.ts @@ -1,6 +1,5 @@ import { SuperFluidPaymentDetector } from '@requestnetwork/payment-detection'; import { - CurrencyTypes, ExtensionTypes, IdentityTypes, PaymentTypes, @@ -16,9 +15,10 @@ const createMockRequest = ({ paymentAddress, salt, requestId, -}: Record<'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId', string> & { - network: ChainTypes.IEvmChain; -}): RequestLogicTypes.IRequest => ({ +}: Record< + 'network' | 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId', + string +>): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { network, diff --git a/packages/integration-test/test/utils.ts b/packages/integration-test/test/utils.ts index 232576b227..963ae3cc12 100644 --- a/packages/integration-test/test/utils.ts +++ b/packages/integration-test/test/utils.ts @@ -1,5 +1,5 @@ import { - CurrencyTypes, + ChainTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -14,9 +14,9 @@ export const createMockErc20FeeRequest = ({ feeAddress, feeAmount, }: Record< - 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', + 'network' | 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string -> & { network: ChainTypes.IEvmChain }): RequestLogicTypes.IRequest => ({ +>): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { network, @@ -56,10 +56,9 @@ export const createMockConversionErc20Request = ({ feeAmount, currency, }: Record< - 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', + 'network' | 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string > & { - network: ChainTypes.IEvmChain; currency: RequestLogicTypes.ICurrency; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, @@ -98,11 +97,15 @@ export const createMockNativeTokenRequest = ({ feeAmount, nativeTokenCode, }: Record< - 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount' | 'nativeTokenCode', + | 'network' + | 'paymentAddress' + | 'salt' + | 'requestId' + | 'feeAddress' + | 'feeAmount' + | 'nativeTokenCode', string -> & { - network: ChainTypes.IEvmChain; -}): RequestLogicTypes.IRequest => ({ +>): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { network, @@ -140,8 +143,10 @@ export const createMockConversionEthTokenRequest = ({ feeAddress, feeAmount, currency, -}: Record<'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string> & { - network: ChainTypes.IEvmChain; +}: Record< + 'network' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', + string +> & { currency: RequestLogicTypes.ICurrency; }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, diff --git a/packages/toolbox/src/chainlinkConversionPathTools.ts b/packages/toolbox/src/chainlinkConversionPathTools.ts index 0d122ecd42..73856c93b1 100644 --- a/packages/toolbox/src/chainlinkConversionPathTools.ts +++ b/packages/toolbox/src/chainlinkConversionPathTools.ts @@ -8,6 +8,7 @@ import { import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { retry } from '@requestnetwork/utils'; import { ChainTypes } from '@requestnetwork/types'; +import { ChainManager } from '@requestnetwork/chain/src'; export interface IOptions { network?: string; @@ -139,35 +140,39 @@ const getCurrency = (symbol: string) => { }; export const listAggregators = async (options?: IOptions): Promise => { - let networks = ['private', 'rinkeby', 'mainnet']; + let chains = [ + ChainManager.current().fromName('private', [ChainTypes.ECOSYSTEM.EVM]), + ChainManager.current().fromName('goerli', [ChainTypes.ECOSYSTEM.EVM]), + ChainManager.current().fromName('mainnet', [ChainTypes.ECOSYSTEM.EVM]), + ]; if (options?.network) { - EvmChains.assertChainSupported(options.network); - networks = [options.network]; + const chain = ChainManager.current().fromName(options.network, [ChainTypes.ECOSYSTEM.EVM]); + chains = [chain]; } // Create an Object to be used by a dijkstra algorithm to find the best path between two currencies const allAggregators: Record>> = {}; const aggregatorsNodesForDijkstra: Record>> = {}; - for (const network of networks) { - allAggregators[network] = {}; - const chainlinkConversionPathTools = new ChainlinkConversionPathTools(network, options); - allAggregators[network] = await chainlinkConversionPathTools.getAggregators(); + for (const chain of chains) { + allAggregators[chain.name] = {}; + const chainlinkConversionPathTools = new ChainlinkConversionPathTools(chain, options); + allAggregators[chain.name] = await chainlinkConversionPathTools.getAggregators(); // Include the reverse path of each aggregators - aggregatorsNodesForDijkstra[network] = {}; - for (let ccyIn in allAggregators[network]) { + aggregatorsNodesForDijkstra[chain.name] = {}; + for (let ccyIn in allAggregators[chain.name]) { ccyIn = ccyIn.toLowerCase(); - if (!aggregatorsNodesForDijkstra[network][ccyIn]) { - aggregatorsNodesForDijkstra[network][ccyIn] = {}; + if (!aggregatorsNodesForDijkstra[chain.name][ccyIn]) { + aggregatorsNodesForDijkstra[chain.name][ccyIn] = {}; } - for (let ccyOut in allAggregators[network][ccyIn]) { + for (let ccyOut in allAggregators[chain.name][ccyIn]) { ccyOut = ccyOut.toLowerCase(); - if (!aggregatorsNodesForDijkstra[network][ccyOut]) { - aggregatorsNodesForDijkstra[network][ccyOut] = {}; + if (!aggregatorsNodesForDijkstra[chain.name][ccyOut]) { + aggregatorsNodesForDijkstra[chain.name][ccyOut] = {}; } - aggregatorsNodesForDijkstra[network][ccyIn][ccyOut] = 1; - aggregatorsNodesForDijkstra[network][ccyOut][ccyIn] = 1; + aggregatorsNodesForDijkstra[chain.name][ccyIn][ccyOut] = 1; + aggregatorsNodesForDijkstra[chain.name][ccyOut][ccyIn] = 1; } } } diff --git a/packages/toolbox/src/commands/chainlink/addAggregator.ts b/packages/toolbox/src/commands/chainlink/addAggregator.ts index 7492f8da13..7285dc8253 100644 --- a/packages/toolbox/src/commands/chainlink/addAggregator.ts +++ b/packages/toolbox/src/commands/chainlink/addAggregator.ts @@ -2,7 +2,7 @@ import * as yargs from 'yargs'; import { runUpdate } from './contractUtils'; import { getAllAggregators, getCurrencyManager } from './aggregatorsUtils'; import assert from 'assert'; -import { EvmChains } from '@requestnetwork/currency'; +import { ChainTypes } from '@requestnetwork/types'; type Options = { dryRun: boolean; @@ -58,12 +58,12 @@ export const builder = (): yargs.Argv => export const handler = async (args: Options): Promise => { const { input, output, aggregator: aggregatorArg } = args; - const { network, list } = args; + const { network: chainName, list } = args; - EvmChains.assertChainSupported(network); const currencyManager = await getCurrencyManager(list); - const inputCcy = currencyManager.from(input, network) || currencyManager.from(input); - const outputCcy = currencyManager.from(output, network) || currencyManager.from(output); + const chain = currencyManager.chainManager.fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]); + const inputCcy = currencyManager.from(input, chain) || currencyManager.from(input); + const outputCcy = currencyManager.from(output, chain) || currencyManager.from(output); let inputAddress = input; if (!inputAddress.startsWith('0x')) { @@ -80,7 +80,7 @@ export const handler = async (args: Options): Promise => { const aggregator = aggregatorArg || `${inputCcy?.symbol} / ${outputCcy?.symbol}`; let aggregatorAddress = aggregator; if (!aggregatorAddress.startsWith('0x')) { - const aggregators = await getAllAggregators(network); + const aggregators = await getAllAggregators(chain); const newAggregator = aggregators.find((x) => x.name === aggregator); assert(newAggregator, `aggregator ${aggregator} not found`); aggregatorAddress = newAggregator?.proxyAddress; diff --git a/packages/toolbox/src/commands/chainlink/addAggregators.ts b/packages/toolbox/src/commands/chainlink/addAggregators.ts index 0b036e8988..7f5e9aa8f7 100644 --- a/packages/toolbox/src/commands/chainlink/addAggregators.ts +++ b/packages/toolbox/src/commands/chainlink/addAggregators.ts @@ -2,7 +2,8 @@ import * as yargs from 'yargs'; import inquirer from 'inquirer'; import { runUpdate } from './contractUtils'; import { Aggregator, getAvailableAggregators, getCurrencyManager } from './aggregatorsUtils'; -import { conversionSupportedNetworks, EvmChains } from '@requestnetwork/currency'; +import { conversionSupportedNetworks } from '@requestnetwork/currency'; +import { ChainTypes } from '@requestnetwork/types'; type Options = { dryRun: boolean; @@ -68,21 +69,21 @@ const pickAggregators = async (aggregators: Aggregator[], pairs?: string[]) => { }; export const handler = async (args: Options): Promise => { - const { network, pair } = args; + const { network: chainName, pair } = args; const pairs = pair?.map((x) => x.toLowerCase().trim()); const currencyManager = await getCurrencyManager(args.list); + const chain = currencyManager.chainManager.fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]); - EvmChains.assertChainSupported(network); - if (!conversionSupportedNetworks.includes(network)) { + if (!conversionSupportedNetworks.includes(chainName)) { console.warn( - `WARNING: ${network} is missing in conversionSupportedNetworks from the Currency package.`, - `Add '${network}: {}' to chainlinkCurrencyPairs, in currency/src/conversion-aggregators.ts.`, + `WARNING: ${chainName} is missing in conversionSupportedNetworks from the Currency package.`, + `Add '${chainName}: {}' to chainlinkCurrencyPairs, in currency/src/conversion-aggregators.ts.`, ); } const availableAggregators = await getAvailableAggregators( - network, + chain, currencyManager, pairs, args.listAll, diff --git a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts index 23ba43ed84..c2b578ac91 100644 --- a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts +++ b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts @@ -1,5 +1,5 @@ import { AggregatorsMap, CurrencyInput, CurrencyManager } from '@requestnetwork/currency'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; type Feed = { name: string; @@ -13,7 +13,7 @@ export type Aggregator = { aggregator: string; }; -const feedMap: Partial> = { +const feedMap: Partial> = { mainnet: ['mainnet', 'Ethereum Mainnet'], goerli: ['goerli', 'Goerli Testnet'], sepolia: ['sepolia', 'Sepolia Testnet'], @@ -28,7 +28,7 @@ const feedMap: Partial => { - const [feedName, networkName] = feedMap[network] || []; + const [feedName, networkName] = feedMap[network.name] || []; if (!feedName || !networkName) { throw new Error( `network ${network} not supported by feed provider. Is it supported by Chainlink?`, @@ -47,18 +47,18 @@ export const getAllAggregators = async (network: ChainTypes.IEvmChain): Promise< }; export const getAvailableAggregators = async ( - network: ChainTypes.IEvmChain, + chain: ChainTypes.IEvmChain, cm: CurrencyManager, pairs?: string[], listAll?: boolean, ): Promise => { - const feeds = await getAllAggregators(network); + const feeds = await getAllAggregators(chain); const missingAggregators: Aggregator[] = []; for (const feed of feeds) { const [from, to] = feed.name.split(' / '); - const fromCurrency = cm.from(from, network) || cm.from(from); - const toCurrency = cm.from(to, network) || cm.from(to); + const fromCurrency = cm.from(from, chain) || cm.from(from); + const toCurrency = cm.from(to, chain) || cm.from(to); if (pairs && !pairs.includes(`${from}-${to}`.toLowerCase())) { continue; } @@ -68,8 +68,8 @@ export const getAvailableAggregators = async ( fromCurrency.type !== RequestLogicTypes.CURRENCY.BTC && toCurrency.type !== RequestLogicTypes.CURRENCY.BTC && (fromCurrency.type === RequestLogicTypes.CURRENCY.ISO4217 || - fromCurrency.network === network) && - (listAll || !cm.getConversionPath(fromCurrency, toCurrency, network)) + fromCurrency.network === chain.name) && + (listAll || !cm.getConversionPath(fromCurrency, toCurrency, chain)) ) { missingAggregators.push({ name: feed.name, diff --git a/packages/toolbox/src/commands/chainlink/contractUtils.ts b/packages/toolbox/src/commands/chainlink/contractUtils.ts index 31ef9b2611..6a643cc20e 100644 --- a/packages/toolbox/src/commands/chainlink/contractUtils.ts +++ b/packages/toolbox/src/commands/chainlink/contractUtils.ts @@ -4,7 +4,8 @@ import { getDefaultProvider } from '@requestnetwork/payment-detection'; import { chainlinkConversionPath } from '@requestnetwork/smart-contracts'; import { GasFeeDefiner } from '@requestnetwork/ethereum-storage'; import { ChainlinkConversionPath } from '@requestnetwork/smart-contracts/types'; -import { EvmChains } from '@requestnetwork/currency'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainTypes } from '@requestnetwork/types'; export const runUpdate = async ( method: T, @@ -77,9 +78,8 @@ const connectChainlinkContracts = ({ dryRun, network, }: SharedOptions): ChainlinkContractWithVersion[] => { - EvmChains.assertChainSupported(network); - - const provider = getDefaultProvider(network); + const chain = ChainManager.current().fromName(network, [ChainTypes.ECOSYSTEM.EVM]); + const provider = getDefaultProvider(chain); const wallet = privateKey ? new Wallet(privateKey).connect(provider as any) // TODO diff --git a/packages/toolbox/src/commands/chainlink/getConversionPath.ts b/packages/toolbox/src/commands/chainlink/getConversionPath.ts index b4bfee0728..c75e296e5f 100644 --- a/packages/toolbox/src/commands/chainlink/getConversionPath.ts +++ b/packages/toolbox/src/commands/chainlink/getConversionPath.ts @@ -1,5 +1,6 @@ import * as yargs from 'yargs'; -import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyManager } from '@requestnetwork/currency'; +import { ChainTypes } from '@requestnetwork/types'; type Options = { to: string; from: string; network: string }; @@ -27,6 +28,6 @@ export const handler = (args: yargs.Arguments): void => { const currencyManager = CurrencyManager.getDefault(); const from = currencyManager.from(args.from)!; const to = currencyManager.from(args.to)!; - EvmChains.assertChainSupported(args.network); - console.log(currencyManager.getConversionPath(from, to, args.network)); + const chain = currencyManager.chainManager.fromName(args.network, [ChainTypes.ECOSYSTEM.EVM]); + console.log(currencyManager.getConversionPath(from, to, chain)); }; diff --git a/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts b/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts index c7816cca14..b793ebaac1 100644 --- a/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts +++ b/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts @@ -1,6 +1,6 @@ import * as yargs from 'yargs'; import { getAvailableAggregators, getCurrencyManager } from './aggregatorsUtils'; -import { EvmChains } from '@requestnetwork/currency'; +import { ChainTypes } from '@requestnetwork/types'; type Options = { network: string[]; @@ -30,11 +30,11 @@ export const builder = (): yargs.Argv => export const handler = async (args: Options): Promise => { const { list } = args; const currencyManager = await getCurrencyManager(list); - for (const network of args.network) { - EvmChains.assertChainSupported(network); - const available = await getAvailableAggregators(network, currencyManager); + for (const chainName of args.network) { + const chain = currencyManager.chainManager.fromName(chainName, [ChainTypes.ECOSYSTEM.EVM]); + const available = await getAvailableAggregators(chain, currencyManager); if (available.length > 0) { - console.log(network); + console.log(chainName); console.log(available.map((x) => x.name).join('\n')); console.log(); } diff --git a/packages/toolbox/src/commands/hash/submit.ts b/packages/toolbox/src/commands/hash/submit.ts index a1b75671db..c7d1db2fa6 100644 --- a/packages/toolbox/src/commands/hash/submit.ts +++ b/packages/toolbox/src/commands/hash/submit.ts @@ -5,7 +5,8 @@ import { InferArgs } from '../../types'; import yargs from 'yargs'; import { getWallet } from '../transaction/utils'; import { EthereumTransactionSubmitter, IpfsStorage } from '@requestnetwork/ethereum-storage'; -import { EvmChains } from '@requestnetwork/currency'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainTypes } from '@requestnetwork/types'; export const command = 'hash submit '; export const describe = 'Forces the submission of an IPFS hash to the Request HashStorage contract'; @@ -17,9 +18,9 @@ export const builder = (y: yargs.Argv) => .option('dryRun', { type: 'boolean', default: false }); export const handler = async (argv: yargs.Arguments>>) => { - EvmChains.assertChainSupported(argv.chainName); + const chain = ChainManager.current().fromName(argv.chainName, [ChainTypes.ECOSYSTEM.EVM]); - const wallet = await getWallet({ chainName: argv.chainName, dryRun: argv.dryRun }); + const wallet = await getWallet({ chain, dryRun: argv.dryRun }); const ipfsStorage = new IpfsStorage({ ipfsTimeout: 5000, }); diff --git a/packages/toolbox/src/commands/transaction/nonce.ts b/packages/toolbox/src/commands/transaction/nonce.ts index 9200f639ba..42120afbe9 100644 --- a/packages/toolbox/src/commands/transaction/nonce.ts +++ b/packages/toolbox/src/commands/transaction/nonce.ts @@ -2,6 +2,8 @@ import * as yargs from 'yargs'; import { InferArgs } from '../../types'; import { getProvider, getWallet } from './utils'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainTypes } from '@requestnetwork/types'; export const command = 'nonce'; export const describe = 'Gets a wallet nonce'; @@ -17,10 +19,11 @@ export const builder = (y: yargs.Argv) => { export const handler = async (argv: InferArgs>) => { let address = argv.address; - const provider = await getProvider(argv.chainName); + const chain = ChainManager.current().fromName(argv.chainName, [ChainTypes.ECOSYSTEM.EVM]); + const provider = await getProvider(chain); if (!address) { - const wallet = await getWallet({ chainName: argv.chainName, provider }); + const wallet = await getWallet({ chain, provider }); address = wallet.address; } const nonce = await provider.getTransactionCount(address); diff --git a/packages/toolbox/src/commands/transaction/retry.ts b/packages/toolbox/src/commands/transaction/retry.ts index 3aa66025fa..ede1bc1a93 100644 --- a/packages/toolbox/src/commands/transaction/retry.ts +++ b/packages/toolbox/src/commands/transaction/retry.ts @@ -5,6 +5,8 @@ import { InferArgs } from '../../types'; import yargs from 'yargs'; import { getWallet } from './utils'; import { providers, utils } from 'ethers'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { ChainTypes } from '@requestnetwork/types'; export const command = 'transaction retry '; export const describe = 'Retries sending a pending transaction stuck in the mempool'; @@ -18,7 +20,8 @@ export const builder = (y: yargs.Argv) => .option('dryRun', { type: 'boolean', default: false }); export const handler = async (argv: yargs.Arguments>>) => { - const wallet = await getWallet({ chainName: argv.chainName, dryRun: argv.dryRun }); + const chain = ChainManager.current().fromName(argv.chainName, [ChainTypes.ECOSYSTEM.EVM]); + const wallet = await getWallet({ chain, dryRun: argv.dryRun }); const tx = await wallet.provider.getTransaction(argv.txHash); diff --git a/packages/toolbox/src/commands/transaction/utils.ts b/packages/toolbox/src/commands/transaction/utils.ts index add6f95f62..ebf7539d50 100644 --- a/packages/toolbox/src/commands/transaction/utils.ts +++ b/packages/toolbox/src/commands/transaction/utils.ts @@ -1,19 +1,20 @@ import { getDefaultProvider } from '@requestnetwork/payment-detection'; import { providers, Wallet } from 'ethers'; +import { ChainTypes } from '@requestnetwork/types'; export const getWallet = async ({ - chainName, + chain, dryRun = false, provider, }: { - chainName: string; + chain: ChainTypes.IEvmChain; dryRun?: boolean; provider?: providers.Provider; }): Promise => { const privateKey = process.env.PRIVATE_KEY; if (!privateKey && !dryRun) throw new Error('env var PRIVATE_KEY is required'); if (!provider) { - provider = await getProvider(chainName); + provider = await getProvider(chain); } return dryRun @@ -21,16 +22,15 @@ export const getWallet = async ({ : new Wallet(privateKey || '').connect(provider); }; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const getProvider = async (chainName: string) => { - const chain = await getChainConfig(chainName); - if (chain) { - const rpc = chain.rpcUrls[0] +export const getProvider = async (chain: ChainTypes.IEvmChain) => { + const chainConfig = await getChainConfig(chain?.name); + if (chainConfig) { + const rpc = chainConfig.rpcUrls[0] .replace('{ALCHEMY_API_KEY}', process.env.ALCHEMY_API_KEY || '') .replace('{INFURA_API_KEY}', process.env.INFURA_API_KEY || ''); return new providers.StaticJsonRpcProvider(rpc); } - return getDefaultProvider(chainName); + return getDefaultProvider(chain); }; const getChainConfig = async ( From 3f30469da5b0866c381584457df233509f57e716 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Tue, 20 Feb 2024 11:27:40 +0100 Subject: [PATCH 06/14] fix build error --- packages/types/src/extensions/pn-any-to-eth-types.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/types/src/extensions/pn-any-to-eth-types.ts b/packages/types/src/extensions/pn-any-to-eth-types.ts index 8c120cea2f..ae654c1db7 100644 --- a/packages/types/src/extensions/pn-any-to-eth-types.ts +++ b/packages/types/src/extensions/pn-any-to-eth-types.ts @@ -1,4 +1,3 @@ -import { ChainName } from '../currency-types'; import * as PnAnyToAnyConversion from './pn-any-to-any-conversion-types'; /** Any to ETH reference-based payment network extension interface */ @@ -6,5 +5,5 @@ export type IAnyToEth = PnAnyToAnyConversion.IConversionReferenceBased & { - network: ChainName; + network: string; }; From fe52066457a88cd5f2c272dc17e03cf17fb73930 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Tue, 20 Feb 2024 11:40:03 +0100 Subject: [PATCH 07/14] fix lint --- .../src/extensions/payment-network/native-token.ts | 1 - packages/currency/src/iso4217.ts | 3 +-- packages/currency/src/native.ts | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/advanced-logic/src/extensions/payment-network/native-token.ts b/packages/advanced-logic/src/extensions/payment-network/native-token.ts index 3ecc8685ac..6197069d5c 100644 --- a/packages/advanced-logic/src/extensions/payment-network/native-token.ts +++ b/packages/advanced-logic/src/extensions/payment-network/native-token.ts @@ -3,7 +3,6 @@ import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-b import ReferenceBasedPaymentNetwork from './reference-based'; import { ICurrencyManager } from '@requestnetwork/currency'; -import * as chai from 'chai'; /** * Implementation of the payment network to pay in ETH based on input data. diff --git a/packages/currency/src/iso4217.ts b/packages/currency/src/iso4217.ts index ad2a4b6c82..7310ef4590 100644 --- a/packages/currency/src/iso4217.ts +++ b/packages/currency/src/iso4217.ts @@ -4,8 +4,7 @@ Data last updated 2018-08-29 */ -import { ISO4217CurrencyInput, NativeCurrencyInput } from './types'; -import { nativeCurrencies } from './native'; +import { ISO4217CurrencyInput } from './types'; import { RequestLogicTypes } from '@requestnetwork/types'; const iso4217Currencies = [ diff --git a/packages/currency/src/native.ts b/packages/currency/src/native.ts index 4157aac853..a9fc9cfc99 100644 --- a/packages/currency/src/native.ts +++ b/packages/currency/src/native.ts @@ -1,5 +1,5 @@ import { RequestLogicTypes } from '@requestnetwork/types'; -import { NativeCurrency, NativeCurrencyInput, TokenMap } from './types'; +import { NativeCurrencyInput, TokenMap } from './types'; export const nativeCurrencies: Record< RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH, From c6b8cee26d9cadb1e51ab74ddc051636d4d57fc9 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Tue, 20 Feb 2024 11:45:21 +0100 Subject: [PATCH 08/14] fix test --- .../extensions/payment-network/any-to-eth-proxy.test.ts | 2 +- .../test/extensions/payment-network/native-token.test.ts | 6 +++--- .../test/erc20/transferable-receivable.test.ts | 2 +- .../test/erc777/superfluid-detector.test.ts | 2 +- .../test/payment/encoder-approval.test.ts | 4 ++-- .../test/payment/encoder-payment.test.ts | 4 ++-- .../test/payment/erc20-escrow-payment.test.ts | 4 +--- .../payment-processor/test/payment/erc20-proxy.test.ts | 2 +- .../payment-processor/test/payment/erc777-stream.test.ts | 2 +- .../test/payment/eth-batch-proxy.test.ts | 2 +- .../payment-processor/test/payment/eth-fee-proxy.test.ts | 2 +- .../payment-processor/test/payment/eth-input-data.test.ts | 2 +- packages/payment-processor/test/payment/eth-proxy.test.ts | 2 +- .../test/payment/swap-erc20-fee-proxy.test.ts | 8 +++----- packages/smart-contracts/test/lib/artifact.test.ts | 6 +++--- 15 files changed, 23 insertions(+), 27 deletions(-) diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts index a05c8b45d2..7916d35228 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts @@ -146,7 +146,7 @@ describe('extensions/payment-network/ethereum/any-to-eth-fee-proxy-contract', () requestCreatedNoExtension.currency = { type: RequestLogicTypes.CURRENCY.ETH, value: 'invalid value', - network: 'invalid network' as ChainTypes.IEvmChain, + network: 'invalid network', }; const action: ExtensionTypes.IAction = deepCopy( diff --git a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts index bfd6985d8c..3e84745609 100644 --- a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts @@ -11,7 +11,7 @@ import { } from '../../utils/payment-network/mocked_native_data'; import { AdvancedLogic } from '../../../src'; import { arbitraryTimestamp, payeeRaw } from '../../utils/test-data-generator'; -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyManager } from '@requestnetwork/currency'; import NearTestnetNativeNativePaymentNetwork from '../../../src/extensions/payment-network/near/near-testnet-native'; @@ -154,7 +154,7 @@ describe('extensions/payment-network/native-token', () => { expect(() => { new NearNativePaymentNetwork(currencyManager).createCreationAction({ ...partialCreationParams, - paymentNetworkName: 'another-chain' as ChainTypes.INearChain, + paymentNetworkName: 'another-chain', }); }).toThrowError( `Payment network 'another-chain' is not supported by this extension (only aurora)`, @@ -331,7 +331,7 @@ describe('extensions/payment-network/native-token', () => { }); it('throws on a wrong payment network', () => { const advancedLogic = new AdvancedLogic(currencyManager); - const wrongNetwork = `wrong network` as ChainTypes.IEvmChain; + const wrongNetwork = `wrong network`; const wrongNativeTokenRequestState: typeof requestStateNoExtensions = { ...requestStateNoExtensions, diff --git a/packages/payment-detection/test/erc20/transferable-receivable.test.ts b/packages/payment-detection/test/erc20/transferable-receivable.test.ts index ea251d7559..a3a3f872a9 100644 --- a/packages/payment-detection/test/erc20/transferable-receivable.test.ts +++ b/packages/payment-detection/test/erc20/transferable-receivable.test.ts @@ -379,7 +379,7 @@ describe('api/erc20/transferable-receivable-contract', () => { txHash: '0x3e2d6cc2534b1d340ba2954f34e6cc819d6da64ff76863ea89c6d34b15d13c97', from: '0x186e7fe6c34ea0eca7f9c2fd29651fc0443e3f29', to: paymentAddress, - network: 'rinkeby' as ChainTypes.IEvmChain, + network: 'rinkeby', salt: '0ee84db293a752c6', amount: '30000000000000', requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1', diff --git a/packages/payment-detection/test/erc777/superfluid-detector.test.ts b/packages/payment-detection/test/erc777/superfluid-detector.test.ts index 1b60fa8b87..01cbdd957f 100644 --- a/packages/payment-detection/test/erc777/superfluid-detector.test.ts +++ b/packages/payment-detection/test/erc777/superfluid-detector.test.ts @@ -36,7 +36,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { const baseRequestData = { creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { - network: 'private' as ChainTypes.IEvmChain, + network: 'private', type: RequestLogicTypes.CURRENCY.ERC20, value: '0x9FBDa871d559710256a2502A2517b794B482Db40', // local ERC20 token }, diff --git a/packages/payment-processor/test/payment/encoder-approval.test.ts b/packages/payment-processor/test/payment/encoder-approval.test.ts index 3d3f4e6f0a..5481c60082 100644 --- a/packages/payment-processor/test/payment/encoder-approval.test.ts +++ b/packages/payment-processor/test/payment/encoder-approval.test.ts @@ -257,12 +257,12 @@ beforeAll(async () => { await revokeErc20Approval(proxyERC20Conv, alphaContractAddress, wallet); proxyERC20Swap = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, + validRequestERC20FeeProxy.currencyInfo.network!, ); await revokeErc20Approval(proxyERC20Swap, alphaContractAddress, wallet); proxyERC20SwapConv = erc20SwapConversionArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, + validRequestERC20FeeProxy.currencyInfo.network!, ); await revokeErc20Approval(proxyERC20SwapConv, alphaContractAddress, wallet); }); diff --git a/packages/payment-processor/test/payment/encoder-payment.test.ts b/packages/payment-processor/test/payment/encoder-payment.test.ts index b1fd9c7ea7..26af66b180 100644 --- a/packages/payment-processor/test/payment/encoder-payment.test.ts +++ b/packages/payment-processor/test/payment/encoder-payment.test.ts @@ -316,7 +316,7 @@ describe('Payment encoder handles ERC20 Swap Proxy', () => { }); const proxyAddress = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network! as ChainTypes.IEvmChain, + validRequestERC20FeeProxy.currencyInfo.network!, ); expect(paymentTransaction).toEqual({ @@ -335,7 +335,7 @@ describe('Payment encoder handles ERC20 Swap & Conversion Proxy', () => { }); const proxyAddress = erc20SwapConversionArtifact.getAddress( - alphaConversionSettings.currency.network as ChainTypes.IEvmChain, + alphaConversionSettings.currency.network, ); expect(paymentTransaction).toEqual({ diff --git a/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts b/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts index 11c335b040..818df0c63c 100644 --- a/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts +++ b/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts @@ -67,9 +67,7 @@ const validRequest: ClientTypes.IRequestData = { version: '1.0', }; -const escrowAddress = erc20EscrowToPayArtifact.getAddress( - validRequest.currencyInfo.network! as ChainTypes.IEvmChain, -); +const escrowAddress = erc20EscrowToPayArtifact.getAddress(validRequest.currencyInfo.network!); const payerAddress = wallet.address; describe('erc20-escrow-payment tests:', () => { diff --git a/packages/payment-processor/test/payment/erc20-proxy.test.ts b/packages/payment-processor/test/payment/erc20-proxy.test.ts index f2f61a4ce1..f97a8ae9c2 100644 --- a/packages/payment-processor/test/payment/erc20-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-proxy.test.ts @@ -92,7 +92,7 @@ describe('payErc20ProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect(payErc20ProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-erc20-proxy-contract request', ); diff --git a/packages/payment-processor/test/payment/erc777-stream.test.ts b/packages/payment-processor/test/payment/erc777-stream.test.ts index 0ba334e0c2..c2f983b1f9 100644 --- a/packages/payment-processor/test/payment/erc777-stream.test.ts +++ b/packages/payment-processor/test/payment/erc777-stream.test.ts @@ -111,7 +111,7 @@ describe('erc777-stream', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect(payErc777StreamRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-erc777-stream request', ); diff --git a/packages/payment-processor/test/payment/eth-batch-proxy.test.ts b/packages/payment-processor/test/payment/eth-batch-proxy.test.ts index e40d497aa6..6ed4daa24f 100644 --- a/packages/payment-processor/test/payment/eth-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-batch-proxy.test.ts @@ -106,7 +106,7 @@ describe('payBatchProxyRequest', () => { it('should throw an error if in one request, currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect( payBatchProxyRequest([validRequest, request], batchVersion, wallet, batchFee), ).rejects.toThrowError( diff --git a/packages/payment-processor/test/payment/eth-fee-proxy.test.ts b/packages/payment-processor/test/payment/eth-fee-proxy.test.ts index 99e2bee54b..dba583ef8d 100644 --- a/packages/payment-processor/test/payment/eth-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-fee-proxy.test.ts @@ -86,7 +86,7 @@ describe('payEthFeeProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect(payEthFeeProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-fee-proxy-contract request', ); diff --git a/packages/payment-processor/test/payment/eth-input-data.test.ts b/packages/payment-processor/test/payment/eth-input-data.test.ts index db548bc304..d645e5a56f 100644 --- a/packages/payment-processor/test/payment/eth-input-data.test.ts +++ b/packages/payment-processor/test/payment/eth-input-data.test.ts @@ -81,7 +81,7 @@ describe('payEthInputDataRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect(payEthInputDataRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-input-data request', ); diff --git a/packages/payment-processor/test/payment/eth-proxy.test.ts b/packages/payment-processor/test/payment/eth-proxy.test.ts index 880932df17..e9ebee4294 100644 --- a/packages/payment-processor/test/payment/eth-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-proxy.test.ts @@ -87,7 +87,7 @@ describe('payEthProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect(payEthProxyRequest(request, wallet)).rejects.toThrowError( 'request cannot be processed, or is not an pn-eth-input-data request', ); diff --git a/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts b/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts index 0528f84214..9ce8525d04 100644 --- a/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/swap-erc20-fee-proxy.test.ts @@ -85,7 +85,7 @@ describe('swap-erc20-fee-proxy', () => { beforeAll(async () => { // revoke erc20SwapToPay approval await revokeErc20Approval( - erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network! as ChainTypes.IEvmChain), + erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network!), alphaErc20Address, wallet.provider, ); @@ -94,9 +94,7 @@ describe('swap-erc20-fee-proxy', () => { beforeAll(async () => { // revoke erc20SwapToPay approval await revokeErc20Approval( - erc20SwapToPayArtifact.getAddress( - validRequest.currencyInfo.network! as ChainTypes.IEvmChain, - ), + erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network!), alphaErc20Address, wallet.provider, ); @@ -124,7 +122,7 @@ describe('swap-erc20-fee-proxy', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = '' as ChainTypes.IEvmChain; + request.currencyInfo.network = ''; await expect( swapErc20FeeProxyRequest(request, wallet, validSwapSettings), ).rejects.toThrowError('Unsupported chain '); diff --git a/packages/smart-contracts/test/lib/artifact.test.ts b/packages/smart-contracts/test/lib/artifact.test.ts index 0c47a510ca..1d4059cd2c 100644 --- a/packages/smart-contracts/test/lib/artifact.test.ts +++ b/packages/smart-contracts/test/lib/artifact.test.ts @@ -55,9 +55,9 @@ describe('Artifact', () => { }); it('throws for a non-existing network', () => { - expect(() => - erc20ProxyArtifact.getDeploymentInformation('fakenetwork' as ChainTypes.IEvmChain), - ).toThrowError(`No deployment for network: fakenetwork`); + expect(() => erc20ProxyArtifact.getDeploymentInformation('fakenetwork')).toThrowError( + `No deployment for network: fakenetwork`, + ); }); it('throws for a non-existing version', () => { From 5cefa05c446c2a44689080fc307b1079f4eb7ccc Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Tue, 20 Feb 2024 14:59:19 +0100 Subject: [PATCH 09/14] fix type issues in tests --- .../payment-network/address-based.test.ts | 9 +++- packages/chain/src/chains/chain-abstract.ts | 1 - packages/chain/test/chain-utils.test.ts | 39 --------------- packages/chain/test/chain.test.ts | 50 +++++++++++++++++++ 4 files changed, 57 insertions(+), 42 deletions(-) delete mode 100644 packages/chain/test/chain-utils.test.ts create mode 100644 packages/chain/test/chain.test.ts diff --git a/packages/advanced-logic/test/extensions/payment-network/address-based.test.ts b/packages/advanced-logic/test/extensions/payment-network/address-based.test.ts index 90eb197ae9..390cc9efcd 100644 --- a/packages/advanced-logic/test/extensions/payment-network/address-based.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/address-based.test.ts @@ -1,6 +1,7 @@ import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; -import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import AddressBasedPaymentNetwork from '../../../src/extensions/payment-network/address-based'; +import { ChainManager } from '@requestnetwork/chain'; describe('extensions/payment-network/address-based', () => { it('address validation should throw when using unsupported currency type', () => { @@ -37,7 +38,11 @@ describe('extensions/payment-network/address-based', () => { super(CurrencyManager.getDefault(), extensionId, currentVersion, supportedCurrencyType); } public testIsValidAddress() { - this.isValidAddressForSymbolAndNetwork('test', 'test', 'mainnet'); + this.isValidAddressForSymbolAndNetwork( + 'test', + 'test', + ChainManager.current().fromName('mainnet', [ChainTypes.ECOSYSTEM.EVM]), + ); } } expect(() => { diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts index b86358b353..2502b121e2 100644 --- a/packages/chain/src/chains/chain-abstract.ts +++ b/packages/chain/src/chains/chain-abstract.ts @@ -12,7 +12,6 @@ export abstract class ChainAbstract implements ChainTypes.IChainCommon { ) { this.name = this.name.toLowerCase(); } - public eq(chain: ChainTypes.IChain): boolean { return this === chain || (this.ecosystem === chain.ecosystem && this.id === chain.id); } diff --git a/packages/chain/test/chain-utils.test.ts b/packages/chain/test/chain-utils.test.ts deleted file mode 100644 index aa08e06209..0000000000 --- a/packages/chain/test/chain-utils.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { EvmChains, NearChains, isSameChain } from '../src/index'; - -describe('isSameChain', () => { - it('Should return true for 2 identical EVMs', () => { - expect(isSameChain('arbitrum-one', 'arbitrum-one')).toBe(true); - }); - it('Should return false for 2 different EVMs', () => { - expect(isSameChain('mainnet', 'arbitrum-one')).toBe(false); - }); - // FIXME: get rid of all aurora alias and mentions - it('Should return true for 2 identical NEAR', () => { - expect(isSameChain('aurora-testnet', 'near-testnet')).toBe(true); - }); - it('Should return false for 2 different chains on 2 different ecosystems', () => { - expect(isSameChain('aurora-testnet', 'arbitrum-one')).toBe(false); - }); -}); - -describe('isChainSupported', () => { - describe('NearChains', () => { - it('returns true for near', () => { - expect(NearChains.isChainSupported('near')).toEqual(true); - }); - it('returns true for aurora', () => { - expect(NearChains.isChainSupported('aurora')).toEqual(true); - }); - it('returns false for mainnet', () => { - expect(NearChains.isChainSupported('mainnet')).toEqual(false); - }); - }); - describe('EvmChains', () => { - it('returns true for mainnet', () => { - expect(EvmChains.isChainSupported('mainnet')).toEqual(true); - }); - it('returns false for near', () => { - expect(EvmChains.isChainSupported('near')).toEqual(false); - }); - }); -}); diff --git a/packages/chain/test/chain.test.ts b/packages/chain/test/chain.test.ts new file mode 100644 index 0000000000..ac971d40d0 --- /dev/null +++ b/packages/chain/test/chain.test.ts @@ -0,0 +1,50 @@ +import EvmEcosystem from '../src/chains/evm/evm-ecosystem'; +import { ChainManager } from '../src'; +import { ChainTypes } from '@requestnetwork/types'; +import NearEcosystem from '../src/chains/near/near-ecosystem'; + +describe('chain equality', () => { + it('Should return true for 2 identical EVMs', () => { + const chain1 = ChainManager.current().fromName('arbitrum-one', [ChainTypes.ECOSYSTEM.EVM]); + const chain2 = ChainManager.current().fromName('arbitrum-one', [ChainTypes.ECOSYSTEM.EVM]); + expect(chain1.eq(chain2)).toBe(true); + }); + it('Should return false for 2 different EVMs', () => { + const chain1 = ChainManager.current().fromName('mainnet', [ChainTypes.ECOSYSTEM.EVM]); + const chain2 = ChainManager.current().fromName('arbitrum-one', [ChainTypes.ECOSYSTEM.EVM]); + expect(chain1.eq(chain2)).toBe(false); + }); + // FIXME: get rid of all aurora alias and mentions + it('Should return true for 2 identical NEAR', () => { + const chain1 = ChainManager.current().fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]); + const chain2 = ChainManager.current().fromName('near-testnet', [ChainTypes.ECOSYSTEM.NEAR]); + expect(chain1.eq(chain2)).toBe(true); + }); + it('Should return false for 2 different chains on 2 different ecosystems', () => { + const chain2 = ChainManager.current().fromName('arbitrum-one', [ChainTypes.ECOSYSTEM.EVM]); + const chain1 = ChainManager.current().fromName('aurora-testnet', [ChainTypes.ECOSYSTEM.NEAR]); + expect(chain1.eq(chain2)).toBe(false); + }); +}); + +describe('ecosystem isChainSupported', () => { + describe('NearEcosystem', () => { + it('returns true for near', () => { + expect(NearEcosystem.isChainSupported('near')).toEqual(true); + }); + it('returns true for aurora', () => { + expect(NearEcosystem.isChainSupported('aurora')).toEqual(true); + }); + it('returns false for mainnet', () => { + expect(NearEcosystem.isChainSupported('mainnet')).toEqual(false); + }); + }); + describe('EvmEcosystem', () => { + it('returns true for mainnet', () => { + expect(EvmEcosystem.isChainSupported('mainnet')).toEqual(true); + }); + it('returns false for near', () => { + expect(EvmEcosystem.isChainSupported('near')).toEqual(false); + }); + }); +}); From 101b5e374c00773b4e299e05d931cb1b97c01330 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Wed, 21 Feb 2024 15:43:33 +0100 Subject: [PATCH 10/14] fix unrecognized extension --- packages/advanced-logic/src/advanced-logic.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index b65aa42f88..5c4423a1d6 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -131,6 +131,9 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic requestState: RequestLogicTypes.IRequest, ): ExtensionTypes.IExtension { const id: ExtensionTypes.ID = extensionAction.id; + if (!(id in AdvancedLogic.supportedEcosystemsForExtension)) { + throw Error(`extension not recognized, id: ${id}`); + } const ecosystems = AdvancedLogic.supportedEcosystemsForExtension[id]; if (!ecosystems) { throw Error(`chain ecosystem not recognized for extension: ${id}`); @@ -144,7 +147,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic return extension; } - public getExtensionsForChain( + protected getExtensionsForChain( chain?: ChainTypes.IChain, ): Record { const extensions: Record = { From c1621b9b3816e4d3bb7a2e7cc0e4337fd62ff88e Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Wed, 21 Feb 2024 16:53:15 +0100 Subject: [PATCH 11/14] fix more tests related to chain initialization --- packages/advanced-logic/src/advanced-logic.ts | 13 +++++++------ .../payment-network/erc20/fee-proxy-contract.ts | 2 +- .../payment-network/any-to-eth-proxy.test.ts | 2 +- .../extensions/payment-network/any-to-near.test.ts | 4 ++-- .../erc20/fee-proxy-contract.test.ts | 11 ++++++++--- .../extensions/payment-network/native-token.test.ts | 8 ++++---- packages/chain/src/chain-manager.ts | 6 +++--- packages/chain/src/chains/btc/btc-chain.ts | 3 +-- packages/chain/src/chains/btc/btc-ecosystem.ts | 7 ++----- packages/chain/src/chains/chain-abstract.ts | 3 --- .../src/chains/declarative/declarative-chain.ts | 3 +-- .../src/chains/declarative/declarative-ecosystem.ts | 11 ++++++----- packages/chain/src/chains/ecosystem-abstract.ts | 4 ++-- packages/chain/src/chains/evm/evm-chain.ts | 3 +-- packages/chain/src/chains/evm/evm-ecosystem.ts | 6 +++++- packages/chain/src/chains/near/near-chain.ts | 3 +-- packages/chain/src/chains/near/near-ecosystem.ts | 5 ++++- packages/chain/src/chains/utils.ts | 8 ++++++-- packages/currency/src/currency-manager.ts | 4 ++-- packages/types/src/chain-types.ts | 7 +------ 20 files changed, 58 insertions(+), 55 deletions(-) diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index 5c4423a1d6..87d0e4673e 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -41,7 +41,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic [ExtensionTypes.ID.CONTENT_DATA]: [ECOSYSTEM.EVM], [ExtensionTypes.PAYMENT_NETWORK_ID.BITCOIN_ADDRESS_BASED]: [ECOSYSTEM.BTC], [ExtensionTypes.PAYMENT_NETWORK_ID.TESTNET_BITCOIN_ADDRESS_BASED]: [ECOSYSTEM.BTC], - [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_DECLARATIVE]: [ECOSYSTEM.BTC], + [ExtensionTypes.PAYMENT_NETWORK_ID.ANY_DECLARATIVE]: [], [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_ADDRESS_BASED]: VM_ECOSYSTEMS, [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_PROXY_CONTRACT]: VM_ECOSYSTEMS, [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT]: VM_ECOSYSTEMS, @@ -173,14 +173,15 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic [ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_TRANSFERABLE_RECEIVABLE]: this.extensions.erc20TransferableReceivable, }; + if (!chain) return extensions; // filter-out unsupported extensions for this chain ecosystem return (Object.keys(extensions) as ExtensionTypes.ID[]).reduce( (filteredExtensions, extensionId) => { - filteredExtensions[extensionId] = - chain && - AdvancedLogic.supportedEcosystemsForExtension[extensionId].includes(chain.ecosystem) - ? extensions[extensionId] - : undefined; + filteredExtensions[extensionId] = AdvancedLogic.supportedEcosystemsForExtension[ + extensionId + ].includes(chain.ecosystem) + ? extensions[extensionId] + : undefined; return filteredExtensions; }, {} as Record, diff --git a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts index 3973e9e0a0..4c0facaccf 100644 --- a/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts +++ b/packages/advanced-logic/src/extensions/payment-network/erc20/fee-proxy-contract.ts @@ -65,7 +65,7 @@ export default class Erc20FeeProxyPaymentNetwork< super.validate(request, extensionAction); } - // Override `isValidAddress` to account for network-specific instanciation (non-EVM only) + // Override `isValidAddress` to account for network-specific instantiation (non-EVM only) protected isValidAddress(address: string): boolean { if ( this.currencyManager.chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported( diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts index 7916d35228..9c33c9d562 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-eth-proxy.test.ts @@ -1,4 +1,4 @@ -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts index 57a87589e6..4a94829470 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts @@ -8,7 +8,7 @@ import { } from '../../utils/payment-network/any/generator-data-create'; import { AdvancedLogic } from '../../../src'; import { arbitraryTimestamp, payeeRaw, payerRaw } from '../../utils/test-data-generator'; -import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import AnyToNearPaymentNetwork from '../../../src/extensions/payment-network/near/any-to-near'; import AnyToNativeTokenPaymentNetwork from '../../../src/extensions/payment-network/any-to-native'; import { CurrencyManager } from '@requestnetwork/currency'; @@ -206,7 +206,7 @@ describe('extensions/payment-network/any-to-native-token', () => { expect(() => { new AnyToNearPaymentNetwork(currencyManager).createCreationAction({ ...partialCreationParams, - network: 'another-chain' as ChainTypes.INearChain, + network: 'another-chain', }); }).toThrowError( `Payment network 'another-chain' is not supported by this extension (only aurora)`, diff --git a/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts b/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts index d3e831c9a7..d9c07a095d 100644 --- a/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts @@ -1,4 +1,4 @@ -import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import * as DataERC20FeeAddData from '../../../utils/payment-network/erc20/fee-proxy-contract-add-data-generator'; import * as DataERC20FeeCreate from '../../../utils/payment-network/erc20/fee-proxy-contract-create-data-generator'; @@ -7,6 +7,7 @@ import * as TestData from '../../../utils/test-data-generator'; import { deepCopy } from '@requestnetwork/utils'; import { CurrencyManager } from '@requestnetwork/currency'; import { AdvancedLogic } from '../../../../src'; +import { ChainManager } from '@requestnetwork/chain'; const currencyManager = new CurrencyManager(CurrencyManager.getDefaultList()); @@ -118,7 +119,9 @@ describe('extensions/payment-network/erc20/fee-proxy-contract', () => { }); describe('on Near testnet', () => { - const extension = advancedLogic.getFeeProxyContractErc20ForNetwork('near-testnet'); + const extension = advancedLogic.getFeeProxyContractErc20ForNetwork( + ChainManager.current().fromName('near-testnet', [ChainTypes.ECOSYSTEM.NEAR]), + ); it('can create a create action with all parameters', () => { expect( extension.createCreationAction({ @@ -382,7 +385,9 @@ describe('extensions/payment-network/erc20/fee-proxy-contract', () => { }); describe('on Near testnet', () => { - const extension = advancedLogic.getFeeProxyContractErc20ForNetwork('near-testnet'); + const extension = advancedLogic.getFeeProxyContractErc20ForNetwork( + ChainManager.current().fromName('near-testnet', [ChainTypes.ECOSYSTEM.NEAR]), + ); it('can applyActionToExtensions of creation', () => { expect( extension.applyActionToExtension( diff --git a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts index 3e84745609..6ab653ec13 100644 --- a/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/native-token.test.ts @@ -157,7 +157,7 @@ describe('extensions/payment-network/native-token', () => { paymentNetworkName: 'another-chain', }); }).toThrowError( - `Payment network 'another-chain' is not supported by this extension (only aurora)`, + `No chain found with "name=another-chain" for ecosystem(s) "DECLARATIVE,EVM,NEAR"`, ); }); it('createCreationAction() throws without payment network', () => { @@ -274,7 +274,7 @@ describe('extensions/payment-network/native-token', () => { arbitraryTimestamp, ); }).toThrowError( - 'Cannot apply action for network aurora-testnet on state with payment network: aurora', + 'Cannot apply action for extension aurora-testnet on state with chain: aurora', ); }); it('throws when adding a payment address a different network', () => { @@ -357,7 +357,7 @@ describe('extensions/payment-network/native-token', () => { payeeRaw.identity, arbitraryTimestamp, ), - ).toThrowError('extension with id: pn-native-token not found for network: wrong network'); + ).toThrowError('No chain found with "name=wrong network" for ecosystem(s) "NEAR"'); }); it('throws on a different payment network', () => { const advancedLogic = new AdvancedLogic(currencyManager); @@ -384,7 +384,7 @@ describe('extensions/payment-network/native-token', () => { arbitraryTimestamp, ), ).toThrowError( - `Cannot apply action for network ${mainnetTestCase.wrongCurrency.network} on state with payment network: ${mainnetTestCase.currency.network}`, + `Cannot apply action for extension ${mainnetTestCase.wrongCurrency.network} on state with chain: ${mainnetTestCase.currency.network}`, ); }); diff --git a/packages/chain/src/chain-manager.ts b/packages/chain/src/chain-manager.ts index fcd09ee8d0..097e31b1e7 100644 --- a/packages/chain/src/chain-manager.ts +++ b/packages/chain/src/chain-manager.ts @@ -42,9 +42,9 @@ export class ChainManager implements ChainTypes.IChainManager { } getEcosystemsByCurrencyType(currencyType: RequestLogicTypes.CURRENCY): ChainTypes.ECOSYSTEM[] { - return (Object.keys(this.ecosystems) as ChainTypes.ECOSYSTEM[]).filter((ecosystemName) => - this.ecosystems[ecosystemName].currencyType.includes(currencyType), - ); + return (Object.keys(this.ecosystems) as ChainTypes.ECOSYSTEM[]).filter((ecosystemName) => { + return this.ecosystems[ecosystemName].currencyTypes.includes(currencyType); + }); } static getName(chain: string | ChainTypes.IChain): string { diff --git a/packages/chain/src/chains/btc/btc-chain.ts b/packages/chain/src/chains/btc/btc-chain.ts index 9f6dc20b02..cb19f87ac8 100644 --- a/packages/chain/src/chains/btc/btc-chain.ts +++ b/packages/chain/src/chains/btc/btc-chain.ts @@ -1,7 +1,6 @@ import { ChainAbstract } from '../chain-abstract'; -import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; export class BtcChain extends ChainAbstract implements ChainTypes.IBtcChain { public readonly ecosystem = ChainTypes.ECOSYSTEM.BTC; - public readonly currencyType = RequestLogicTypes.CURRENCY.BTC; } diff --git a/packages/chain/src/chains/btc/btc-ecosystem.ts b/packages/chain/src/chains/btc/btc-ecosystem.ts index cb61e8adbd..3980189e7c 100644 --- a/packages/chain/src/chains/btc/btc-ecosystem.ts +++ b/packages/chain/src/chains/btc/btc-ecosystem.ts @@ -4,9 +4,6 @@ import { chains } from './index'; import { BtcChain } from './btc-chain'; class BtcEcosystem extends EcosystemAbstract {} -export default new BtcEcosystem( - ChainTypes.ECOSYSTEM.BTC, - BtcChain, - chains, +export default new BtcEcosystem(ChainTypes.ECOSYSTEM.BTC, BtcChain, chains, [ RequestLogicTypes.CURRENCY.BTC, -); +]); diff --git a/packages/chain/src/chains/chain-abstract.ts b/packages/chain/src/chains/chain-abstract.ts index 2502b121e2..7f3f9913e9 100644 --- a/packages/chain/src/chains/chain-abstract.ts +++ b/packages/chain/src/chains/chain-abstract.ts @@ -1,10 +1,7 @@ import { ChainTypes } from '@requestnetwork/types'; -import { RequestLogicTypes } from '@requestnetwork/types/src'; export abstract class ChainAbstract implements ChainTypes.IChainCommon { public declare readonly ecosystem: ChainTypes.ECOSYSTEM; - public declare readonly currencyType: RequestLogicTypes.CURRENCY; - constructor( public readonly id: string, public readonly name: string, diff --git a/packages/chain/src/chains/declarative/declarative-chain.ts b/packages/chain/src/chains/declarative/declarative-chain.ts index 483b407aa7..3c6024c782 100644 --- a/packages/chain/src/chains/declarative/declarative-chain.ts +++ b/packages/chain/src/chains/declarative/declarative-chain.ts @@ -1,7 +1,6 @@ -import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; import { ChainAbstract } from '../chain-abstract'; export class DeclarativeChain extends ChainAbstract implements ChainTypes.IDeclarativeChain { public readonly ecosystem = ChainTypes.ECOSYSTEM.DECLARATIVE; - public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/declarative/declarative-ecosystem.ts b/packages/chain/src/chains/declarative/declarative-ecosystem.ts index 7bea696ffb..0a945f487f 100644 --- a/packages/chain/src/chains/declarative/declarative-ecosystem.ts +++ b/packages/chain/src/chains/declarative/declarative-ecosystem.ts @@ -5,12 +5,13 @@ import { chains } from './index'; class DeclarativeEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super( - ChainTypes.ECOSYSTEM.DECLARATIVE, - DeclarativeChain, - chains, + super(ChainTypes.ECOSYSTEM.DECLARATIVE, DeclarativeChain, chains, [ + RequestLogicTypes.CURRENCY.ISO4217, + RequestLogicTypes.CURRENCY.BTC, RequestLogicTypes.CURRENCY.ETH, - ); + RequestLogicTypes.CURRENCY.ERC20, + RequestLogicTypes.CURRENCY.ERC777, + ]); } } diff --git a/packages/chain/src/chains/ecosystem-abstract.ts b/packages/chain/src/chains/ecosystem-abstract.ts index ccc907b0c3..67d8d46f05 100644 --- a/packages/chain/src/chains/ecosystem-abstract.ts +++ b/packages/chain/src/chains/ecosystem-abstract.ts @@ -12,7 +12,7 @@ export abstract class EcosystemAbstract testnet?: boolean, ) => ChainTypes.ChainTypeByEcosystem[ECOSYSTEM], public chains: Record, - public currencyType: RequestLogicTypes.CURRENCY, + public currencyTypes: RequestLogicTypes.CURRENCY[], ) {} get chainNames(): string[] { @@ -40,7 +40,7 @@ export abstract class EcosystemAbstract /** * Check if chainName lives amongst the list of supported chains by this chain type. */ - public isChainSupported(chainName?: string | ChainAbstract) { + public isChainSupported(chainName?: string | ChainAbstract): boolean { return ( !!chainName && this.chainNames.includes(chainName instanceof ChainAbstract ? chainName.name : chainName) diff --git a/packages/chain/src/chains/evm/evm-chain.ts b/packages/chain/src/chains/evm/evm-chain.ts index af7cc60ff2..596643c344 100644 --- a/packages/chain/src/chains/evm/evm-chain.ts +++ b/packages/chain/src/chains/evm/evm-chain.ts @@ -1,7 +1,6 @@ import { ChainAbstract } from '../chain-abstract'; -import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; export class EvmChain extends ChainAbstract implements ChainTypes.IEvmChain { public readonly ecosystem = ChainTypes.ECOSYSTEM.EVM; - public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/evm/evm-ecosystem.ts b/packages/chain/src/chains/evm/evm-ecosystem.ts index 6558cec0f9..f361003bee 100644 --- a/packages/chain/src/chains/evm/evm-ecosystem.ts +++ b/packages/chain/src/chains/evm/evm-ecosystem.ts @@ -5,7 +5,11 @@ import { EvmChain } from './evm-chain'; class EvmEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super(ChainTypes.ECOSYSTEM.EVM, EvmChain, chains, RequestLogicTypes.CURRENCY.ETH); + super(ChainTypes.ECOSYSTEM.EVM, EvmChain, chains, [ + RequestLogicTypes.CURRENCY.ETH, + RequestLogicTypes.CURRENCY.ERC20, + RequestLogicTypes.CURRENCY.ERC777, + ]); } } diff --git a/packages/chain/src/chains/near/near-chain.ts b/packages/chain/src/chains/near/near-chain.ts index c23e8e4dce..9aa1abb586 100644 --- a/packages/chain/src/chains/near/near-chain.ts +++ b/packages/chain/src/chains/near/near-chain.ts @@ -1,7 +1,6 @@ import { ChainAbstract } from '../chain-abstract'; -import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes } from '@requestnetwork/types'; export class NearChain extends ChainAbstract implements ChainTypes.INearChain { public readonly ecosystem = ChainTypes.ECOSYSTEM.NEAR; - public readonly currencyType = RequestLogicTypes.CURRENCY.ETH; } diff --git a/packages/chain/src/chains/near/near-ecosystem.ts b/packages/chain/src/chains/near/near-ecosystem.ts index ef24846bb9..b1c3a38781 100644 --- a/packages/chain/src/chains/near/near-ecosystem.ts +++ b/packages/chain/src/chains/near/near-ecosystem.ts @@ -5,7 +5,10 @@ import { NearChain } from './near-chain'; class NearEcosystem extends EcosystemAbstract { constructor(chains: Record) { - super(ChainTypes.ECOSYSTEM.NEAR, NearChain, chains, RequestLogicTypes.CURRENCY.ETH); + super(ChainTypes.ECOSYSTEM.NEAR, NearChain, chains, [ + RequestLogicTypes.CURRENCY.ETH, + RequestLogicTypes.CURRENCY.ERC20, + ]); } } diff --git a/packages/chain/src/chains/utils.ts b/packages/chain/src/chains/utils.ts index ca78a16d87..92caed3525 100644 --- a/packages/chain/src/chains/utils.ts +++ b/packages/chain/src/chains/utils.ts @@ -2,12 +2,16 @@ import { ChainAbstract } from './chain-abstract'; import { ChainDefinition } from '../types'; export const initializeChains = ( - chainClass: new (chainId: string, chainName: string) => CHAIN_CLASS, + chainClass: new (chainId: string, chainName: string, testnet?: boolean) => CHAIN_CLASS, chainDefinitions: Record, ): Record => Object.keys(chainDefinitions).reduce( (chains, chainName) => { - chains[chainName] = new chainClass(chainDefinitions[chainName].chainId, chainName); + chains[chainName] = new chainClass( + chainDefinitions[chainName].chainId, + chainName, + chainDefinitions[chainName].testnet, + ); return chains; }, {} as Record, diff --git a/packages/currency/src/currency-manager.ts b/packages/currency/src/currency-manager.ts index 785d414947..e1064b3a19 100644 --- a/packages/currency/src/currency-manager.ts +++ b/packages/currency/src/currency-manager.ts @@ -142,7 +142,7 @@ export class CurrencyManager implements ICurrencyManager (!network || ('network' in x && x.network === ChainManager.getName(network))) && (!network || typeof network === 'string' || - x.type === this.chainManager.ecosystems[network.ecosystem].currencyType), + this.chainManager.ecosystems[network.ecosystem].currencyTypes.includes(x.type)), ); } @@ -156,7 +156,7 @@ export class CurrencyManager implements ICurrencyManager (!network || ('network' in x && x.network === ChainManager.getName(network))) && (!network || typeof network === 'string' || - x.type === this.chainManager.ecosystems[network.ecosystem].currencyType), + this.chainManager.ecosystems[network.ecosystem].currencyTypes.includes(x.type)), ); } diff --git a/packages/types/src/chain-types.ts b/packages/types/src/chain-types.ts index 1e5e2f12b1..2d8a9b963e 100644 --- a/packages/types/src/chain-types.ts +++ b/packages/types/src/chain-types.ts @@ -21,28 +21,23 @@ export interface IChainCommon { name: string; testnet: boolean; ecosystem: ECOSYSTEM; - currencyType: RequestLogicTypes.CURRENCY; eq(chain: IChainCommon): boolean; } export interface IBtcChain extends IChainCommon { ecosystem: ECOSYSTEM.BTC; - currencyType: RequestLogicTypes.CURRENCY.BTC; } export interface IDeclarativeChain extends IChainCommon { ecosystem: ECOSYSTEM.DECLARATIVE; - currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface IEvmChain extends IChainCommon { ecosystem: ECOSYSTEM.EVM; - currencyType: RequestLogicTypes.CURRENCY.ETH; } export interface INearChain extends IChainCommon { ecosystem: ECOSYSTEM.NEAR; - currencyType: RequestLogicTypes.CURRENCY.ETH; } /** @@ -65,7 +60,7 @@ export interface IEcosystem { name: E; chainClass: new (id: string, name: string, testnet?: boolean) => ChainTypeByEcosystem[E]; chains: Record; - currencyType: RequestLogicTypes.CURRENCY; + currencyTypes: RequestLogicTypes.CURRENCY[]; chainNames: string[]; assertChainNameSupported(chainName?: string): asserts chainName is string; assertChainSupported(chain?: IChain): asserts chain is ChainTypeByEcosystem[E]; From 1ef0da3d86c27e0a062addc5f0170daed59db83d Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Wed, 21 Feb 2024 18:00:40 +0100 Subject: [PATCH 12/14] wip fixing currency manager --> chains as objects --- packages/currency/src/currency-manager.ts | 82 +++++++++++++------ packages/currency/src/types.ts | 28 ++++--- .../conversion-supported-currencies.test.ts | 74 ++++++++--------- .../currency/test/currencyManager.test.ts | 57 ++++++------- .../payment-detection/src/erc20/currency.ts | 13 ++- 5 files changed, 144 insertions(+), 110 deletions(-) diff --git a/packages/currency/src/currency-manager.ts b/packages/currency/src/currency-manager.ts index e1064b3a19..41769f3390 100644 --- a/packages/currency/src/currency-manager.ts +++ b/packages/currency/src/currency-manager.ts @@ -5,6 +5,7 @@ import { getSupportedERC20Currencies } from './erc20'; import { getSupportedERC777Currencies } from './erc777'; import { getHash } from './getHash'; import { + Currency, CurrencyDefinition, CurrencyInput, ICurrencyManager, @@ -19,6 +20,10 @@ import { ChainManager } from '@requestnetwork/chain'; const { BTC, ERC20, ERC777, ETH, ISO4217 } = RequestLogicTypes.CURRENCY; +type MixedCurrencyType = + | (CurrencyInput & { id?: string; hash?: string; meta?: TMeta }) + | CurrencyDefinition; + /** * Handles a list of currencies and provide features to retrieve them, as well as convert to/from storage format */ @@ -37,11 +42,17 @@ export class CurrencyManager implements ICurrencyManager * @param chainManager A ChainManager instance that describes the supported underlying chains */ constructor( - inputCurrencies: (CurrencyInput & { id?: string; meta?: TMeta })[], + inputCurrencies: MixedCurrencyType[], legacyTokens?: LegacyTokenMap, conversionPairs?: AggregatorsMap, chainManager?: ChainTypes.IChainManager, ) { + this.legacyTokens = legacyTokens || CurrencyManager.getDefaultLegacyTokens(); + this.conversionPairs = conversionPairs || CurrencyManager.getDefaultConversionPairs(); + this.chainManager = chainManager || ChainManager.current(); + ChainManager.setCurrent(this.chainManager); + + // initialize currencies this.knownCurrencies = []; for (const input of inputCurrencies) { const currency = CurrencyManager.fromInput(input); @@ -50,10 +61,6 @@ export class CurrencyManager implements ICurrencyManager } this.knownCurrencies.push(currency); } - this.legacyTokens = legacyTokens || CurrencyManager.getDefaultLegacyTokens(); - this.conversionPairs = conversionPairs || CurrencyManager.getDefaultConversionPairs(); - this.chainManager = chainManager || ChainManager.current(); - ChainManager.setCurrent(this.chainManager); } /** @@ -80,7 +87,9 @@ export class CurrencyManager implements ICurrencyManager const currencyFromId = this.fromId(currencyIdentifier); - if (currencyFromId) return currencyFromId; + if (currencyFromId) { + return currencyFromId; + } const parts = currencyIdentifier.split('-'); const currencyFromSymbol = @@ -111,7 +120,10 @@ export class CurrencyManager implements ICurrencyManager (x) => (x.type === ERC20 || x.type === ERC777) && x.address === address && - (!network || x.network === network), + (!network || + (typeof network === 'string' + ? x.network.name === network + : x.network.name === network.name)), ); if (matches.length > 1) { const networks = matches.map((x) => ('network' in x ? x.network : '')).join(', '); @@ -139,7 +151,7 @@ export class CurrencyManager implements ICurrencyManager return this.knownCurrencies.find( (x) => x.symbol.toUpperCase() === symbol && - (!network || ('network' in x && x.network === ChainManager.getName(network))) && + (!network || ('network' in x && x.network.name === ChainManager.getName(network))) && (!network || typeof network === 'string' || this.chainManager.ecosystems[network.ecosystem].currencyTypes.includes(x.type)), @@ -153,7 +165,7 @@ export class CurrencyManager implements ICurrencyManager return this.knownCurrencies.find( (x) => x.hash.toLowerCase() === hash.toLowerCase() && - (!network || ('network' in x && x.network === ChainManager.getName(network))) && + (!network || ('network' in x && x.network.name === ChainManager.getName(network))) && (!network || typeof network === 'string' || this.chainManager.ecosystems[network.ecosystem].currencyTypes.includes(x.type)), @@ -176,8 +188,8 @@ export class CurrencyManager implements ICurrencyManager x.type === currency.type && (((x.type === ERC20 || x.type === ERC777) && currency.value === x.address && - x.network === networkOrDefault) || - ((x.type === ETH || x.type === BTC) && x.network === networkOrDefault) || + x.network.name === networkOrDefault) || + ((x.type === ETH || x.type === BTC) && x.network.name === networkOrDefault) || (x.symbol === currency.value && !currency.network)), ); } @@ -190,7 +202,7 @@ export class CurrencyManager implements ICurrencyManager network: string | ChainTypes.IChain, ): CurrencyDefinition | undefined { return this.knownCurrencies.find( - (x) => x.type === type && x.network === ChainManager.getName(network), + (x) => x.type === type && x.network.name === ChainManager.getName(network), ); } @@ -218,7 +230,7 @@ export class CurrencyManager implements ICurrencyManager hash, meta, ...input - }: CurrencyInput & { id?: string; hash?: string; meta?: TMeta }): CurrencyDefinition { + }: MixedCurrencyType): CurrencyDefinition { if ('address' in input) { if (input.address.startsWith('0x') && input.address.length === 42) { input.address = utils.getAddress(input.address); @@ -229,7 +241,16 @@ export class CurrencyManager implements ICurrencyManager hash: hash || getHash(CurrencyManager.toStorageCurrency(input)), meta: meta as TMeta, ...input, - }; + network: + 'network' in input + ? typeof input.network === 'string' + ? ChainManager.current().fromName( + input.network, + ChainManager.current().getEcosystemsByCurrencyType(input.type), + ) + : input.network + : undefined, + } as CurrencyDefinition; } /** @@ -244,12 +265,17 @@ export class CurrencyManager implements ICurrencyManager /** * Converts a currency to the storage format (ICurrency) */ - static toStorageCurrency(currency: CurrencyInput): StorageCurrency { + static toStorageCurrency(currency: CurrencyInput | Currency): StorageCurrency { return { type: currency.type, value: currency.type === ERC20 || currency.type === ERC777 ? currency.address : currency.symbol, - network: currency.type === ISO4217 ? undefined : currency.network, + network: + currency.type === ISO4217 + ? undefined + : typeof currency.network === 'string' + ? currency.network + : currency.network.name, }; } @@ -257,27 +283,28 @@ export class CurrencyManager implements ICurrencyManager * Validates an address for a given currency. * Throws if the currency is an ISO4217 currency. */ - validateAddress(address: string, currency: CurrencyInput | StorageCurrency): boolean { + validateAddress(address: string, currency: CurrencyDefinition | StorageCurrency): boolean { if (currency.type === RequestLogicTypes.CURRENCY.ISO4217) { throw new Error(`Could not validate an address for an ISO4217 currency`); } + const chainName = + currency.network && + (typeof currency.network === 'string' ? currency.network : currency.network.name); switch (currency.type) { case RequestLogicTypes.CURRENCY.ETH: case RequestLogicTypes.CURRENCY.ERC20: case RequestLogicTypes.CURRENCY.ERC777: - if ( - this.chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(currency.network) - ) { - return isValidNearAddress(address, currency.network); - } else if (currency.network === 'tron' || currency.network === 'solana') { - return addressValidator.validate(address, currency.network); + if (this.chainManager.ecosystems[ChainTypes.ECOSYSTEM.NEAR].isChainSupported(chainName)) { + return isValidNearAddress(address, chainName); + } else if (chainName === 'tron' || chainName === 'solana') { + return addressValidator.validate(address, chainName); } return addressValidator.validate(address, 'ETH'); case RequestLogicTypes.CURRENCY.BTC: return addressValidator.validate( address, 'BTC', - currency.network === 'testnet' ? 'testnet' : 'prod', + chainName === 'testnet' ? 'testnet' : 'prod', ); default: throw new Error(`Could not validate an address for an unknown currency type`); @@ -292,8 +319,9 @@ export class CurrencyManager implements ICurrencyManager currency.type === RequestLogicTypes.CURRENCY.ISO4217 || currency.type === RequestLogicTypes.CURRENCY.ETH || currency.type === RequestLogicTypes.CURRENCY.BTC - ) + ) { return true; + } return this.validateAddress(currency.value, currency); } @@ -334,7 +362,9 @@ export class CurrencyManager implements ICurrencyManager * Returns a default instance of CurrencyManager based on default lists */ static getDefault(): CurrencyManager { - if (this.defaultInstance) return this.defaultInstance; + if (this.defaultInstance) { + return this.defaultInstance; + } this.defaultInstance = new CurrencyManager( CurrencyManager.getDefaultList(), diff --git a/packages/currency/src/types.ts b/packages/currency/src/types.ts index c4172f5f1c..eb4cc0aa47 100644 --- a/packages/currency/src/types.ts +++ b/packages/currency/src/types.ts @@ -7,10 +7,14 @@ type TokenAddress = string; type TokenDefinition = { name: string; symbol: string; decimals: number; id?: string }; export type TokenMap = Record; +/** Native Currency types */ +export type NativeCurrencyType = RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH; + /** * A native blockchain token (ETH, MATIC, ETH-rinkeby...) */ export type NativeCurrency = { + type: NativeCurrencyType; symbol: string; decimals: number; network: ChainTypes.IChain; @@ -20,6 +24,7 @@ export type NativeCurrency = { * A Fiat currency (EUR, USD...) */ export type ISO4217Currency = { + type: RequestLogicTypes.CURRENCY.ISO4217; symbol: string; decimals: number; }; @@ -28,6 +33,7 @@ export type ISO4217Currency = { * An ERC20 token (DAI, USDT...) */ export type ERC20Currency = { + type: RequestLogicTypes.CURRENCY.ERC20; symbol: string; decimals: number; network: ChainTypes.IEvmChain | ChainTypes.INearChain | ChainTypes.IDeclarativeChain; @@ -38,35 +44,29 @@ export type ERC20Currency = { * An ERC777 SuperToken (DAIx, USDCx...) */ export type ERC777Currency = { + type: RequestLogicTypes.CURRENCY.ERC777; symbol: string; decimals: number; network: ChainTypes.IEvmChain; address: string; }; -/** Native Currency types */ -export type NativeCurrencyType = RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH; - /** * The minimum properties of a native Currency */ export type NativeCurrencyInput = Omit & { - type: NativeCurrencyType; network: string; }; /** * The minimum properties of an ISO4217 Currency */ -export type ISO4217CurrencyInput = ISO4217Currency & { - type: RequestLogicTypes.CURRENCY.ISO4217; -}; +export type ISO4217CurrencyInput = ISO4217Currency; /** * The minimum properties of an ERC20 Currency */ export type ERC20CurrencyInput = Omit & { - type: RequestLogicTypes.CURRENCY.ERC20; network: string; }; @@ -74,7 +74,6 @@ export type ERC20CurrencyInput = Omit & { * The minimum properties of an ERC777 Currency */ export type ERC777CurrencyInput = Omit & { - type: RequestLogicTypes.CURRENCY.ERC777; network: string; }; @@ -87,11 +86,16 @@ export type CurrencyInput = | ERC20CurrencyInput | ERC777CurrencyInput; +/** + * The different representations of a currency + */ +export type Currency = NativeCurrency | ISO4217Currency | ERC20Currency | ERC777Currency; + /** * The description of Currency, its core properties and some computed properties. * `meta` enables applications to add any metadata they need to a Currency */ -export type CurrencyDefinition = CurrencyInput & { +export type CurrencyDefinition = Currency & { id: string; hash: string; meta: TMeta; @@ -137,13 +141,13 @@ export interface ICurrencyManager { currency: Pick, network: string | ChainTypes.IChain, ): boolean; - validateAddress(address: string, currency: CurrencyInput | StorageCurrency): boolean; + validateAddress(address: string, currency: CurrencyDefinition): boolean; validateCurrency(currency: StorageCurrency): boolean; } /** * A mapping from old to new name for a given currency. * - * Format { "chainName": {"TOKEN": ["NEW_TOKEN","NEW_CHAIN"]}} + * Format { "chainName": {"TOKEN": ["NEW_TOKEN","NEW_CHAIN"]}} */ export type LegacyTokenMap = Record>; diff --git a/packages/currency/test/conversion-supported-currencies.test.ts b/packages/currency/test/conversion-supported-currencies.test.ts index 9d0c063c2a..b8bde61383 100644 --- a/packages/currency/test/conversion-supported-currencies.test.ts +++ b/packages/currency/test/conversion-supported-currencies.test.ts @@ -1,5 +1,5 @@ import { CurrencyManager } from '../src'; -import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { RequestLogicTypes } from '@requestnetwork/types'; const currencyManager = new CurrencyManager([ ...CurrencyManager.getDefaultList(), @@ -14,14 +14,12 @@ const currencyManager = new CurrencyManager([ describe('supported currencies with oracles from chainlink', () => { describe('fiat currencies', () => { - ( - Object.entries({ - mainnet: ['AUD', 'CAD', 'CHF', 'EUR', 'GBP', 'SGD', 'USD'], - private: ['EUR', 'USD'], - matic: ['AUD', 'CAD', 'CHF', 'EUR', 'GBP', 'SGD', 'USD'], - fantom: ['USD', 'CHF'], - }) as [ChainTypes.IEvmChain, string[]][] - ).forEach(([network, symbols]) => { + Object.entries({ + mainnet: ['AUD', 'CAD', 'CHF', 'EUR', 'GBP', 'SGD', 'USD'], + private: ['EUR', 'USD'], + matic: ['AUD', 'CAD', 'CHF', 'EUR', 'GBP', 'SGD', 'USD'], + fantom: ['USD', 'CHF'], + }).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { it(symbol, () => { @@ -35,12 +33,10 @@ describe('supported currencies with oracles from chainlink', () => { }); describe('native currencies', () => { - ( - Object.entries({ - mainnet: ['ETH'], - fantom: ['FTM'], - }) as [ChainTypes.IEvmChain, string[]][] - ).forEach(([network, symbols]) => { + Object.entries({ + mainnet: ['ETH'], + fantom: ['FTM'], + }).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { it(symbol, () => { @@ -54,31 +50,29 @@ describe('supported currencies with oracles from chainlink', () => { }); describe('ERC20 tokens', () => { - ( - Object.entries({ - mainnet: [ - '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c', - '0x3845badade8e6dff049820680d1f14bd3903a5d0', - '0x4e15361fd6b4bb609fa63c81a2be19d873717870', - '0x6b175474e89094c44da98b954eedeac495271d0f', - '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9', - '0x8290333cef9e6d528dd5618fb97a76f268f3edd4', - '0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7', - '0x967da4048cd07ab37855c090aaf366e4ce1b9f48', - '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', - '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', - '0xa117000000f279d81a1d3cc75430faa017fa5a2e', - '0xc944e90c64b2c07662a292be6244bdf05cda44a7', - '0xdac17f958d2ee523a2206206994597c13d831ec7', - ], - matic: [ - '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063', - '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', - ], - private: ['0x38cf23c52bb4b13f051aec09580a2de845a7fa35'], - }) as [ChainTypes.IEvmChain, string[]][] - ).forEach(([network, addresses]) => { + Object.entries({ + mainnet: [ + '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c', + '0x3845badade8e6dff049820680d1f14bd3903a5d0', + '0x4e15361fd6b4bb609fa63c81a2be19d873717870', + '0x6b175474e89094c44da98b954eedeac495271d0f', + '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9', + '0x8290333cef9e6d528dd5618fb97a76f268f3edd4', + '0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7', + '0x967da4048cd07ab37855c090aaf366e4ce1b9f48', + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + '0xa117000000f279d81a1d3cc75430faa017fa5a2e', + '0xc944e90c64b2c07662a292be6244bdf05cda44a7', + '0xdac17f958d2ee523a2206206994597c13d831ec7', + ], + matic: [ + '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', + '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063', + '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', + ], + private: ['0x38cf23c52bb4b13f051aec09580a2de845a7fa35'], + }).forEach(([network, addresses]) => { describe(network, () => { addresses.forEach((address) => { const currency = currencyManager.fromAddress(address, network)!; diff --git a/packages/currency/test/currencyManager.test.ts b/packages/currency/test/currencyManager.test.ts index 9a20b14103..919a0472c3 100644 --- a/packages/currency/test/currencyManager.test.ts +++ b/packages/currency/test/currencyManager.test.ts @@ -1,4 +1,4 @@ -import { RequestLogicTypes } from '@requestnetwork/types'; +import { ChainTypes, RequestLogicTypes } from '@requestnetwork/types'; import { CurrencyInput, CurrencyDefinition, @@ -6,8 +6,9 @@ import { ERC20Currency, StorageCurrency, } from '../src'; +import { ChainManager } from '@requestnetwork/chain'; -const testCasesPerNetwork: Record>> = { +const testCasesPerNetwork: Record>> = { mainnet: { ETH: { symbol: 'ETH', network: 'mainnet' }, SAI: { @@ -126,7 +127,7 @@ describe('CurrencyManager', () => { it('fails if there is a duplicate token in the list', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const dai = CurrencyManager.getDefaultList().find((x) => x.id === 'DAI-mainnet')!; - const list: CurrencyInput[] = [dai, dai, dai, dai]; + const list: CurrencyDefinition[] = [dai, dai, dai, dai]; expect(() => new CurrencyManager(list)).toThrowError('Duplicate found: DAI-mainnet'); }); @@ -159,78 +160,78 @@ describe('CurrencyManager', () => { it('access a common token by its symbol', () => { expect(currencyManager.from('DAI')).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); expect(currencyManager.fromSymbol('DAI')).toBeDefined(); }); it('access a chain-specific token by its symbol', () => { expect(currencyManager.from('CELO')).toMatchObject({ - network: 'celo', + network: expect.objectContaining({ name: 'celo' }), }); expect(currencyManager.fromSymbol('CELO')).toMatchObject({ - network: 'celo', + network: expect.objectContaining({ name: 'celo' }), }); }); it('access a multichain token by its symbol and network', () => { expect(currencyManager.from('DAI-matic')).toMatchObject({ symbol: 'DAI', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), }); expect(currencyManager.fromSymbol('DAI-matic')).toBeUndefined(); expect(currencyManager.from('DAI', 'matic')).toMatchObject({ symbol: 'DAI', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), }); expect(currencyManager.fromSymbol('DAI', 'matic')).toMatchObject({ symbol: 'DAI', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), }); }); it('access a currency by its id', () => { expect(currencyManager.from('ETH-rinkeby-rinkeby')).toMatchObject({ symbol: 'ETH-rinkeby', - network: 'rinkeby', + network: expect.objectContaining({ name: 'rinkeby' }), }); }); it('access a mainnet token by its address with or without network', () => { expect(currencyManager.from('0x6B175474E89094C44Da98b954EedeAC495271d0F')).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); expect( currencyManager.from('0x6B175474E89094C44Da98b954EedeAC495271d0F', 'mainnet'), ).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); expect( currencyManager.fromAddress('0x6B175474E89094C44Da98b954EedeAC495271d0F'), ).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); expect( currencyManager.fromAddress('0x6B175474E89094C44Da98b954EedeAC495271d0F', 'mainnet'), ).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); }); it('access a mainnet token by its address whatever the case', () => { expect(currencyManager.from('0x6b175474e89094c44da98b954eedeac495271d0f')).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); expect(currencyManager.from('0x6B175474E89094C44DA98B954EEDEAC495271D0F')).toMatchObject({ symbol: 'DAI', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), }); }); @@ -239,38 +240,38 @@ describe('CurrencyManager', () => { currencyManager.from('0xD3b71117E6C1558c1553305b44988cd944e97300', 'matic'), ).toMatchObject({ symbol: 'YEL', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), }); expect( currencyManager.from('0xD3b71117E6C1558c1553305b44988cd944e97300', 'fantom'), ).toMatchObject({ symbol: 'YEL', - network: 'fantom', + network: expect.objectContaining({ name: 'fantom' }), }); expect( currencyManager.fromAddress('0xD3b71117E6C1558c1553305b44988cd944e97300', 'matic'), ).toMatchObject({ symbol: 'YEL', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), }); expect( currencyManager.fromAddress('0xD3b71117E6C1558c1553305b44988cd944e97300', 'fantom'), ).toMatchObject({ symbol: 'YEL', - network: 'fantom', + network: expect.objectContaining({ name: 'fantom' }), }); }); it('defaults to mainnet for native tokens with a mainnet equivalent', () => { expect(currencyManager.from('MATIC')).toMatchObject({ symbol: 'MATIC', - network: 'mainnet', + network: expect.objectContaining({ name: 'mainnet' }), type: RequestLogicTypes.CURRENCY.ERC20, }); expect(currencyManager.from('MATIC-matic')).toMatchObject({ symbol: 'MATIC', - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), type: RequestLogicTypes.CURRENCY.ETH, }); }); @@ -493,10 +494,7 @@ describe('CurrencyManager', () => { '0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', ]; - const extendedTestCasesPerNetwork: Record< - string, - Record> - > = { + const extendedTestCasesPerNetwork: Record>> = { ...testCasesPerNetwork, aurora: { NEAR: { @@ -548,7 +546,10 @@ describe('CurrencyManager', () => { switch (currency.symbol) { case 'NEAR': case 'NEAR-testnet': - testValidateAddressForCurrency(nearAddresses[currency.network], currency); + testValidateAddressForCurrency( + nearAddresses[currency.network.name], + currency, + ); break; default: eip55Addresses.forEach((address) => @@ -557,7 +558,7 @@ describe('CurrencyManager', () => { } break; case RequestLogicTypes.CURRENCY.BTC: - testValidateAddressForCurrency(bitcoinAddresses[currency.network], currency); + testValidateAddressForCurrency(bitcoinAddresses[currency.network.name], currency); break; default: throw new Error(`Could not generate a valid address for an unknown type`); diff --git a/packages/payment-detection/src/erc20/currency.ts b/packages/payment-detection/src/erc20/currency.ts index f14fc47e54..f1e32524e8 100644 --- a/packages/payment-detection/src/erc20/currency.ts +++ b/packages/payment-detection/src/erc20/currency.ts @@ -1,6 +1,7 @@ import { CurrencyDefinition, CurrencyManager, + ERC20Currency, getCurrencyHash, StorageCurrency, } from '@requestnetwork/currency'; @@ -8,7 +9,8 @@ import { RequestLogicTypes } from '@requestnetwork/types'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { isAddress } from 'ethers/lib/utils'; import { getDefaultProvider } from '@requestnetwork/utils'; -import { ERC20CurrencyInput } from '@requestnetwork/currency/src'; +import { CurrencyInput, ERC20CurrencyInput } from '@requestnetwork/currency/src'; +import { ChainManager } from '@requestnetwork/chain/src'; export const loadCurrencyFromContract = async ( currency: StorageCurrency, @@ -32,13 +34,16 @@ export const loadCurrencyFromContract = async ( return null; } - const definition: ERC20CurrencyInput = { + const definition = { address: value, decimals, symbol, - network: network, + network: ChainManager.current().fromName( + network, + ChainManager.current().getEcosystemsByCurrencyType(RequestLogicTypes.CURRENCY.ERC20), + ), type: RequestLogicTypes.CURRENCY.ERC20, - }; + } as ERC20Currency; return { ...definition, From 5311775048dff18e53695954cf7cc6faf543e596 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 22 Feb 2024 12:53:55 +0100 Subject: [PATCH 13/14] fix more build errors --- packages/currency/src/currency-manager.ts | 13 ++++++------- packages/currency/src/iso4217.ts | 2 +- packages/currency/src/types.ts | 7 +++++++ packages/currency/test/currencyManager.test.ts | 14 ++++++++++---- packages/integration-test/test/node-client.test.ts | 14 +++++++++++--- .../request-client.js/src/http-request-network.ts | 4 ++-- .../src/commands/chainlink/aggregatorsUtils.ts | 2 +- 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/currency/src/currency-manager.ts b/packages/currency/src/currency-manager.ts index 41769f3390..11143a364b 100644 --- a/packages/currency/src/currency-manager.ts +++ b/packages/currency/src/currency-manager.ts @@ -10,6 +10,7 @@ import { CurrencyInput, ICurrencyManager, LegacyTokenMap, + MixedCurrencyType, NativeCurrencyType, StorageCurrency, } from './types'; @@ -17,13 +18,10 @@ import { AggregatorsMap, defaultConversionPairs, getPath } from './conversion-ag import { isValidNearAddress } from './currency-utils'; import { getSupportedNativeCurrencies } from './native'; import { ChainManager } from '@requestnetwork/chain'; +import { getSupportedIso4217Currencies } from './iso4217'; const { BTC, ERC20, ERC777, ETH, ISO4217 } = RequestLogicTypes.CURRENCY; -type MixedCurrencyType = - | (CurrencyInput & { id?: string; hash?: string; meta?: TMeta }) - | CurrencyDefinition; - /** * Handles a list of currencies and provide features to retrieve them, as well as convert to/from storage format */ @@ -126,9 +124,9 @@ export class CurrencyManager implements ICurrencyManager : x.network.name === network.name)), ); if (matches.length > 1) { - const networks = matches.map((x) => ('network' in x ? x.network : '')).join(', '); + const networks = matches.map((x) => ('network' in x ? x.network.name : '')).join(', '); console.warn( - `${address} has several matches on "${networks}". To avoid errors, specify a network.`, + `${address} has several matches on ${networks}. To avoid errors, specify a network.`, ); return undefined; } @@ -337,9 +335,10 @@ export class CurrencyManager implements ICurrencyManager */ static getDefaultList(): CurrencyDefinition[] { return ([] as CurrencyInput[]) - .concat(getSupportedNativeCurrencies()) + .concat(getSupportedIso4217Currencies()) .concat(getSupportedERC20Currencies()) .concat(getSupportedERC777Currencies()) + .concat(getSupportedNativeCurrencies()) .map(CurrencyManager.fromInput); } diff --git a/packages/currency/src/iso4217.ts b/packages/currency/src/iso4217.ts index 7310ef4590..b3eea08fc0 100644 --- a/packages/currency/src/iso4217.ts +++ b/packages/currency/src/iso4217.ts @@ -1365,7 +1365,7 @@ export default iso4217Currencies; * * @returns List of supported ISO-4217 currencies */ -export function getSupportedNativeCurrencies(): ISO4217CurrencyInput[] { +export function getSupportedIso4217Currencies(): ISO4217CurrencyInput[] { return iso4217Currencies.map((cc) => ({ type: RequestLogicTypes.CURRENCY.ISO4217, decimals: cc.digits, diff --git a/packages/currency/src/types.ts b/packages/currency/src/types.ts index eb4cc0aa47..cdc3f47401 100644 --- a/packages/currency/src/types.ts +++ b/packages/currency/src/types.ts @@ -101,6 +101,13 @@ export type CurrencyDefinition = Currency & { meta: TMeta; }; +/** + * Allowed inputs to instantiate the CurrencyManager + */ +export type MixedCurrencyType = + | (CurrencyInput & Partial<{ id?: string; hash?: string; meta?: TMeta }>) + | CurrencyDefinition; + /** * Alias for ICurrency for clarity in the context */ diff --git a/packages/currency/test/currencyManager.test.ts b/packages/currency/test/currencyManager.test.ts index 919a0472c3..68da9aa5ec 100644 --- a/packages/currency/test/currencyManager.test.ts +++ b/packages/currency/test/currencyManager.test.ts @@ -91,7 +91,7 @@ const testCasesPerNetwork: Record> }, }, bitcoin: { - BTC: { symbol: 'BTC' }, + BTC: { symbol: 'BTC', network: 'mainnet' }, 'BTC-testnet': { symbol: 'BTC-testnet', network: 'testnet' }, }, other: { @@ -406,7 +406,13 @@ describe('CurrencyManager', () => { describe(network, () => { Object.entries(testCases).forEach(([symbol, expected]) => { it(`Resolves ${symbol}`, () => { - expect(currencyManager.from(symbol)).toMatchObject(expected); + expect(currencyManager.from(symbol)).toMatchObject({ + ...expected, + network: + 'network' in expected + ? expect.objectContaining({ name: expected.network }) + : undefined, + }); }); }); }); @@ -744,7 +750,7 @@ describe('CurrencyManager', () => { it('Detects USDCe matic by USDC-matic id', () => { expect(currencyManager.from('USDC-matic')).toMatchObject({ type: RequestLogicTypes.CURRENCY.ERC20, - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), symbol: 'USDCe', id: 'USDC-matic', address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', @@ -753,7 +759,7 @@ describe('CurrencyManager', () => { it('Detects native USDC matic by USDCn-matic id', () => { expect(currencyManager.from('USDCn-matic')).toMatchObject({ type: RequestLogicTypes.CURRENCY.ERC20, - network: 'matic', + network: expect.objectContaining({ name: 'matic' }), symbol: 'USDC', id: 'USDCn-matic', address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', diff --git a/packages/integration-test/test/node-client.test.ts b/packages/integration-test/test/node-client.test.ts index 03f41e1fbf..d290c75b62 100644 --- a/packages/integration-test/test/node-client.test.ts +++ b/packages/integration-test/test/node-client.test.ts @@ -7,12 +7,18 @@ import { PaymentTypes, RequestLogicTypes, ExtensionTypes, + ChainTypes, } from '@requestnetwork/types'; import { payRequest, approveErc20ForProxyConversionIfNeeded, } from '@requestnetwork/payment-processor'; -import { CurrencyInput, CurrencyManager } from '@requestnetwork/currency'; +import { + Currency, + CurrencyDefinition, + CurrencyInput, + CurrencyManager, +} from '@requestnetwork/currency'; import { Wallet, providers, BigNumber } from 'ethers'; import { @@ -24,6 +30,8 @@ import { signatureProvider, } from './scheduled/fixtures'; import { getCurrentTimestampInSecond, normalizeKeccak256Hash } from '@requestnetwork/utils'; +import { ChainManager } from '@requestnetwork/chain/src'; +import { MixedCurrencyType } from '@requestnetwork/currency/src'; const mnemonic = 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat'; const provider = new providers.JsonRpcProvider('http://localhost:8545'); @@ -561,7 +569,7 @@ describe('ERC20 localhost request creation and detection test', () => { it('can create ERC20 requests with any to erc20 proxy', async () => { const tokenContractAddress = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35'; - const currencies: CurrencyInput[] = [ + const currencies: MixedCurrencyType[] = [ ...CurrencyManager.getDefaultList(), { address: tokenContractAddress, @@ -702,7 +710,7 @@ describe('ETH localhost request creation and detection test', () => { }); it('can create & pay a request with any to eth proxy', async () => { - const currencies: CurrencyInput[] = [ + const currencies: MixedCurrencyType[] = [ ...CurrencyManager.getDefaultList(), { network: 'private', diff --git a/packages/request-client.js/src/http-request-network.ts b/packages/request-client.js/src/http-request-network.ts index 6762f1343d..63b60e150c 100644 --- a/packages/request-client.js/src/http-request-network.ts +++ b/packages/request-client.js/src/http-request-network.ts @@ -1,4 +1,4 @@ -import { CurrencyInput, CurrencyManager, ICurrencyManager } from '@requestnetwork/currency'; +import { MixedCurrencyType, CurrencyManager, ICurrencyManager } from '@requestnetwork/currency'; import { ClientTypes, DataAccessTypes, @@ -41,7 +41,7 @@ export default class HttpRequestNetwork extends RequestNetwork { nodeConnectionConfig?: Partial; signatureProvider?: SignatureProviderTypes.ISignatureProvider; useMockStorage?: boolean; - currencies?: CurrencyInput[]; + currencies?: MixedCurrencyType[]; currencyManager?: ICurrencyManager; paymentOptions?: Partial; } = { diff --git a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts index c2b578ac91..286e89bca6 100644 --- a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts +++ b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts @@ -68,7 +68,7 @@ export const getAvailableAggregators = async ( fromCurrency.type !== RequestLogicTypes.CURRENCY.BTC && toCurrency.type !== RequestLogicTypes.CURRENCY.BTC && (fromCurrency.type === RequestLogicTypes.CURRENCY.ISO4217 || - fromCurrency.network === chain.name) && + fromCurrency.network.eq(chain)) && (listAll || !cm.getConversionPath(fromCurrency, toCurrency, chain)) ) { missingAggregators.push({ From b410f472edf481fff09a7904e8993e0b4fdc7deb Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 22 Feb 2024 14:57:15 +0100 Subject: [PATCH 14/14] update error messages in tests --- .../test/extensions/payment-network/any-to-near.test.ts | 2 +- .../extensions/payment-network/erc20/fee-proxy-contract.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts index 4a94829470..336dcf70de 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts @@ -209,7 +209,7 @@ describe('extensions/payment-network/any-to-native-token', () => { network: 'another-chain', }); }).toThrowError( - `Payment network 'another-chain' is not supported by this extension (only aurora)`, + `No chain found with "name=another-chain" for ecosystem(s) "DECLARATIVE,EVM,NEAR"`, ); }); it('throws when payment network is missing', () => { diff --git a/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts b/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts index d9c07a095d..0876455bb4 100644 --- a/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/erc20/fee-proxy-contract.test.ts @@ -411,7 +411,7 @@ describe('extensions/payment-network/erc20/fee-proxy-contract', () => { TestData.arbitraryTimestamp, ), ).toThrowError( - "Payment network 'mainnet' is not supported by this extension (only near-testnet)", + `The extension "Erc20FeeProxyPaymentNetwork" does not support the chain "mainnet" (only "near-testnet")`, ); }); });