diff --git a/packages/advanced-logic/src/advanced-logic.ts b/packages/advanced-logic/src/advanced-logic.ts index d917aa7467..8ac057a519 100644 --- a/packages/advanced-logic/src/advanced-logic.ts +++ b/packages/advanced-logic/src/advanced-logic.ts @@ -1,5 +1,6 @@ import { AdvancedLogicTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -147,7 +148,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic } public getNativeTokenExtensionForNetwork( - network: string, + network: CurrencyTypes.ChainName, ): ExtensionTypes.IExtension | undefined { return this.extensions.nativeToken.find((nativeTokenExtension) => nativeTokenExtension.supportedNetworks.includes(network), @@ -172,7 +173,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic } public getAnyToNativeTokenExtensionForNetwork( - network: string, + network: CurrencyTypes.ChainName, ): ExtensionTypes.IExtension | undefined { return this.extensions.anyToNativeToken.find((anyToNativeTokenExtension) => anyToNativeTokenExtension.supportedNetworks.includes(network), @@ -190,7 +191,7 @@ export default class AdvancedLogic implements AdvancedLogicTypes.IAdvancedLogic protected getNetwork( extensionAction: ExtensionTypes.IAction, requestState: RequestLogicTypes.IRequest, - ): string | undefined { + ): CurrencyTypes.ChainName | undefined { const network = extensionAction.action === 'create' ? extensionAction.parameters.network 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 a21350b02e..96b43937df 100644 --- a/packages/advanced-logic/src/extensions/payment-network/address-based.ts +++ b/packages/advanced-logic/src/extensions/payment-network/address-based.ts @@ -1,5 +1,10 @@ import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; -import { ExtensionTypes, IdentityTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + IdentityTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { areEqualIdentities, deepCopy } from '@requestnetwork/utils'; import DeclarativePaymentNetwork from './declarative'; @@ -155,7 +160,7 @@ export default abstract class AddressBasedPaymentNetwork< protected isValidAddressForSymbolAndNetwork( address: string, symbol: string, - network: string, + network: CurrencyTypes.ChainName, ): boolean { const currencyManager = CurrencyManager.getDefault(); const currency = currencyManager.from(symbol, 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 5c7ed20a51..a7a6bc0587 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,12 +1,12 @@ import { FeeReferenceBasedPaymentNetwork } from './fee-reference-based'; -import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-based'; export default abstract class AnyToNativeTokenPaymentNetwork extends FeeReferenceBasedPaymentNetwork { protected constructor( extensionId: ExtensionTypes.PAYMENT_NETWORK_ID, currentVersion: string, - public readonly supportedNetworks: string[], + public readonly supportedNetworks: CurrencyTypes.ChainName[], ) { super(extensionId, currentVersion, RequestLogicTypes.CURRENCY.ETH); } @@ -44,7 +44,9 @@ export default abstract class AnyToNativeTokenPaymentNetwork extends FeeReferenc ); } - protected throwIfInvalidNetwork(network?: string): asserts network is string { + protected throwIfInvalidNetwork( + network?: CurrencyTypes.ChainName, + ): asserts network is CurrencyTypes.ChainName { 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/native-token.ts b/packages/advanced-logic/src/extensions/payment-network/native-token.ts index a8ef9ce635..13c0def2c6 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 { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { InvalidPaymentAddressError, UnsupportedNetworkError } from './address-based'; import ReferenceBasedPaymentNetwork from './reference-based'; @@ -10,7 +10,7 @@ export default abstract class NativeTokenPaymentNetwork extends ReferenceBasedPa public constructor( extensionId: ExtensionTypes.PAYMENT_NETWORK_ID, currentVersion: string, - public readonly supportedNetworks: string[], + public readonly supportedNetworks: CurrencyTypes.ChainName[], ) { super(extensionId, currentVersion, RequestLogicTypes.CURRENCY.ETH); } @@ -50,7 +50,9 @@ export default abstract class NativeTokenPaymentNetwork extends ReferenceBasedPa ); } - protected throwIfInvalidNetwork(network?: string): asserts network is string { + protected throwIfInvalidNetwork( + network?: CurrencyTypes.ChainName, + ): asserts network is CurrencyTypes.ChainName { 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/near/any-to-near.ts b/packages/advanced-logic/src/extensions/payment-network/near/any-to-near.ts index 01f09fa08f..5b0b802067 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,5 +1,10 @@ import { ICurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; -import { ExtensionTypes, IdentityTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + IdentityTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import AnyToNativeTokenPaymentNetwork from '../any-to-native'; const CURRENT_VERSION = '0.1.0'; @@ -7,7 +12,7 @@ const CURRENT_VERSION = '0.1.0'; export default class AnyToNearPaymentNetwork extends AnyToNativeTokenPaymentNetwork { public constructor( private currencyManager: ICurrencyManager, - supportedNetworks: string[] = [ + supportedNetworks: CurrencyTypes.NearChainName[] = [ '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 cfaed280d9..4584b99b27 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 { ExtensionTypes } from '@requestnetwork/types'; +import { CurrencyTypes, ExtensionTypes } from '@requestnetwork/types'; import NativeTokenPaymentNetwork from '../native-token'; const CURRENT_VERSION = '0.2.0'; @@ -8,7 +8,7 @@ const CURRENT_VERSION = '0.2.0'; */ export default class NearNativePaymentNetwork extends NativeTokenPaymentNetwork { public constructor( - supportedNetworks: string[] = [ + supportedNetworks: CurrencyTypes.NearChainName[] = [ 'aurora', // FIXME: enable near network support // 'near' 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 29f7353a25..7b04f15ad8 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 @@ -37,7 +37,7 @@ describe('extensions/payment-network/address-based', () => { super(extensionId, currentVersion, supportedCurrencyType); } public testIsValidAddress() { - this.isValidAddressForSymbolAndNetwork('test', 'test', 'test'); + this.isValidAddressForSymbolAndNetwork('test', 'test', 'mainnet'); } } expect(() => { @@ -47,6 +47,6 @@ describe('extensions/payment-network/address-based', () => { RequestLogicTypes.CURRENCY.ERC20, ); testAddressBasedPaymentNetwork.testIsValidAddress(); - }).toThrowError(new UnsupportedCurrencyError({ value: 'test', network: 'test' })); + }).toThrowError(new UnsupportedCurrencyError({ value: 'test', network: 'mainnet' })); }); }); diff --git a/packages/advanced-logic/test/extensions/payment-network/any-to-erc20-proxy.test.ts b/packages/advanced-logic/test/extensions/payment-network/any-to-erc20-proxy.test.ts index 7975ba1d62..cda4dcd4b7 100644 --- a/packages/advanced-logic/test/extensions/payment-network/any-to-erc20-proxy.test.ts +++ b/packages/advanced-logic/test/extensions/payment-network/any-to-erc20-proxy.test.ts @@ -145,11 +145,11 @@ describe('extensions/payment-network/erc20/any-to-erc20-fee-proxy-contract', () anyToErc20Proxy.createCreationAction({ paymentAddress: '0x0000000000000000000000000000000000000001', salt: 'ea3bc7caf64110ca', - network: 'kovan', + network: 'goerli', acceptedTokens: ['0x0000000000000000000000000000000000000003'], }); }).toThrowError( - "The currency '0x0000000000000000000000000000000000000003' on kovan is unknown or not supported.", + "The currency '0x0000000000000000000000000000000000000003' on goerli is unknown or not supported.", ); }); 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 9c33c9d562..8525fbcdb4 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 { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; @@ -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', + network: 'invalid network' as CurrencyTypes.EvmChainName, }; 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 b9e099d1ce..0fd2e16904 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 { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, 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'; @@ -52,7 +52,7 @@ describe('extensions/payment-network/any-to-native-token', () => { maxRateTimespan: 100000, feeAmount: '100', }, - ]; + ] as const; anyToNativeTokenTestCases.forEach((testCase) => { describe(`action creations for ${testCase.name}`, () => { @@ -184,7 +184,7 @@ describe('extensions/payment-network/any-to-native-token', () => { expect(() => { new AnyToNearPaymentNetwork(currencyManager).createCreationAction({ ...partialCreationParams, - network: 'another-chain', + network: 'another-chain' as CurrencyTypes.NearChainName, }); }).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 b8787e744e..c84c6f01bd 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 { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import NearTestnetNativeNativePaymentNetwork from '../../../src/extensions/payment-network/near/near-testnet-native'; const salt = arbitrarySalt; @@ -21,17 +21,17 @@ describe('extensions/payment-network/native-token', () => { type: RequestLogicTypes.CURRENCY.ETH, value: 'NEAR', network: 'aurora', - }; + } as const; const auroraTestnetCurrency = { type: RequestLogicTypes.CURRENCY.ETH, value: 'NEAR-testnet', network: 'aurora-testnet', - }; + } as const; const nearTestnetCurrency = { type: RequestLogicTypes.CURRENCY.ETH, value: 'NEAR-testnet', network: 'near-testnet', - }; + } as const; const nativeTokenTestCases = [ { name: 'Near', @@ -60,7 +60,7 @@ describe('extensions/payment-network/native-token', () => { currency: nearTestnetCurrency, wrongCurrency: nearCurrency, }, - ]; + ] as const; nativeTokenTestCases.forEach((testCase) => { describe(`action creations for ${testCase.name}`, () => { @@ -148,7 +148,7 @@ describe('extensions/payment-network/native-token', () => { expect(() => { new NearNativePaymentNetwork().createCreationAction({ ...partialCreationParams, - paymentNetworkName: 'another-chain', + paymentNetworkName: 'another-chain' as CurrencyTypes.NearChainName, }); }).toThrowError( `Payment network 'another-chain' is not supported by this extension (only aurora)`, @@ -325,7 +325,7 @@ describe('extensions/payment-network/native-token', () => { }); it('throws on a wrong payment network', () => { const advancedLogic = new AdvancedLogic(); - const wrongNetwork = `wrong network`; + const wrongNetwork = `wrong network` as CurrencyTypes.EvmChainName; const wrongNativeTokenRequestState: typeof requestStateNoExtensions = { ...requestStateNoExtensions, diff --git a/packages/advanced-logic/test/utils/payment-network/erc777/stream-create-data-generator.ts b/packages/advanced-logic/test/utils/payment-network/erc777/stream-create-data-generator.ts index ee088e7db6..3ee89b7229 100644 --- a/packages/advanced-logic/test/utils/payment-network/erc777/stream-create-data-generator.ts +++ b/packages/advanced-logic/test/utils/payment-network/erc777/stream-create-data-generator.ts @@ -160,7 +160,7 @@ const baseRequestState = { state: RequestLogicTypes.STATE.CREATED, timestamp: TestData.arbitraryTimestamp, version, -}; +} as const; const baseRequestEvent = { actionSigner: { @@ -174,7 +174,7 @@ const baseRequestEvent = { isSignedRequest: false, }, timestamp: arbitraryTimestamp, -}; +} as const; export const requestStateNoExtensions: RequestLogicTypes.IRequest = { ...baseRequestState, diff --git a/packages/currency/README.md b/packages/currency/README.md index 9769df6dc7..7d4784be2d 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 shared between the @requestnetwork packages. +It is a collection of tools for the currencies and chains shared between the @requestnetwork packages. ## Installation @@ -51,6 +51,27 @@ 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/src/chains/ChainsAbstract.ts b/packages/currency/src/chains/ChainsAbstract.ts new file mode 100644 index 0000000000..523ca141c1 --- /dev/null +++ b/packages/currency/src/chains/ChainsAbstract.ts @@ -0,0 +1,62 @@ +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 (!chainName || !(this.chainNames as string[]).includes(chainName)) + throw new Error(`Unsupported chain ${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); + } +} diff --git a/packages/currency/src/chains/btc/BtcChains.ts b/packages/currency/src/chains/btc/BtcChains.ts new file mode 100644 index 0000000000..defd944134 --- /dev/null +++ b/packages/currency/src/chains/btc/BtcChains.ts @@ -0,0 +1,6 @@ +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/data/mainnet.ts b/packages/currency/src/chains/btc/data/mainnet.ts new file mode 100644 index 0000000000..2e046f8fd4 --- /dev/null +++ b/packages/currency/src/chains/btc/data/mainnet.ts @@ -0,0 +1 @@ +export const chainId = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'; diff --git a/packages/currency/src/chains/btc/data/testnet.ts b/packages/currency/src/chains/btc/data/testnet.ts new file mode 100644 index 0000000000..61ad4860df --- /dev/null +++ b/packages/currency/src/chains/btc/data/testnet.ts @@ -0,0 +1 @@ +export const chainId = '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'; diff --git a/packages/currency/src/chains/btc/index.ts b/packages/currency/src/chains/btc/index.ts new file mode 100644 index 0000000000..7c46a09b8e --- /dev/null +++ b/packages/currency/src/chains/btc/index.ts @@ -0,0 +1,14 @@ +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/evm/EvmChains.ts b/packages/currency/src/chains/evm/EvmChains.ts new file mode 100644 index 0000000000..f9ee82f6de --- /dev/null +++ b/packages/currency/src/chains/evm/EvmChains.ts @@ -0,0 +1,6 @@ +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 new file mode 100644 index 0000000000..8614655cb8 --- /dev/null +++ b/packages/currency/src/chains/evm/data/alfajores.ts @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000..7dd7a3a62d --- /dev/null +++ b/packages/currency/src/chains/evm/data/arbitrum-one.ts @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000..dd24630b18 --- /dev/null +++ b/packages/currency/src/chains/evm/data/arbitrum-rinkeby.ts @@ -0,0 +1 @@ +export const chainId = 421611; diff --git a/packages/currency/src/chains/evm/data/avalanche.ts b/packages/currency/src/chains/evm/data/avalanche.ts new file mode 100644 index 0000000000..6bd1c9f5d6 --- /dev/null +++ b/packages/currency/src/chains/evm/data/avalanche.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..b13f8f522a --- /dev/null +++ b/packages/currency/src/chains/evm/data/bsc.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..7fc2bc374e --- /dev/null +++ b/packages/currency/src/chains/evm/data/bsctest.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..f07c603cd4 --- /dev/null +++ b/packages/currency/src/chains/evm/data/celo.ts @@ -0,0 +1,7 @@ +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/fantom.ts b/packages/currency/src/chains/evm/data/fantom.ts new file mode 100644 index 0000000000..596a2db0db --- /dev/null +++ b/packages/currency/src/chains/evm/data/fantom.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..010d964245 --- /dev/null +++ b/packages/currency/src/chains/evm/data/fuse.ts @@ -0,0 +1 @@ +export const chainId = 122; diff --git a/packages/currency/src/chains/evm/data/goerli.ts b/packages/currency/src/chains/evm/data/goerli.ts new file mode 100644 index 0000000000..2668b32207 --- /dev/null +++ b/packages/currency/src/chains/evm/data/goerli.ts @@ -0,0 +1,7 @@ +import { TokenMap } from '../../../types'; +import { supportedGoerliERC20 } from '../../../erc20/chains/goerli'; + +export const chainId = 5; +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 new file mode 100644 index 0000000000..4e6bb83ceb --- /dev/null +++ b/packages/currency/src/chains/evm/data/mainnet.ts @@ -0,0 +1,7 @@ +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/matic.ts b/packages/currency/src/chains/evm/data/matic.ts new file mode 100644 index 0000000000..a7738d898c --- /dev/null +++ b/packages/currency/src/chains/evm/data/matic.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..de586f0b7b --- /dev/null +++ b/packages/currency/src/chains/evm/data/moonbeam.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..4e2cf0f738 --- /dev/null +++ b/packages/currency/src/chains/evm/data/mumbai.ts @@ -0,0 +1 @@ +export const chainId = 80001; diff --git a/packages/currency/src/chains/evm/data/optimism.ts b/packages/currency/src/chains/evm/data/optimism.ts new file mode 100644 index 0000000000..447d2f2300 --- /dev/null +++ b/packages/currency/src/chains/evm/data/optimism.ts @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000000..8334ef3906 --- /dev/null +++ b/packages/currency/src/chains/evm/data/private.ts @@ -0,0 +1 @@ +export const chainId = 0; diff --git a/packages/currency/src/chains/evm/data/rinkeby.ts b/packages/currency/src/chains/evm/data/rinkeby.ts new file mode 100644 index 0000000000..1d3610f911 --- /dev/null +++ b/packages/currency/src/chains/evm/data/rinkeby.ts @@ -0,0 +1,9 @@ +import { TokenMap } from '../../../types'; +import { supportedRinkebyERC20 } from '../../../erc20/chains/rinkeby'; +import { supportedRinkebyERC777 } from '../../../erc777/chains/rinkeby'; + +export const chainId = 4; +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 new file mode 100644 index 0000000000..ca79b559f7 --- /dev/null +++ b/packages/currency/src/chains/evm/data/ronin.ts @@ -0,0 +1 @@ +export const chainId = 2020; diff --git a/packages/currency/src/chains/evm/data/sokol.ts b/packages/currency/src/chains/evm/data/sokol.ts new file mode 100644 index 0000000000..ba023a8140 --- /dev/null +++ b/packages/currency/src/chains/evm/data/sokol.ts @@ -0,0 +1 @@ +export const chainId = 77; diff --git a/packages/currency/src/chains/evm/data/tombchain.ts b/packages/currency/src/chains/evm/data/tombchain.ts new file mode 100644 index 0000000000..43cc4b72b6 --- /dev/null +++ b/packages/currency/src/chains/evm/data/tombchain.ts @@ -0,0 +1 @@ +export const chainId = 6969; diff --git a/packages/currency/src/chains/evm/data/xdai.ts b/packages/currency/src/chains/evm/data/xdai.ts new file mode 100644 index 0000000000..edbf8ba0ce --- /dev/null +++ b/packages/currency/src/chains/evm/data/xdai.ts @@ -0,0 +1,7 @@ +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/index.ts b/packages/currency/src/chains/evm/index.ts new file mode 100644 index 0000000000..dc8c8ea2a3 --- /dev/null +++ b/packages/currency/src/chains/evm/index.ts @@ -0,0 +1,52 @@ +import { CurrencyTypes } from '@requestnetwork/types'; +import { Chain } from '../../types'; + +import * as AlfajoresDefinition from './data/alfajores'; +import * as ArbitrumOneDefinition from './data/arbitrum-one'; +import * as ArbitrumRinkebyDefinition from './data/arbitrum-rinkeby'; +import * as AvalancheDefinition from './data/avalanche'; +import * as BscDefinition from './data/bsc'; +import * as BscTestDefinition from './data/bsctest'; +import * as CeloDefinition from './data/celo'; +import * as FantomDefinition from './data/fantom'; +import * as FuseDefinition from './data/fuse'; +import * as GoerliDefinition from './data/goerli'; +import * as MainnetDefinition from './data/mainnet'; +import * as MaticDefinition from './data/matic'; +import * as MoonbeamDefinition from './data/moonbeam'; +import * as MumbaiDefinition from './data/mumbai'; +import * as OptimismDefinition from './data/optimism'; +import * as PrivateDefinition from './data/private'; +import * as RinkebyDefinition from './data/rinkeby'; +import * as RoninDefinition from './data/ronin'; +import * as SokolDefinition from './data/sokol'; +import * as TombchainDefinition from './data/tombchain'; +import * as XDaiDefinition from './data/xdai'; + +export type EvmChain = Chain & { + chainId: number; +}; + +export const chains: Record = { + alfajores: AlfajoresDefinition, + 'arbitrum-one': ArbitrumOneDefinition, + 'arbitrum-rinkeby': ArbitrumRinkebyDefinition, + avalanche: AvalancheDefinition, + bsc: BscDefinition, + bsctest: BscTestDefinition, + celo: CeloDefinition, + fantom: FantomDefinition, + fuse: FuseDefinition, + goerli: GoerliDefinition, + mainnet: MainnetDefinition, + matic: MaticDefinition, + moonbeam: MoonbeamDefinition, + mumbai: MumbaiDefinition, + optimism: OptimismDefinition, + private: PrivateDefinition, + rinkeby: RinkebyDefinition, // FIXME: Rinkeby is deprecated + ronin: RoninDefinition, + sokol: SokolDefinition, + tombchain: TombchainDefinition, + xdai: XDaiDefinition, +}; diff --git a/packages/currency/src/chains/index.ts b/packages/currency/src/chains/index.ts new file mode 100644 index 0000000000..cdac913071 --- /dev/null +++ b/packages/currency/src/chains/index.ts @@ -0,0 +1,5 @@ +import BtcChains from './btc/BtcChains'; +import EvmChains from './evm/EvmChains'; +import NearChains from './near/NearChains'; + +export { BtcChains, EvmChains, NearChains }; diff --git a/packages/currency/src/chains/near/NearChains.ts b/packages/currency/src/chains/near/NearChains.ts new file mode 100644 index 0000000000..411d734c56 --- /dev/null +++ b/packages/currency/src/chains/near/NearChains.ts @@ -0,0 +1,6 @@ +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/data/near-testnet.ts b/packages/currency/src/chains/near/data/near-testnet.ts new file mode 100644 index 0000000000..aeffcb72cd --- /dev/null +++ b/packages/currency/src/chains/near/data/near-testnet.ts @@ -0,0 +1 @@ +export const chainId = 'testnet'; diff --git a/packages/currency/src/chains/near/data/near.ts b/packages/currency/src/chains/near/data/near.ts new file mode 100644 index 0000000000..bc1566c787 --- /dev/null +++ b/packages/currency/src/chains/near/data/near.ts @@ -0,0 +1 @@ +export const chainId = 'mainnet'; diff --git a/packages/currency/src/chains/near/index.ts b/packages/currency/src/chains/near/index.ts new file mode 100644 index 0000000000..b35b78c7a1 --- /dev/null +++ b/packages/currency/src/chains/near/index.ts @@ -0,0 +1,14 @@ +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, // TODO: add support for near + 'near-testnet': NearTestnetDefinition, +}; diff --git a/packages/currency/src/conversion-aggregators.ts b/packages/currency/src/conversion-aggregators.ts index 5abf5aa23b..fb90a8d2af 100644 --- a/packages/currency/src/conversion-aggregators.ts +++ b/packages/currency/src/conversion-aggregators.ts @@ -10,6 +10,7 @@ import fantomAggregator from './aggregators/fantom.json'; import nearAggregator from './aggregators/near.json'; import nearTestnetAggregator from './aggregators/near-testnet.json'; import auroraTestnetAggregator from './aggregators/aurora-testnet.json'; +import { CurrencyTypes } from '@requestnetwork/types'; /** * currencyFrom => currencyTo => cost @@ -21,10 +22,12 @@ export type CurrencyPairs = Record>; * * Network => currencyFrom => currencyTo => cost */ -export type AggregatorsMap = Record; +export type AggregatorsMap = Partial< + Record +>; // 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, @@ -34,7 +37,7 @@ const chainlinkCurrencyPairs: AggregatorsMap = { }; // Pairs supported by Flux Protocol -const fluxCurrencyPairs: AggregatorsMap = { +const fluxCurrencyPairs: AggregatorsMap = { aurora: nearAggregator, 'aurora-testnet': auroraTestnetAggregator, 'near-testnet': nearTestnetAggregator, @@ -62,7 +65,9 @@ export const defaultConversionPairs: AggregatorsMap = { ...noConversionNetworks, }; -export const conversionSupportedNetworks = Object.keys(defaultConversionPairs); +export const conversionSupportedNetworks = Object.keys( + defaultConversionPairs, +) as CurrencyTypes.ChainName[]; /** * Gets the on-chain conversion path between two currencies. @@ -77,7 +82,7 @@ export const conversionSupportedNetworks = Object.keys(defaultConversionPairs); export function getPath( currencyFrom: Pick, currencyTo: Pick, - network = 'mainnet', + network: CurrencyTypes.ChainName = 'mainnet', pairs = defaultConversionPairs, ): string[] | null { if (!pairs[network]) { diff --git a/packages/currency/src/currencyManager.ts b/packages/currency/src/currencyManager.ts index 0d51b9a875..a9712cfb9e 100644 --- a/packages/currency/src/currencyManager.ts +++ b/packages/currency/src/currencyManager.ts @@ -1,4 +1,4 @@ -import { RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; import { utils } from 'ethers'; import addressValidator from 'multicoin-address-validator'; import { getSupportedERC20Tokens } from './erc20'; @@ -17,6 +17,7 @@ import { } from './types'; import { defaultConversionPairs, AggregatorsMap, getPath } from './conversion-aggregators'; import { isValidNearAddress } from './currency-utils'; +import { NearChains } from './chains'; const { BTC, ERC20, ERC777, ETH, ISO4217 } = RequestLogicTypes.CURRENCY; @@ -59,7 +60,7 @@ export class CurrencyManager implements ICurrencyManager */ from( currencyIdentifier: string | undefined, - network?: string, + network?: CurrencyTypes.ChainName, ): CurrencyDefinition | undefined { if (!currencyIdentifier) { return; @@ -70,7 +71,7 @@ export class CurrencyManager implements ICurrencyManager const parts = currencyIdentifier.split('-'); const currencyFromSymbol = - this.fromSymbol(parts[0], network || parts[1]) || + this.fromSymbol(parts[0], network || (parts[1] as CurrencyTypes.ChainName)) || // try without splitting the symbol to support currencies like ETH-rinkeby this.fromSymbol(currencyIdentifier, network); @@ -90,7 +91,7 @@ export class CurrencyManager implements ICurrencyManager /** * Gets a supported currency from its address and network. - * If more than 1 currencies are found, undefined is returned + * If more than one currency are found, undefined is returned */ fromAddress(address: string, network?: string): CurrencyDefinition | undefined { address = utils.getAddress(address); @@ -113,9 +114,12 @@ export class CurrencyManager implements ICurrencyManager /** * Gets a supported currency from its symbol and network. */ - fromSymbol(symbol: string, network?: string): CurrencyDefinition | undefined { + fromSymbol( + symbol: string, + network?: CurrencyTypes.ChainName, + ): CurrencyDefinition | undefined { symbol = symbol?.toUpperCase(); - network = network?.toLowerCase(); + network = network?.toLowerCase() as CurrencyTypes.ChainName | undefined; const legacy = network ? this.legacyTokens[network]?.[symbol] : undefined; if (legacy) { @@ -171,7 +175,7 @@ export class CurrencyManager implements ICurrencyManager getConversionPath( from: Pick, to: Pick, - network: string, + network: CurrencyTypes.ChainName, ): string[] | null { try { return getPath(from, to, network, this.conversionPairs); @@ -180,7 +184,10 @@ export class CurrencyManager implements ICurrencyManager } } - supportsConversion(currency: Pick, network: string): boolean { + supportsConversion( + currency: Pick, + network: CurrencyTypes.ChainName, + ): boolean { return !!this.conversionPairs[network]?.[currency.hash.toLowerCase()]; } @@ -237,13 +244,13 @@ export class CurrencyManager implements ICurrencyManager case RequestLogicTypes.CURRENCY.ETH: case RequestLogicTypes.CURRENCY.ERC20: case RequestLogicTypes.CURRENCY.ERC777: - switch (currency.network) { - case 'aurora': - case 'aurora-testnet': - return isValidNearAddress(address, currency.network); - default: - return addressValidator.validate(address, 'ETH'); + if ( + currency.network && + (NearChains.chainNames as CurrencyTypes.ChainName[]).includes(currency.network) + ) { + return isValidNearAddress(address, currency.network); } + return addressValidator.validate(address, 'ETH'); case RequestLogicTypes.CURRENCY.BTC: return addressValidator.validate( address, diff --git a/packages/currency/src/erc20/networks/avalanche.ts b/packages/currency/src/erc20/chains/avalanche.ts similarity index 95% rename from packages/currency/src/erc20/networks/avalanche.ts rename to packages/currency/src/erc20/chains/avalanche.ts index a6baabb97c..b9ca4bd490 100644 --- a/packages/currency/src/erc20/networks/avalanche.ts +++ b/packages/currency/src/erc20/chains/avalanche.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsc network tokens export const supportedAvalancheERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/bsc.ts b/packages/currency/src/erc20/chains/bsc.ts similarity index 89% rename from packages/currency/src/erc20/networks/bsc.ts rename to packages/currency/src/erc20/chains/bsc.ts index cfd9e8f731..c423a1003d 100644 --- a/packages/currency/src/erc20/networks/bsc.ts +++ b/packages/currency/src/erc20/chains/bsc.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsc network tokens export const supportedBSCERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/bsctest.ts b/packages/currency/src/erc20/chains/bsctest.ts similarity index 84% rename from packages/currency/src/erc20/networks/bsctest.ts rename to packages/currency/src/erc20/chains/bsctest.ts index 8bb28cf363..e5dd428752 100644 --- a/packages/currency/src/erc20/networks/bsctest.ts +++ b/packages/currency/src/erc20/chains/bsctest.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsctest network tokens export const supportedBSCTestERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/celo.ts b/packages/currency/src/erc20/chains/celo.ts similarity index 95% rename from packages/currency/src/erc20/networks/celo.ts rename to packages/currency/src/erc20/chains/celo.ts index cc107ec1c8..9e56e7882f 100644 --- a/packages/currency/src/erc20/networks/celo.ts +++ b/packages/currency/src/erc20/chains/celo.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported celo network tokens export const supportedCeloERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/fantom.ts b/packages/currency/src/erc20/chains/fantom.ts similarity index 57% rename from packages/currency/src/erc20/networks/fantom.ts rename to packages/currency/src/erc20/chains/fantom.ts index ca191095d7..33c47b9b79 100644 --- a/packages/currency/src/erc20/networks/fantom.ts +++ b/packages/currency/src/erc20/chains/fantom.ts @@ -1,6 +1,6 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; -export const supportedFantomTokens: TokenMap = { +export const supportedFantomERC20: TokenMap = { '0xD3b71117E6C1558c1553305b44988cd944e97300': { name: 'YEL Token', symbol: 'YEL', diff --git a/packages/currency/src/erc20/networks/goerli.ts b/packages/currency/src/erc20/chains/goerli.ts similarity index 86% rename from packages/currency/src/erc20/networks/goerli.ts rename to packages/currency/src/erc20/chains/goerli.ts index b8529468ec..68596661dd 100644 --- a/packages/currency/src/erc20/networks/goerli.ts +++ b/packages/currency/src/erc20/chains/goerli.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported goerli ERC20 tokens export const supportedGoerliERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/index.ts b/packages/currency/src/erc20/chains/index.ts similarity index 77% rename from packages/currency/src/erc20/networks/index.ts rename to packages/currency/src/erc20/chains/index.ts index a93f6c1def..a87dc6c8f4 100644 --- a/packages/currency/src/erc20/networks/index.ts +++ b/packages/currency/src/erc20/chains/index.ts @@ -1,25 +1,27 @@ -import { supportedRinkebyERC20 } from './rinkeby'; -import { supportedMainnetERC20 } from './mainnet'; -import { supportedCeloERC20 } from './celo'; -import { supportedMaticERC20 } from './matic'; -import type { TokenMap } from './types'; -import { supportedFantomTokens } from './fantom'; -import { supportedBSCTestERC20 } from './bsctest'; +import { TokenMap } from '../../types'; +import { CurrencyTypes } from '@requestnetwork/types'; + +import { supportedAvalancheERC20 } from './avalanche'; import { supportedBSCERC20 } from './bsc'; -import { supportedXDAIERC20 } from './xdai'; +import { supportedBSCTestERC20 } from './bsctest'; +import { supportedCeloERC20 } from './celo'; +import { supportedFantomERC20 } from './fantom'; import { supportedGoerliERC20 } from './goerli'; -import { supportedAvalancheERC20 } from './avalanche'; -import { supportedOptimismERC20 } from './optimism'; +import { supportedMainnetERC20 } from './mainnet'; +import { supportedMaticERC20 } from './matic'; import { supportedMoonbeamERC20 } from './moonbeam'; +import { supportedOptimismERC20 } from './optimism'; +import { supportedRinkebyERC20 } from './rinkeby'; +import { supportedXDAIERC20 } from './xdai'; -export const supportedNetworks: Record = { +export const supportedNetworks: Partial> = { celo: supportedCeloERC20, // FIXME: Rinkeby is deprecated rinkeby: supportedRinkebyERC20, goerli: supportedGoerliERC20, mainnet: supportedMainnetERC20, matic: supportedMaticERC20, - fantom: supportedFantomTokens, + fantom: supportedFantomERC20, bsctest: supportedBSCTestERC20, bsc: supportedBSCERC20, xdai: supportedXDAIERC20, @@ -27,5 +29,3 @@ export const supportedNetworks: Record = { optimism: supportedOptimismERC20, moonbeam: supportedMoonbeamERC20, }; - -export type { TokenMap }; diff --git a/packages/currency/src/erc20/networks/mainnet.ts b/packages/currency/src/erc20/chains/mainnet.ts similarity index 98% rename from packages/currency/src/erc20/networks/mainnet.ts rename to packages/currency/src/erc20/chains/mainnet.ts index 1744a84ca4..4026029f12 100644 --- a/packages/currency/src/erc20/networks/mainnet.ts +++ b/packages/currency/src/erc20/chains/mainnet.ts @@ -1,5 +1,5 @@ import * as metamaskContractMap from '@metamask/contract-metadata'; -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // These interfaces are declared here because they should be used only in this context // A Token description from the eth-contract-metadata list diff --git a/packages/currency/src/erc20/networks/matic.ts b/packages/currency/src/erc20/chains/matic.ts similarity index 94% rename from packages/currency/src/erc20/networks/matic.ts rename to packages/currency/src/erc20/chains/matic.ts index cdfd13754f..a3b8a01a7a 100644 --- a/packages/currency/src/erc20/networks/matic.ts +++ b/packages/currency/src/erc20/chains/matic.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported matic network tokens export const supportedMaticERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/moonbeam.ts b/packages/currency/src/erc20/chains/moonbeam.ts similarity index 89% rename from packages/currency/src/erc20/networks/moonbeam.ts rename to packages/currency/src/erc20/chains/moonbeam.ts index 88d9626ff8..12aca53a59 100644 --- a/packages/currency/src/erc20/networks/moonbeam.ts +++ b/packages/currency/src/erc20/chains/moonbeam.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsc network tokens export const supportedMoonbeamERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/optimism.ts b/packages/currency/src/erc20/chains/optimism.ts similarity index 91% rename from packages/currency/src/erc20/networks/optimism.ts rename to packages/currency/src/erc20/chains/optimism.ts index 8069f44a49..439c079c8c 100644 --- a/packages/currency/src/erc20/networks/optimism.ts +++ b/packages/currency/src/erc20/chains/optimism.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsc network tokens export const supportedOptimismERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/rinkeby.ts b/packages/currency/src/erc20/chains/rinkeby.ts similarity index 92% rename from packages/currency/src/erc20/networks/rinkeby.ts rename to packages/currency/src/erc20/chains/rinkeby.ts index 992e11a090..8540c0faab 100644 --- a/packages/currency/src/erc20/networks/rinkeby.ts +++ b/packages/currency/src/erc20/chains/rinkeby.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported rinkeby ERC20 tokens export const supportedRinkebyERC20: TokenMap = { diff --git a/packages/currency/src/erc20/networks/xdai.ts b/packages/currency/src/erc20/chains/xdai.ts similarity index 84% rename from packages/currency/src/erc20/networks/xdai.ts rename to packages/currency/src/erc20/chains/xdai.ts index 51b31f8b23..2dbbbb4114 100644 --- a/packages/currency/src/erc20/networks/xdai.ts +++ b/packages/currency/src/erc20/chains/xdai.ts @@ -1,4 +1,4 @@ -import { TokenMap } from './types'; +import { TokenMap } from '../../types'; // List of the supported bsc network tokens export const supportedXDAIERC20: TokenMap = { diff --git a/packages/currency/src/erc20/index.ts b/packages/currency/src/erc20/index.ts index b9ad3d9692..9a8bc5b7a3 100644 --- a/packages/currency/src/erc20/index.ts +++ b/packages/currency/src/erc20/index.ts @@ -1,5 +1,6 @@ -import { ERC20Currency } from '../types'; -import { supportedNetworks } from './networks'; +import { ERC20Currency, TokenMap } from '../types'; +import { supportedNetworks } from './chains'; +import { CurrencyTypes } from '@requestnetwork/types'; /** * Returns a list of supported ERC20 tokens @@ -7,7 +8,7 @@ import { supportedNetworks } from './networks'; * @returns List of supported ERC20 tokens */ export function getSupportedERC20Tokens(): ERC20Currency[] { - return Object.entries(supportedNetworks).reduce( + return (Object.entries(supportedNetworks) as [CurrencyTypes.EvmChainName, TokenMap][]).reduce( (acc: ERC20Currency[], [networkName, supportedCurrencies]) => { return [ ...acc, diff --git a/packages/currency/src/erc20/networks/types.ts b/packages/currency/src/erc20/networks/types.ts deleted file mode 100644 index 0ca9bf4f8b..0000000000 --- a/packages/currency/src/erc20/networks/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type TokenMap = Record; diff --git a/packages/currency/src/erc777/chains/index.ts b/packages/currency/src/erc777/chains/index.ts new file mode 100644 index 0000000000..05d09408bb --- /dev/null +++ b/packages/currency/src/erc777/chains/index.ts @@ -0,0 +1,7 @@ +import { supportedRinkebyERC777 } from './rinkeby'; +import { TokenMap } from '../../types'; +import { CurrencyTypes } from '@requestnetwork/types'; + +export const supportedNetworks: Partial> = { + rinkeby: supportedRinkebyERC777, +}; diff --git a/packages/currency/src/erc777/networks/rinkeby.ts b/packages/currency/src/erc777/chains/rinkeby.ts similarity index 84% rename from packages/currency/src/erc777/networks/rinkeby.ts rename to packages/currency/src/erc777/chains/rinkeby.ts index 53d1f842ab..407297a0ea 100644 --- a/packages/currency/src/erc777/networks/rinkeby.ts +++ b/packages/currency/src/erc777/chains/rinkeby.ts @@ -1,4 +1,4 @@ -import { TokenMap } from '../../erc20/networks/types'; +import { TokenMap } from '../../types'; // List of the supported rinkeby ERC777 tokens export const supportedRinkebyERC777: TokenMap = { diff --git a/packages/currency/src/erc777/index.ts b/packages/currency/src/erc777/index.ts index eb37f2dbca..36e2f5f53a 100644 --- a/packages/currency/src/erc777/index.ts +++ b/packages/currency/src/erc777/index.ts @@ -1,5 +1,6 @@ -import { ERC777Currency } from '../types'; -import { supportedNetworks } from './networks'; +import { ERC777Currency, TokenMap } from '../types'; +import { supportedNetworks } from './chains'; +import { CurrencyTypes } from '@requestnetwork/types'; /** * Returns a list of supported ERC777 tokens @@ -7,7 +8,7 @@ import { supportedNetworks } from './networks'; * @returns List of supported ERC777 tokens */ export function getSupportedERC777Tokens(): ERC777Currency[] { - return Object.entries(supportedNetworks).reduce( + return (Object.entries(supportedNetworks) as [CurrencyTypes.EvmChainName, TokenMap][]).reduce( (acc: ERC777Currency[], [networkName, supportedCurrencies]) => { return [ ...acc, diff --git a/packages/currency/src/erc777/networks/index.ts b/packages/currency/src/erc777/networks/index.ts deleted file mode 100644 index 9613ad7866..0000000000 --- a/packages/currency/src/erc777/networks/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { supportedRinkebyERC777 } from './rinkeby'; -import type { TokenMap } from '../../erc20/networks/types'; - -export const supportedNetworks: Record = { - rinkeby: supportedRinkebyERC777, -}; - -export type { TokenMap }; diff --git a/packages/currency/src/index.ts b/packages/currency/src/index.ts index c08a5e8f54..e3f77834d2 100644 --- a/packages/currency/src/index.ts +++ b/packages/currency/src/index.ts @@ -1,3 +1,4 @@ +export * from './chains'; export { getSupportedERC20Tokens } from './erc20'; export { getSupportedERC777Tokens } from './erc777'; export { diff --git a/packages/currency/src/native.ts b/packages/currency/src/native.ts index be240b3060..714b25bd9d 100644 --- a/packages/currency/src/native.ts +++ b/packages/currency/src/native.ts @@ -1,7 +1,13 @@ -import { RequestLogicTypes } from '@requestnetwork/types'; -import { NativeCurrency, NativeCurrencyType } from './types'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { NamedNativeCurrency } from './types'; -export const nativeCurrencies: Record = { +type NativeEthCurrency = NamedNativeCurrency & { + network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName; +}; +type NativeBtcCurrency = NamedNativeCurrency & { network: CurrencyTypes.BtcChainName }; + +export const nativeCurrencies: Record & + Record = { [RequestLogicTypes.CURRENCY.ETH]: [ { symbol: 'ETH', diff --git a/packages/currency/src/types.ts b/packages/currency/src/types.ts index 2437712f0c..ec6f3c3c08 100644 --- a/packages/currency/src/types.ts +++ b/packages/currency/src/types.ts @@ -1,4 +1,19 @@ -import { RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; + +/** + * Common types used in token configuration files + */ +type TokenAddress = string; +type TokenDefinition = { name: string; symbol: string; decimals: number }; +export type TokenMap = Record; + +/** + * Common types used in chain configuration files + */ +export type Chain = { + chainId: number | string; + currencies?: TokenMap; +}; /** * A native blockchain token (ETH, MATIC, ETH-rinkeby...) @@ -6,8 +21,10 @@ import { RequestLogicTypes } from '@requestnetwork/types'; export type NativeCurrency = { symbol: string; decimals: number; - network: string; + network: CurrencyTypes.ChainName; }; +type NamedCurrency = { name: string }; +export type NamedNativeCurrency = NativeCurrency & NamedCurrency; /** Native Currency types */ export type NativeCurrencyType = RequestLogicTypes.CURRENCY.BTC | RequestLogicTypes.CURRENCY.ETH; @@ -26,7 +43,7 @@ export type ISO4217Currency = { export type ERC20Currency = { symbol: string; decimals: number; - network: string; + network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName; address: string; }; @@ -36,7 +53,7 @@ export type ERC20Currency = { export type ERC777Currency = { symbol: string; decimals: number; - network: string; + network: CurrencyTypes.EvmChainName; address: string; }; @@ -118,4 +135,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 b8bde61383..04f6ed14e0 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 { RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; const currencyManager = new CurrencyManager([ ...CurrencyManager.getDefaultList(), @@ -14,12 +14,14 @@ 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'], - }).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'], + }) as [CurrencyTypes.EvmChainName, string[]][] + ).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { it(symbol, () => { @@ -33,10 +35,12 @@ describe('supported currencies with oracles from chainlink', () => { }); describe('native currencies', () => { - Object.entries({ - mainnet: ['ETH'], - fantom: ['FTM'], - }).forEach(([network, symbols]) => { + ( + Object.entries({ + mainnet: ['ETH'], + fantom: ['FTM'], + }) as [CurrencyTypes.EvmChainName, string[]][] + ).forEach(([network, symbols]) => { describe(network, () => { symbols.forEach((symbol) => { it(symbol, () => { @@ -50,29 +54,31 @@ 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'], - }).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'], + }) as [CurrencyTypes.EvmChainName, string[]][] + ).forEach(([network, addresses]) => { describe(network, () => { addresses.forEach((address) => { const currency = currencyManager.fromAddress(address, network)!; diff --git a/packages/currency/test/currency/erc20.test.ts b/packages/currency/test/currency/erc20.test.ts index b43c3cfc3f..5e39700650 100644 --- a/packages/currency/test/currency/erc20.test.ts +++ b/packages/currency/test/currency/erc20.test.ts @@ -1,6 +1,6 @@ import { getSupportedERC20Tokens } from '../../src/erc20'; import * as metamaskContractMap from '@metamask/contract-metadata'; -import { extraERC20Tokens } from '../../src/erc20/networks/mainnet'; +import { extraERC20Tokens } from '../../src/erc20/chains/mainnet'; import { utils } from 'ethers'; describe('erc20', () => { diff --git a/packages/currency/test/currencyManager.test.ts b/packages/currency/test/currencyManager.test.ts index a81e04d989..31a9d6c282 100644 --- a/packages/currency/test/currencyManager.test.ts +++ b/packages/currency/test/currencyManager.test.ts @@ -1,5 +1,11 @@ import { RequestLogicTypes } from '@requestnetwork/types'; -import { CurrencyInput, CurrencyDefinition, CurrencyManager, ERC20Currency } from '../src'; +import { + CurrencyInput, + CurrencyDefinition, + CurrencyManager, + ERC20Currency, + StorageCurrency, +} from '../src'; const testCasesPerNetwork: Record>> = { mainnet: { @@ -111,7 +117,7 @@ describe('CurrencyManager', () => { it('can instantiate a currency manager based on a currency list', () => { const list: CurrencyInput[] = [ - { type: RequestLogicTypes.CURRENCY.ETH, decimals: 18, network: 'anything', symbol: 'ANY' }, + { type: RequestLogicTypes.CURRENCY.ETH, decimals: 18, network: 'mainnet', symbol: 'ANY' }, ]; currencyManager = new CurrencyManager(list); expect(currencyManager.from('ANY')).toBeDefined(); @@ -593,7 +599,7 @@ describe('CurrencyManager', () => { describe('Validate currencies', () => { describe('Valid cases', () => { - it.each([ + const currencies: { currency: StorageCurrency; label: string }[] = [ { currency: { type: RequestLogicTypes.CURRENCY.ISO4217, @@ -641,14 +647,15 @@ describe('CurrencyManager', () => { }, label: 'ERC777 currency', }, - ])('Should validate $label', ({ currency }) => { + ]; + it.each(currencies)('Should validate $label', ({ currency }) => { const result = CurrencyManager.validateCurrency(currency); expect(result).toBe(true); }); }); describe('Invalid cases', () => { - it.each([ + const currencies: { currency: StorageCurrency; label: string }[] = [ { currency: { type: RequestLogicTypes.CURRENCY.ERC20, @@ -673,7 +680,8 @@ describe('CurrencyManager', () => { }, label: 'ERC777 currency', }, - ])('Should not validate an invalid $label', ({ currency }) => { + ]; + it.each(currencies)('Should not validate an invalid $label', ({ currency }) => { const result = CurrencyManager.validateCurrency(currency); expect(result).toBe(false); }); diff --git a/packages/ethereum-storage/package.json b/packages/ethereum-storage/package.json index 1a444f241b..fd0a07e5dd 100644 --- a/packages/ethereum-storage/package.json +++ b/packages/ethereum-storage/package.json @@ -40,6 +40,7 @@ "init-ipfs": "node scripts/init-ipfs.js" }, "dependencies": { + "@requestnetwork/currency": "0.9.0", "@requestnetwork/smart-contracts": "0.29.0", "@requestnetwork/types": "0.36.0", "@requestnetwork/utils": "0.36.0", diff --git a/packages/ethereum-storage/src/config.ts b/packages/ethereum-storage/src/config.ts index ced6ca7724..77e0d80daf 100644 --- a/packages/ethereum-storage/src/config.ts +++ b/packages/ethereum-storage/src/config.ts @@ -1,4 +1,4 @@ -import { StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, StorageTypes } from '@requestnetwork/types'; import { BigNumber } from 'ethers'; // This contains default values used to use Ethereum Network and IPFS @@ -73,7 +73,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(): string { +export function getDefaultEthereumNetwork(): CurrencyTypes.EvmChainName { return config.ethereum.default; } diff --git a/packages/ethereum-storage/src/ethereum-storage-ethers.ts b/packages/ethereum-storage/src/ethereum-storage-ethers.ts index 05e7737ddc..34817a143e 100644 --- a/packages/ethereum-storage/src/ethereum-storage-ethers.ts +++ b/packages/ethereum-storage/src/ethereum-storage-ethers.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'events'; import { BigNumber, ContractReceipt, providers, Signer } from 'ethers'; import TypedEmitter from 'typed-emitter'; -import { LogTypes, StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; import { requestHashSubmitterArtifact } from '@requestnetwork/smart-contracts'; import { EthereumTransactionSubmitter } from './ethereum-tx-submitter'; import { getCurrentTimestampInSecond, SimpleLogger } from '@requestnetwork/utils'; @@ -11,7 +11,7 @@ export type GasDefinerProps = { }; export type SubmitterProps = GasDefinerProps & { - network: string; + network: CurrencyTypes.EvmChainName; signer: Signer; logger?: LogTypes.ILogger; }; @@ -29,7 +29,7 @@ export class EthereumStorageEthers implements StorageTypes.IStorageWrite { private readonly logger: LogTypes.ILogger; private readonly ipfsStorage: StorageTypes.IIpfsStorage; - private readonly network: string; + private readonly network: CurrencyTypes.EvmChainName; private readonly txSubmitter: EthereumTransactionSubmitter; constructor({ network, signer, ipfsStorage, logger, gasPriceMin }: StorageProps) { diff --git a/packages/ethereum-storage/src/ethereum-utils.ts b/packages/ethereum-storage/src/ethereum-utils.ts index 75351078fa..fae9c21aab 100644 --- a/packages/ethereum-storage/src/ethereum-utils.ts +++ b/packages/ethereum-storage/src/ethereum-utils.ts @@ -1,50 +1,46 @@ -import { StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, StorageTypes } from '@requestnetwork/types'; import * as config from './config'; import { BigNumber } from 'ethers'; +import { EvmChains } from '@requestnetwork/currency'; -const networks = { - [StorageTypes.EthereumNetwork.PRIVATE]: 'private', - [StorageTypes.EthereumNetwork.MAINNET]: 'mainnet', - [StorageTypes.EthereumNetwork.KOVAN]: 'kovan', - [StorageTypes.EthereumNetwork.RINKEBY]: 'rinkeby', - [StorageTypes.EthereumNetwork.GOERLI]: 'goerli', - [StorageTypes.EthereumNetwork.SOKOL]: 'sokol', - [StorageTypes.EthereumNetwork.XDAI]: 'xdai', -}; +/** + * Collection of utils functions related to Ethereum Storage + */ /** - * Collection of utils functions related to Ethereum + * Get the name of the Ethereum network from its id + * + * @param networkId Id of the network + * @return name of the network */ -export default { - /** - * Get the name of the Ethereum network from its id - * - * @param networkId Id of the network - * @return name of the network - */ - getEthereumNetworkNameFromId(networkId: StorageTypes.EthereumNetwork): string { - return networks[networkId]; - }, +export const getEthereumStorageNetworkNameFromId = ( + networkId: StorageTypes.EthereumNetwork, +): CurrencyTypes.EvmChainName => { + const chainName = EvmChains.getChainName(networkId); + if (!chainName) { + // this should never happen + throw new Error(`Unsupported storage chain: ${networkId}`); + } + return chainName; +}; - getEthereumIdFromNetworkName(name: string): StorageTypes.EthereumNetwork | undefined { - const id = Object.entries(networks).find((entry) => entry[1] === name)?.[0]; - if (!id) { - return undefined; - } - return Number(id) as StorageTypes.EthereumNetwork; - }, +export const getEthereumStorageNetworkIdFromName = ( + name: CurrencyTypes.EvmChainName, +): number | undefined => { + const networkId = EvmChains.getChainId(name); + return Object.values(StorageTypes.EthereumNetwork).includes(networkId) ? networkId : undefined; +}; - /** - * Ensure the gas price returned by an API is safe to use - * An API could return a high value if it's corrupted or if the format changes - * The web3 provider would not in certain cases ask the user for confirmation - * therefore we have to ensure the gas price is not too high - * - * @param gasPrice Value of the gas price - * @returns True if the gas price can be used - */ - isGasPriceSafe(gasPrice: BigNumber): boolean { - return gasPrice.gt(0) && gasPrice.lt(config.getSafeGasPriceLimit()); - }, +/** + * Ensure the gas price returned by an API is safe to use + * An API could return a high value if it's corrupted or if the format changes + * The web3 provider would not in certain cases ask the user for confirmation + * therefore we have to ensure the gas price is not too high + * + * @param gasPrice Value of the gas price + * @returns True if the gas price can be used + */ +export const isGasPriceSafe = (gasPrice: BigNumber): boolean => { + return gasPrice.gt(0) && gasPrice.lt(config.getSafeGasPriceLimit()); }; diff --git a/packages/ethereum-storage/src/gas-price-definer.ts b/packages/ethereum-storage/src/gas-price-definer.ts index 7bd232392b..bf6c1209a1 100644 --- a/packages/ethereum-storage/src/gas-price-definer.ts +++ b/packages/ethereum-storage/src/gas-price-definer.ts @@ -1,15 +1,15 @@ import * as config from './config'; -import EthereumUtils from './ethereum-utils'; import EtherchainProvider from './gas-price-providers/etherchain-provider'; import EtherscanProvider from './gas-price-providers/etherscan-provider'; import EthGasStationProvider from './gas-price-providers/ethgasstation-provider'; -import { LogTypes, StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; import { BigNumber } from 'ethers'; import XDaiFixedProvider from './gas-price-providers/xdai-fixed-provider'; import { GasDefinerProps } from './ethereum-storage-ethers'; import { SimpleLogger } from '@requestnetwork/utils'; +import { getEthereumStorageNetworkIdFromName } from './ethereum-utils'; /** * Determines the gas price to use depending on the used network @@ -61,9 +61,9 @@ export class GasPriceDefiner { */ public async getGasPrice( type: StorageTypes.GasPriceType, - networkName: string, + networkName: CurrencyTypes.EvmChainName, ): Promise { - const network = EthereumUtils.getEthereumIdFromNetworkName(networkName); + const network = getEthereumStorageNetworkIdFromName(networkName); if (network) { const gasPriceArray = await this.pollProviders(type, network); if (gasPriceArray.length > 0) { diff --git a/packages/ethereum-storage/src/gas-price-providers/etherchain-provider.ts b/packages/ethereum-storage/src/gas-price-providers/etherchain-provider.ts index 3f7b9e5a79..135612fc41 100644 --- a/packages/ethereum-storage/src/gas-price-providers/etherchain-provider.ts +++ b/packages/ethereum-storage/src/gas-price-providers/etherchain-provider.ts @@ -1,11 +1,10 @@ -import EthereumUtils from '../ethereum-utils'; - import { StorageTypes } from '@requestnetwork/types'; import Axios from 'axios'; import { BigNumber } from 'ethers'; import { retry } from '@requestnetwork/utils'; +import { isGasPriceSafe } from '../ethereum-utils'; // Maximum number of api requests to retry when an error is encountered (ECONNRESET, EPIPE, ENOTFOUND) const ETHERCHAIN_REQUEST_MAX_RETRY = 3; @@ -68,7 +67,7 @@ export default class EtherchainProvider implements StorageTypes.IGasPriceProvide ) * API_MULTIPLIER, ); - if (!EthereumUtils.isGasPriceSafe(apiGasPrice)) { + if (!isGasPriceSafe(apiGasPrice)) { throw Error(`Etherchain provided gas price not safe to use: ${apiGasPrice}`); } diff --git a/packages/ethereum-storage/src/gas-price-providers/etherscan-provider.ts b/packages/ethereum-storage/src/gas-price-providers/etherscan-provider.ts index f84928d4ac..40272bdeef 100644 --- a/packages/ethereum-storage/src/gas-price-providers/etherscan-provider.ts +++ b/packages/ethereum-storage/src/gas-price-providers/etherscan-provider.ts @@ -1,11 +1,10 @@ -import EthereumUtils from '../ethereum-utils'; - import { StorageTypes } from '@requestnetwork/types'; import Axios from 'axios'; import { BigNumber } from 'ethers'; import { retry } from '@requestnetwork/utils'; +import { isGasPriceSafe } from '../ethereum-utils'; // Maximum number of api requests to retry when an error is encountered (ECONNRESET, EPIPE, ENOTFOUND) const ETHERSCAN_REQUEST_MAX_RETRY = 3; @@ -76,7 +75,7 @@ export default class EtherscanProvider implements StorageTypes.IGasPriceProvider ) * API_MULTIPLIER, ); - if (!EthereumUtils.isGasPriceSafe(apiGasPrice)) { + if (!isGasPriceSafe(apiGasPrice)) { throw Error(`Etherscan provided gas price not safe to use: ${apiGasPrice}`); } diff --git a/packages/ethereum-storage/src/gas-price-providers/ethgasstation-provider.ts b/packages/ethereum-storage/src/gas-price-providers/ethgasstation-provider.ts index 411a75e0b2..65c5146061 100644 --- a/packages/ethereum-storage/src/gas-price-providers/ethgasstation-provider.ts +++ b/packages/ethereum-storage/src/gas-price-providers/ethgasstation-provider.ts @@ -1,10 +1,9 @@ -import EthereumUtils from '../ethereum-utils'; - import { StorageTypes } from '@requestnetwork/types'; import Axios from 'axios'; import { BigNumber } from 'ethers'; import { retry } from '@requestnetwork/utils'; +import { isGasPriceSafe } from '../ethereum-utils'; // Maximum number of api requests to retry when an error is encountered (ECONNRESET, EPIPE, ENOTFOUND) const ETHGASSTATION_REQUEST_MAX_RETRY = 3; @@ -67,7 +66,7 @@ export default class EthGasStationProvider implements StorageTypes.IGasPriceProv ) * API_MULTIPLIER, ); - if (!EthereumUtils.isGasPriceSafe(apiGasPrice)) { + if (!isGasPriceSafe(apiGasPrice)) { throw Error(`EthGasStation provided gas price not safe to use: ${apiGasPrice}`); } diff --git a/packages/ethereum-storage/src/index.ts b/packages/ethereum-storage/src/index.ts index 4af2a8b5c3..a80514931c 100644 --- a/packages/ethereum-storage/src/index.ts +++ b/packages/ethereum-storage/src/index.ts @@ -1,4 +1,8 @@ export { EthereumStorage } from './ethereum-storage'; +export { + getEthereumStorageNetworkNameFromId, + getEthereumStorageNetworkIdFromName, +} from './ethereum-utils'; export { EthereumStorageEthers } from './ethereum-storage-ethers'; export { EthereumTransactionSubmitter } from './ethereum-tx-submitter'; export { GasPriceDefiner } from './gas-price-definer'; diff --git a/packages/ethereum-storage/src/smart-contract-manager.ts b/packages/ethereum-storage/src/smart-contract-manager.ts index 2c184c37ae..10765f588f 100644 --- a/packages/ethereum-storage/src/smart-contract-manager.ts +++ b/packages/ethereum-storage/src/smart-contract-manager.ts @@ -1,16 +1,9 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { LogTypes, StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, LogTypes, StorageTypes } from '@requestnetwork/types'; import * as Bluebird from 'bluebird'; import * as config from './config'; import EthereumBlocks from './ethereum-blocks'; -import EthereumUtils from './ethereum-utils'; import { GasPriceDefiner } from './gas-price-definer'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const web3Eth = require('web3-eth'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const web3Utils = require('web3-utils'); - import { BigNumber } from 'ethers'; import { flatten2DimensionsArray, @@ -18,6 +11,12 @@ import { SimpleLogger, timeoutPromise, } from '@requestnetwork/utils'; +import { getEthereumStorageNetworkNameFromId } from './ethereum-utils'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const web3Eth = require('web3-eth'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const web3Utils = require('web3-utils'); // Maximum number of attempt to create ethereum metadata when transaction to add hash and size to Ethereum is confirmed // 23 is the number of call of the transaction's confirmation event function @@ -51,7 +50,7 @@ export default class SmartContractManager { */ public maxConcurrency: number; - protected networkName = ''; + protected networkName: CurrencyTypes.EvmChainName = 'private'; protected hashStorageAddress: string; protected hashSubmitterAddress: string; @@ -134,12 +133,7 @@ export default class SmartContractManager { this.networkName = typeof web3Connection.networkId === 'undefined' ? config.getDefaultEthereumNetwork() - : EthereumUtils.getEthereumNetworkNameFromId(web3Connection.networkId); - - // If networkName is undefined, it means the network doesn't exist - if (typeof this.networkName === 'undefined') { - throw Error(`The network id ${web3Connection.networkId} doesn't exist`); - } + : getEthereumStorageNetworkNameFromId(web3Connection.networkId); this.hashStorageAddress = SmartContracts.requestHashStorageArtifact.getAddress( this.networkName, diff --git a/packages/ethereum-storage/test/ethereum-utils.test.ts b/packages/ethereum-storage/test/ethereum-utils.test.ts index a423b9ddad..72b5bd21ce 100644 --- a/packages/ethereum-storage/test/ethereum-utils.test.ts +++ b/packages/ethereum-storage/test/ethereum-utils.test.ts @@ -1,86 +1,73 @@ import { StorageTypes } from '@requestnetwork/types'; import { getSafeGasPriceLimit } from '../src/config'; -import EthereumUtils from '../src/ethereum-utils'; import { BigNumber } from 'ethers'; +import { + getEthereumStorageNetworkIdFromName, + getEthereumStorageNetworkNameFromId, + isGasPriceSafe, +} from '../src/ethereum-utils'; /* eslint-disable @typescript-eslint/no-unused-expressions */ describe('Ethereum Utils', () => { - describe('getEthereumNetworkNameFromId', () => { + describe('getEthereumStorageNetworkNameFromId', () => { it('allows to get the correct network name', async () => { - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.PRIVATE)).toBe( + expect(getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.PRIVATE)).toBe( 'private', ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET)).toBe( + expect(getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET)).toBe( 'mainnet', ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.KOVAN)).toBe( - 'kovan', - ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.RINKEBY)).toBe( + expect(getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.RINKEBY)).toBe( 'rinkeby', ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.GOERLI)).toBe( + expect(getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.GOERLI)).toBe( 'goerli', ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.SOKOL)).toBe( - 'sokol', - ); - expect(EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.XDAI)).toBe( - 'xdai', - ); + expect(getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.XDAI)).toBe('xdai'); }); - it(`should return undefined if the network doesn't exist`, async () => { - expect(EthereumUtils.getEthereumNetworkNameFromId(2000)).toBeUndefined(); + it(`should throw if the storage network is not supported`, async () => { + expect(() => getEthereumStorageNetworkNameFromId(2000)).toThrowError( + 'Unsupported storage chain: 2000', + ); }); }); - describe('getEthereumIdFromNetworkName', () => { + describe('getEthereumStorageNetworkIdFromName', () => { it('allows to get the correct network name', async () => { - expect(EthereumUtils.getEthereumIdFromNetworkName('private')).toBe( + expect(getEthereumStorageNetworkIdFromName('private')).toBe( StorageTypes.EthereumNetwork.PRIVATE, ); - expect(EthereumUtils.getEthereumIdFromNetworkName('mainnet')).toBe( + expect(getEthereumStorageNetworkIdFromName('mainnet')).toBe( StorageTypes.EthereumNetwork.MAINNET, ); - expect(EthereumUtils.getEthereumIdFromNetworkName('kovan')).toBe( - StorageTypes.EthereumNetwork.KOVAN, - ); - expect(EthereumUtils.getEthereumIdFromNetworkName('rinkeby')).toBe( + expect(getEthereumStorageNetworkIdFromName('rinkeby')).toBe( StorageTypes.EthereumNetwork.RINKEBY, ); - expect(EthereumUtils.getEthereumIdFromNetworkName('goerli')).toBe( + expect(getEthereumStorageNetworkIdFromName('goerli')).toBe( StorageTypes.EthereumNetwork.GOERLI, ); - expect(EthereumUtils.getEthereumIdFromNetworkName('sokol')).toBe( - StorageTypes.EthereumNetwork.SOKOL, - ); - expect(EthereumUtils.getEthereumIdFromNetworkName('xdai')).toBe( - StorageTypes.EthereumNetwork.XDAI, - ); + expect(getEthereumStorageNetworkIdFromName('xdai')).toBe(StorageTypes.EthereumNetwork.XDAI); }); - it(`should return undefined if the network doesn't exist`, async () => { - expect(EthereumUtils.getEthereumIdFromNetworkName('wrong')).toBeUndefined(); + it(`should return undefined if the network is not supported for storage`, async () => { + expect(getEthereumStorageNetworkIdFromName('avalanche')).toBeUndefined(); + expect(getEthereumStorageNetworkIdFromName('mumbai')).toBeUndefined(); }); }); describe('isGasPriceSafe', () => { it('should return true when a safe value is given', async () => { - expect(EthereumUtils.isGasPriceSafe(BigNumber.from(1))).toBe(true); - expect(EthereumUtils.isGasPriceSafe(BigNumber.from(1000))).toBe(true); - expect( - EthereumUtils.isGasPriceSafe(BigNumber.from(parseInt(getSafeGasPriceLimit()) - 1)), - ).toBe(true); + expect(isGasPriceSafe(BigNumber.from(1))).toBe(true); + expect(isGasPriceSafe(BigNumber.from(1000))).toBe(true); + expect(isGasPriceSafe(BigNumber.from(parseInt(getSafeGasPriceLimit()) - 1))).toBe(true); }); it('should return false when an unsafe value is given', async () => { - expect(EthereumUtils.isGasPriceSafe(BigNumber.from(0))).toBe(false); - expect(EthereumUtils.isGasPriceSafe(BigNumber.from(parseInt(getSafeGasPriceLimit())))).toBe( - false, - ); + expect(isGasPriceSafe(BigNumber.from(0))).toBe(false); + expect(isGasPriceSafe(BigNumber.from(parseInt(getSafeGasPriceLimit())))).toBe(false); }); }); }); diff --git a/packages/ethereum-storage/test/gas-price-definer.test.ts b/packages/ethereum-storage/test/gas-price-definer.test.ts index 0dea696cd4..8f19e3e317 100644 --- a/packages/ethereum-storage/test/gas-price-definer.test.ts +++ b/packages/ethereum-storage/test/gas-price-definer.test.ts @@ -1,10 +1,9 @@ /* eslint-disable no-magic-numbers */ import { StorageTypes } from '@requestnetwork/types'; -import EthereumUtils from '../src/ethereum-utils'; +import { GasPriceDefiner, getEthereumStorageNetworkNameFromId } from '../src'; import * as config from '../src/config'; -import { GasPriceDefiner } from '../src/gas-price-definer'; import { BigNumber } from 'ethers'; @@ -24,7 +23,7 @@ describe('GasPriceDefiner', () => { }; const gasPrice = await gasPriceDefiner.getGasPrice( StorageTypes.GasPriceType.STANDARD, - EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.RINKEBY), + getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.RINKEBY), ); expect(gasPrice).toEqual(config.getDefaultEthereumGasPrice()); @@ -41,7 +40,7 @@ describe('GasPriceDefiner', () => { }; const gasPrice = await gasPriceDefiner.getGasPrice( StorageTypes.GasPriceType.STANDARD, - EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.XDAI), + getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.XDAI), ); expect(gasPrice).toEqual(BigNumber.from(2)); @@ -53,7 +52,7 @@ describe('GasPriceDefiner', () => { ): Promise => Promise.resolve([]); const gasPrice = await gasPriceDefiner.getGasPrice( StorageTypes.GasPriceType.STANDARD, - EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET), + getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET), ); expect(gasPrice).toEqual(config.getDefaultEthereumGasPrice()); @@ -72,7 +71,7 @@ describe('GasPriceDefiner', () => { const gasPrice = await gasPriceDefiner.getGasPrice( StorageTypes.GasPriceType.STANDARD, - EthereumUtils.getEthereumNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET), + getEthereumStorageNetworkNameFromId(StorageTypes.EthereumNetwork.MAINNET), ); expect(gasPrice).toEqual(BigNumber.from(300)); diff --git a/packages/ethereum-storage/test/smartcontract-manager.test.ts b/packages/ethereum-storage/test/smartcontract-manager.test.ts index 1504e49186..597a00c1fd 100644 --- a/packages/ethereum-storage/test/smartcontract-manager.test.ts +++ b/packages/ethereum-storage/test/smartcontract-manager.test.ts @@ -1,5 +1,5 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { StorageTypes } from '@requestnetwork/types'; +import { CurrencyTypes, StorageTypes } from '@requestnetwork/types'; import EthereumBlocks from '../src/ethereum-blocks'; import SmartContractManager from '../src/smart-contract-manager'; @@ -407,19 +407,23 @@ describe('SmartContractManager', () => { it('initializes smartcontract-manager with an invalid network should throw an error', () => { expect(() => new SmartContractManager(invalidNetworkWeb3Connection)).toThrowError( - `The network id ${invalidNetwork} doesn't exist`, + `Unsupported storage chain: ${invalidNetwork}`, ); }); it('getAddress in artifactsRequestHashStorageUtils with a invalid host network should throw an error', () => { - expect(() => SmartContracts.requestHashStorageArtifact.getAddress('nonexistent')).toThrowError( - 'No deployment for network', - ); + expect(() => + SmartContracts.requestHashStorageArtifact.getAddress( + 'nonexistent' as CurrencyTypes.EvmChainName, + ), + ).toThrowError('No deployment for network'); }); it('getAddress in artifactsRequestHashSubmitterUtils with a invalid host network should throw an error', () => { expect(() => - SmartContracts.requestHashSubmitterArtifact.getAddress('nonexistent'), + SmartContracts.requestHashSubmitterArtifact.getAddress( + 'nonexistent' as CurrencyTypes.EvmChainName, + ), ).toThrowError('No deployment for network'); }); diff --git a/packages/integration-test/test/node-client.test.ts b/packages/integration-test/test/node-client.test.ts index 41a1ae5283..a070ea72be 100644 --- a/packages/integration-test/test/node-client.test.ts +++ b/packages/integration-test/test/node-client.test.ts @@ -541,7 +541,7 @@ describe('ERC20 localhost request creation and detection test', () => { it.only('can create ERC20 requests with any to erc20 proxy', async () => { const tokenContractAddress = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35'; - const currencies = [ + const currencies: CurrencyInput[] = [ ...CurrencyManager.getDefaultList(), { address: tokenContractAddress, diff --git a/packages/integration-test/test/scheduled/btc-test-data.ts b/packages/integration-test/test/scheduled/btc-test-data.ts index 24a89eacab..f4bcd52806 100644 --- a/packages/integration-test/test/scheduled/btc-test-data.ts +++ b/packages/integration-test/test/scheduled/btc-test-data.ts @@ -24,7 +24,7 @@ export const payer = { }, }; -export const testnetRequestData = { +export const testnetRequestData: RequestLogicTypes.ICreateParameters = { currency: { network: 'testnet', type: RequestLogicTypes.CURRENCY.BTC, @@ -36,7 +36,7 @@ export const testnetRequestData = { timestamp: arbitraryTimestamp, }; -export const requestData = { +export const requestData: RequestLogicTypes.ICreateParameters = { currency: { type: RequestLogicTypes.CURRENCY.BTC, value: 'BTC', diff --git a/packages/integration-test/test/scheduled/erc777-stream.test.ts b/packages/integration-test/test/scheduled/erc777-stream.test.ts index aca5430701..a57d187432 100644 --- a/packages/integration-test/test/scheduled/erc777-stream.test.ts +++ b/packages/integration-test/test/scheduled/erc777-stream.test.ts @@ -1,5 +1,6 @@ import { SuperFluidPaymentDetector } from '@requestnetwork/payment-detection'; import { + CurrencyTypes, ExtensionTypes, IdentityTypes, PaymentTypes, @@ -15,10 +16,9 @@ const createMockRequest = ({ paymentAddress, salt, requestId, -}: Record< - 'network' | 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId', - string ->): RequestLogicTypes.IRequest => ({ +}: Record<'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId', string> & { + network: CurrencyTypes.EvmChainName; +}): 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 509e5a80d1..508fec8fb7 100644 --- a/packages/integration-test/test/utils.ts +++ b/packages/integration-test/test/utils.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, IdentityTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + IdentityTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; export const createMockErc20FeeRequest = ({ network, @@ -9,9 +14,9 @@ export const createMockErc20FeeRequest = ({ feeAddress, feeAmount, }: Record< - 'network' | 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', + 'tokenAddress' | 'paymentAddress' | 'salt' | 'requestId' | 'feeAddress' | 'feeAmount', string ->): RequestLogicTypes.IRequest => ({ +> & { network: CurrencyTypes.EvmChainName }): RequestLogicTypes.IRequest => ({ creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { network, 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 9e336cc8c8..d8d2a6bb91 100644 --- a/packages/payment-detection/src/any/any-to-erc20-proxy.ts +++ b/packages/payment-detection/src/any/any-to-erc20-proxy.ts @@ -1,11 +1,17 @@ import { erc20ConversionProxy } from '@requestnetwork/smart-contracts'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { ERC20FeeProxyPaymentDetectorBase } from '../erc20/fee-proxy-contract'; import { AnyToErc20InfoRetriever } from './retrievers/any-to-erc20-proxy'; import { TheGraphInfoRetriever } from '../thegraph'; import { makeGetDeploymentInformation } from '../utils'; import { PaymentNetworkOptions, ReferenceBasedDetectorOptions } from '../types'; import { generate8randomBytes } from '@requestnetwork/utils'; +import { EvmChains } from '@requestnetwork/currency'; const PROXY_CONTRACT_ADDRESS_MAP = { ['0.1.0']: '0.1.0', @@ -78,7 +84,7 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { @@ -130,11 +136,12 @@ export class AnyToERC20PaymentDetector extends ERC20FeeProxyPaymentDetectorBase< }; } - protected getPaymentChain(request: RequestLogicTypes.IRequest): string { + protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.EvmChainName { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } + EvmChains.assertChainSupported(network); return network; } 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 839a692320..64cb911ad1 100644 --- a/packages/payment-detection/src/any/any-to-eth-proxy.ts +++ b/packages/payment-detection/src/any/any-to-eth-proxy.ts @@ -1,7 +1,12 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; -import { UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { AnyToEthInfoRetriever } from './retrievers/any-to-eth-proxy'; import { AnyToAnyDetector } from '../any-to-any-detector'; @@ -58,7 +63,7 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { @@ -117,11 +122,12 @@ export class AnyToEthFeeProxyPaymentDetector extends AnyToAnyDetector< * @param paymentNetwork the payment network * @returns The network of payment */ - protected getPaymentChain(request: RequestLogicTypes.IRequest): string { + protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.EvmChainName { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } + EvmChains.assertChainSupported(network); return network; } diff --git a/packages/payment-detection/src/erc20/currency.ts b/packages/payment-detection/src/erc20/currency.ts index 68b8888a14..a8d938a673 100644 --- a/packages/payment-detection/src/erc20/currency.ts +++ b/packages/payment-detection/src/erc20/currency.ts @@ -1,6 +1,7 @@ import { CurrencyDefinition, CurrencyManager, + EvmChains, getCurrencyHash, StorageCurrency, } from '@requestnetwork/currency'; @@ -8,32 +9,39 @@ 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'; export const loadCurrencyFromContract = async ( currency: StorageCurrency, ): Promise => { - if (!currency.network || !isAddress(currency.value)) { - return null; - } - try { - const contract = ERC20__factory.connect(currency.value, getDefaultProvider(currency.network)); + const { network, value } = currency; + + if (!network || !isAddress(value)) { + return null; + } + EvmChains.assertChainSupported(network); + + const contract = ERC20__factory.connect(value, getDefaultProvider(network)); const decimals = await contract.decimals(); if (!decimals) { return null; } + const symbol = await contract.symbol(); if (!symbol) { return null; } - const definition = { - address: currency.value, + + const definition: ERC20CurrencyInput = { + address: value, decimals, symbol, - network: currency.network, + network: network, type: RequestLogicTypes.CURRENCY.ERC20, }; + return { ...definition, id: CurrencyManager.currencyId(definition), diff --git a/packages/payment-detection/src/erc20/fee-proxy-contract.ts b/packages/payment-detection/src/erc20/fee-proxy-contract.ts index 14c7417ba5..3bca522a78 100644 --- a/packages/payment-detection/src/erc20/fee-proxy-contract.ts +++ b/packages/payment-detection/src/erc20/fee-proxy-contract.ts @@ -1,5 +1,10 @@ import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { CurrencyDefinition, ICurrencyManager } from '@requestnetwork/currency'; import ProxyInfoRetriever from './proxy-info-retriever'; @@ -84,7 +89,7 @@ export class ERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBa toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!toAddress) { diff --git a/packages/payment-detection/src/erc20/proxy-contract.ts b/packages/payment-detection/src/erc20/proxy-contract.ts index 3c7a334f5f..8b34772b98 100644 --- a/packages/payment-detection/src/erc20/proxy-contract.ts +++ b/packages/payment-detection/src/erc20/proxy-contract.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { erc20ProxyArtifact } from '@requestnetwork/smart-contracts'; import ProxyInfoRetriever from './proxy-info-retriever'; import { TheGraphInfoRetriever } from '../thegraph'; @@ -50,7 +55,7 @@ export class ERC20ProxyPaymentDetector extends ReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, 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 4b2ac4b097..dcdb511f3c 100644 --- a/packages/payment-detection/src/erc20/transferable-receivable.ts +++ b/packages/payment-detection/src/erc20/transferable-receivable.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, + CurrencyTypes, +} from '@requestnetwork/types'; import { TheGraphInfoRetriever } from '../thegraph'; import { erc20TransferableReceivableArtifact } from '@requestnetwork/smart-contracts'; @@ -51,7 +56,7 @@ export class ERC20TransferableReceivablePaymentDetector extends FeeReferenceBase toAddress: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, 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 b85ee84fb1..24e47edbc5 100644 --- a/packages/payment-detection/src/erc777/superfluid-detector.ts +++ b/packages/payment-detection/src/erc777/superfluid-detector.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { SuperFluidInfoRetriever } from './superfluid-retriever'; import { ReferenceBasedDetector } from '../reference-based-detector'; import PaymentReferenceCalculator from '../payment-reference-calculator'; @@ -91,7 +96,7 @@ export class SuperFluidPaymentDetector extends ReferenceBasedDetector< address: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, ): Promise> { if (!address) { return { diff --git a/packages/payment-detection/src/eth/fee-proxy-detector.ts b/packages/payment-detection/src/eth/fee-proxy-detector.ts index 5df331b9fa..34b8f434b0 100644 --- a/packages/payment-detection/src/eth/fee-proxy-detector.ts +++ b/packages/payment-detection/src/eth/fee-proxy-detector.ts @@ -1,5 +1,10 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { EthProxyInfoRetriever } from './proxy-info-retriever'; import { FeeReferenceBasedDetector } from '../fee-reference-based-detector'; @@ -57,7 +62,7 @@ export class EthFeeProxyPaymentDetector extends FeeReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, 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 fcdb36549e..68e33f8025 100644 --- a/packages/payment-detection/src/eth/input-data.ts +++ b/packages/payment-detection/src/eth/input-data.ts @@ -1,5 +1,10 @@ import * as SmartContracts from '@requestnetwork/smart-contracts'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { EthInputDataInfoRetriever } from './info-retriever'; import { EthProxyInfoRetriever } from './proxy-info-retriever'; import { ReferenceBasedDetector } from '../reference-based-detector'; @@ -26,7 +31,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< ExtensionTypes.PnReferenceBased.IReferenceBased, PaymentTypes.IETHPaymentEventParameters > { - private explorerApiKeys: Record; + private explorerApiKeys: Partial>; private readonly getSubgraphClient: PaymentNetworkOptions['getSubgraphClient']; /** @@ -63,7 +68,7 @@ export class EthInputDataPaymentDetector extends ReferenceBasedDetector< toAddress: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.EvmChainName, paymentNetwork: ExtensionTypes.IState, ): Promise< PaymentTypes.AllNetworkEvents< diff --git a/packages/payment-detection/src/near/near-conversion-detector.ts b/packages/payment-detection/src/near/near-conversion-detector.ts index 15c8085a1f..7c9dc7f22a 100644 --- a/packages/payment-detection/src/near/near-conversion-detector.ts +++ b/packages/payment-detection/src/near/near-conversion-detector.ts @@ -1,5 +1,10 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; +import { NearChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { NearConversionInfoRetriever } from './retrievers/near-conversion-info-retriever'; import { AnyToNativeDetector } from '../any-to-native-detector'; import { NetworkNotSupported } from '../balance-error'; @@ -23,10 +28,13 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto super(args); } - public static getContractName = (chainName: string, paymentNetworkVersion = '0.1.0'): string => { + public static getContractName = ( + chainName: CurrencyTypes.NearChainName, + paymentNetworkVersion = '0.1.0', + ): string => { const version = NearConversionNativeTokenPaymentDetector.getVersionOrThrow(paymentNetworkVersion); - const versionMap: Record> = { + const versionMap: Record> = { aurora: { '0.1.0': 'native.conversion.reqnetwork.near' }, 'aurora-testnet': { '0.1.0': 'native.conversion.reqnetwork.testnet', @@ -58,7 +66,7 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto address: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.NearChainName, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!address) { @@ -90,11 +98,12 @@ export class NearConversionNativeTokenPaymentDetector extends AnyToNativeDetecto }; } - protected getPaymentChain(request: RequestLogicTypes.IRequest): string { + protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.NearChainName { const network = this.getPaymentExtension(request).values.network; if (!network) { throw Error(`request.extensions[${this.paymentNetworkId}].values.network must be defined`); } + NearChains.assertChainSupported(network); return network; } diff --git a/packages/payment-detection/src/near/near-detector.ts b/packages/payment-detection/src/near/near-detector.ts index 861ab74010..3a97a57580 100644 --- a/packages/payment-detection/src/near/near-detector.ts +++ b/packages/payment-detection/src/near/near-detector.ts @@ -1,4 +1,9 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { NearInfoRetriever } from './retrievers/near-info-retriever'; import { NativeTokenPaymentDetector } from '../native-token-detector'; import { NetworkNotSupported } from '../balance-error'; @@ -23,9 +28,12 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { super(args); } - public static getContractName = (chainName: string, paymentNetworkVersion = '0.2.0'): string => { + public static getContractName = ( + chainName: CurrencyTypes.NearChainName, + 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' }, 'aurora-testnet': { '0.1.0': 'dev-1626339335241-5544297', @@ -58,7 +66,7 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector { address: string | undefined, paymentReference: string, _requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.NearChainName, paymentNetwork: ExtensionTypes.IState, ): Promise> { if (!address) { 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 ab306b0e60..a3927d64a2 100644 --- a/packages/payment-detection/src/near/retrievers/near-info-retriever.ts +++ b/packages/payment-detection/src/near/retrievers/near-info-retriever.ts @@ -1,5 +1,6 @@ import { PaymentTypes } from '@requestnetwork/types'; import { getTheGraphNearClient, TheGraphClient } from '../../thegraph'; +import { NearChains } from '@requestnetwork/currency'; // FIXME#1: when Near subgraphes can retrieve a txHash, replace the custom IPaymentNetworkEvent with PaymentTypes.ETHPaymentNetworkEvent interface NearSubGraphPaymentEvent extends PaymentTypes.IETHPaymentEventParameters { @@ -25,7 +26,9 @@ export class NearInfoRetriever { protected eventName: PaymentTypes.EVENTS_NAMES, network: string, ) { - if (network !== 'aurora' && network !== 'aurora-testnet' && network !== 'near-testnet') { + try { + NearChains.assertChainSupported(network); + } catch { throw new Error('Near input data info-retriever only works with Near mainnet and testnet'); } diff --git a/packages/payment-detection/src/payment-network-factory.ts b/packages/payment-detection/src/payment-network-factory.ts index b32795f0ad..d61ef44939 100644 --- a/packages/payment-detection/src/payment-network-factory.ts +++ b/packages/payment-detection/src/payment-network-factory.ts @@ -1,5 +1,6 @@ import { AdvancedLogicTypes, + CurrencyTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes, @@ -118,7 +119,7 @@ export class PaymentNetworkFactory { public createPaymentNetwork( paymentNetworkId: ExtensionTypes.PAYMENT_NETWORK_ID, currencyType: RequestLogicTypes.CURRENCY, - paymentChain?: string, + paymentChain?: CurrencyTypes.ChainName, paymentNetworkVersion?: string, ): PaymentTypes.IPaymentNetwork { const network = paymentChain ?? 'mainnet'; @@ -149,7 +150,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, + network as CurrencyTypes.EvmChainName, 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 934e2c34e0..0c0cca54c1 100644 --- a/packages/payment-detection/src/reference-based-detector.ts +++ b/packages/payment-detection/src/reference-based-detector.ts @@ -1,4 +1,10 @@ -import { ExtensionTypes, PaymentTypes, RequestLogicTypes, TypesUtils } from '@requestnetwork/types'; +import { + CurrencyTypes, + ExtensionTypes, + PaymentTypes, + RequestLogicTypes, + TypesUtils, +} from '@requestnetwork/types'; import { ICurrencyManager } from '@requestnetwork/currency'; import PaymentReferenceCalculator from './payment-reference-calculator'; @@ -141,7 +147,7 @@ export abstract class ReferenceBasedDetector< address: string | undefined, paymentReference: string, requestCurrency: RequestLogicTypes.ICurrency, - paymentChain: string, + paymentChain: CurrencyTypes.ChainName, paymentNetwork: TExtension extends ExtensionTypes.IExtension ? ExtensionTypes.IState : never, @@ -151,7 +157,7 @@ export abstract class ReferenceBasedDetector< * Get the network of the payment * @returns The network of payment */ - protected getPaymentChain(request: RequestLogicTypes.IRequest): string { + protected getPaymentChain(request: RequestLogicTypes.IRequest): CurrencyTypes.ChainName { 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/info-retriever.ts b/packages/payment-detection/src/thegraph/info-retriever.ts index 655d002889..95676cc07f 100644 --- a/packages/payment-detection/src/thegraph/info-retriever.ts +++ b/packages/payment-detection/src/thegraph/info-retriever.ts @@ -1,4 +1,4 @@ -import { PaymentTypes } from '@requestnetwork/types'; +import { CurrencyTypes, PaymentTypes } from '@requestnetwork/types'; import { ICurrencyManager } from '@requestnetwork/currency'; import { utils } from 'ethers'; import { pick, mapValues } from 'lodash'; @@ -14,12 +14,12 @@ type TransferEventsParams = { /** The address of the payment proxy */ contractAddress: string; /** The chain to check for payment */ - paymentChain: string; + paymentChain: CurrencyTypes.EvmChainName; /** 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 */ acceptedTokens?: string[]; - /** The the maximum span between the time the rate was fetched and the payment */ + /** The maximum span between the time the rate was fetched and the payment */ maxRateTimespan?: number; }; diff --git a/packages/payment-detection/src/types.ts b/packages/payment-detection/src/types.ts index 65fb1bcadc..73b7b99d93 100644 --- a/packages/payment-detection/src/types.ts +++ b/packages/payment-detection/src/types.ts @@ -1,4 +1,9 @@ -import { AdvancedLogicTypes, ExtensionTypes, PaymentTypes } from '@requestnetwork/types'; +import { + AdvancedLogicTypes, + CurrencyTypes, + ExtensionTypes, + PaymentTypes, +} from '@requestnetwork/types'; import { PaymentDetectorBase } from './payment-detector-base'; import { GetDeploymentInformation } from './utils'; import type { ICurrencyManager } from '@requestnetwork/currency'; @@ -54,11 +59,11 @@ 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: Record; + explorerApiKeys: Partial>; /** override the default Subgraph for payment detection (EVM, Near) */ - getSubgraphClient: (network: string) => TheGraphClient | undefined; + getSubgraphClient: (network: CurrencyTypes.ChainName) => TheGraphClient | undefined; /** override the default RPC provider (EVM) */ - getRpcProvider: (network: string) => providers.Provider; + getRpcProvider: (network: CurrencyTypes.ChainName) => providers.Provider; }; export type ReferenceBasedDetectorOptions = { @@ -67,5 +72,5 @@ export type ReferenceBasedDetectorOptions = { }; export type NativeDetectorOptions = ReferenceBasedDetectorOptions & { - network: string; + network: CurrencyTypes.ChainName; }; diff --git a/packages/payment-detection/src/utils.ts b/packages/payment-detection/src/utils.ts index ba2cdc3944..6a64326a33 100644 --- a/packages/payment-detection/src/utils.ts +++ b/packages/payment-detection/src/utils.ts @@ -1,5 +1,10 @@ import { CurrencyDefinition } from '@requestnetwork/currency'; -import { ExtensionTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + 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'; @@ -57,7 +62,7 @@ const getChainlinkPaddingSize = ({ export type DeploymentInformationWithVersion = DeploymentInformation & { contractVersion: string }; export type GetDeploymentInformation = ( - network: string, + network: CurrencyTypes.EvmChainName, paymentNetworkVersion: string, ) => TAllowUndefined extends false ? DeploymentInformationWithVersion 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 28578a80da..e686d1008b 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 @@ -1,6 +1,7 @@ import { ethers } from 'ethers'; import { AdvancedLogicTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, PaymentTypes, @@ -8,8 +9,7 @@ import { } from '@requestnetwork/types'; import { CurrencyManager } from '@requestnetwork/currency'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; -import { AnyToERC20PaymentDetector } from '../../src/any/any-to-erc20-proxy'; -import { getTheGraphClient } from '../../src/thegraph'; +import { AnyToERC20PaymentDetector, getTheGraphClient } from '../../src'; import { mocked } from 'ts-jest/utils'; import { mockAdvancedLogicBase } from '../utils'; @@ -55,7 +55,7 @@ describe('api/any/conversion-fee-proxy-contract', () => { jest.clearAllMocks(); }); - const testSuite = (network: string) => { + const testSuite = (network: CurrencyTypes.EvmChainName) => { it(`can createExtensionsDataForCreation on ${network}`, async () => { await anyToErc20Proxy.createExtensionsDataForCreation({ paymentAddress: 'ethereum address', diff --git a/packages/payment-detection/test/erc20/address-based.test.ts b/packages/payment-detection/test/erc20/address-based.test.ts index 5ec4070b6f..17e96378b9 100644 --- a/packages/payment-detection/test/erc20/address-based.test.ts +++ b/packages/payment-detection/test/erc20/address-based.test.ts @@ -118,7 +118,7 @@ describe('api/erc20/address-based', () => { await expect( erc20AddressedBased.getBalance({ currency: { network: 'wrong' }, - } as RequestLogicTypes.IRequest), + } as unknown as RequestLogicTypes.IRequest), ).resolves.not.toThrowError(); }); }); diff --git a/packages/payment-detection/test/erc20/thegraph-info-retriever.test.ts b/packages/payment-detection/test/erc20/thegraph-info-retriever.test.ts index 37f0dab049..8a7af478aa 100644 --- a/packages/payment-detection/test/erc20/thegraph-info-retriever.test.ts +++ b/packages/payment-detection/test/erc20/thegraph-info-retriever.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-expressions */ -import { TheGraphInfoRetriever, TheGraphClient } from '../../src/thegraph'; +import { TheGraphClient, TheGraphInfoRetriever } from '../../src/thegraph'; import PaymentReferenceCalculator from '../../src/payment-reference-calculator'; import { utils } from 'ethers'; import { PaymentTypes } from '@requestnetwork/types'; @@ -72,7 +72,7 @@ describe('api/erc20/thegraph-info-retriever', () => { block: 9606098, feeAddress: '0x5000EE9FB9c96A2A09D8efB695aC21D6C429fF11', feeAmount: '0', - }; + } as const; const paymentReference = PaymentReferenceCalculator.calculate( paymentData.requestId, paymentData.salt, @@ -111,7 +111,7 @@ describe('api/erc20/thegraph-info-retriever', () => { amount: '7000', block: 9610470, requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1', - }; + } as const; const shortReference = PaymentReferenceCalculator.calculate( paymentData.requestId, diff --git a/packages/payment-detection/test/erc20/transferable-receivable.test.ts b/packages/payment-detection/test/erc20/transferable-receivable.test.ts index dbb3bdd319..67d6667ce7 100644 --- a/packages/payment-detection/test/erc20/transferable-receivable.test.ts +++ b/packages/payment-detection/test/erc20/transferable-receivable.test.ts @@ -4,6 +4,7 @@ import PaymentReferenceCalculator from '../../src/payment-reference-calculator'; import { ERC20TransferableReceivablePaymentDetector } from '../../src/erc20'; import { AdvancedLogicTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, PaymentTypes, @@ -376,7 +377,7 @@ describe('api/erc20/transferable-receivable-contract', () => { txHash: '0x3e2d6cc2534b1d340ba2954f34e6cc819d6da64ff76863ea89c6d34b15d13c97', from: '0x186e7fe6c34ea0eca7f9c2fd29651fc0443e3f29', to: paymentAddress, - network: 'rinkeby', + network: 'rinkeby' as CurrencyTypes.EvmChainName, 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 5bc8a7b6da..33238f026e 100644 --- a/packages/payment-detection/test/erc777/superfluid-detector.test.ts +++ b/packages/payment-detection/test/erc777/superfluid-detector.test.ts @@ -1,5 +1,6 @@ import { AdvancedLogicTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -35,7 +36,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = { const baseRequestData = { creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' }, currency: { - network: 'private', + network: 'private' as CurrencyTypes.EvmChainName, 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 f572c92ce4..2bf898d7a8 100644 --- a/packages/payment-detection/test/near/near-native-conversion.test.ts +++ b/packages/payment-detection/test/near/near-native-conversion.test.ts @@ -190,9 +190,8 @@ describe('Near payments detection', () => { expect(await paymentDetector.getBalance(requestWithWrongNetwork)).toMatchObject({ balance: null, error: { - code: 2, - message: - "Unconfigured near-conversion-detector chain 'unknown-network' and version '0.1.0'", + code: 0, + message: 'Unsupported chain unknown-network', }, events: [], }); diff --git a/packages/payment-detection/test/payment-network-factory.test.ts b/packages/payment-detection/test/payment-network-factory.test.ts index fc48760a48..3a7063afe4 100644 --- a/packages/payment-detection/test/payment-network-factory.test.ts +++ b/packages/payment-detection/test/payment-network-factory.test.ts @@ -146,12 +146,12 @@ describe('api/payment-network/payment-network-factory', () => { }, }; const paymentNetworkFactory = new PaymentNetworkFactory(mockAdvancedLogic, currencyManager, { - explorerApiKeys: { homestead: 'abcd' }, + explorerApiKeys: { mainnet: 'abcd' }, }); const pn = paymentNetworkFactory.getPaymentNetworkFromRequest(request); expect(pn).toBeInstanceOf(EthInputDataPaymentDetector); expect((pn as any).explorerApiKeys).toMatchObject({ - homestead: 'abcd', + mainnet: 'abcd', }); }); }); diff --git a/packages/payment-processor/src/payment/batch-conversion-proxy.ts b/packages/payment-processor/src/payment/batch-conversion-proxy.ts index ecaff095fd..86f4649798 100644 --- a/packages/payment-processor/src/payment/batch-conversion-proxy.ts +++ b/packages/payment-processor/src/payment/batch-conversion-proxy.ts @@ -3,6 +3,7 @@ import { batchConversionPaymentsArtifact } from '@requestnetwork/smart-contracts import { BatchConversionPayments__factory } from '@requestnetwork/smart-contracts/types'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, PaymentTypes, RequestLogicTypes, @@ -273,7 +274,7 @@ function getUSDPathsForFeeLimit( * @returns */ function getBatchDeploymentInformation( - network: string, + network: CurrencyTypes.EvmChainName, version?: string, ): { address: string } | null { return { address: batchConversionPaymentsArtifact.getAddress(network, version) }; diff --git a/packages/payment-processor/src/payment/batch-proxy.ts b/packages/payment-processor/src/payment/batch-proxy.ts index b30bd3ee72..7b3d750a57 100644 --- a/packages/payment-processor/src/payment/batch-proxy.ts +++ b/packages/payment-processor/src/payment/batch-proxy.ts @@ -15,6 +15,7 @@ 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: @@ -211,7 +212,7 @@ export function getBatchArgs( /** * Get Batch contract Address * @param request The request to pay - * @param version The version version of the batch proxy, which can be different from request pn version + * @param version The version of the batch proxy, which can be different from request pn version */ export function getBatchProxyAddress(request: ClientTypes.IRequestData, version: string): string { const pn = getPaymentNetworkExtension(request); @@ -219,11 +220,13 @@ export function getBatchProxyAddress(request: ClientTypes.IRequestData, version: if (!pnId) { throw new Error('No payment network Id'); } - if (!request.currencyInfo.network) { + const { network } = request.currencyInfo; + if (!network) { throw new Error('No currency network'); } + EvmChains.assertChainSupported(network); - const proxyAddress = batchPaymentsArtifact.getAddress(request.currencyInfo.network, version); + const proxyAddress = batchPaymentsArtifact.getAddress(network, version); if (!proxyAddress) { throw new Error(`No deployment found for network ${pn}, version ${pn?.version}`); diff --git a/packages/payment-processor/src/payment/erc20-escrow-payment.ts b/packages/payment-processor/src/payment/erc20-escrow-payment.ts index 03230e97ee..9745b483ab 100644 --- a/packages/payment-processor/src/payment/erc20-escrow-payment.ts +++ b/packages/payment-processor/src/payment/erc20-escrow-payment.ts @@ -13,6 +13,17 @@ 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 + * @param request request to pay + */ +function getContractAddress(request: ClientTypes.IRequestData) { + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); + return erc20EscrowToPayArtifact.getAddress(network); +} /** * Prepare the approval transaction of the payment ERC20 to be spent by the escrow contract @@ -29,7 +40,7 @@ export function prepareErc20EscrowApproval( amount?: BigNumber, overrides?: ITransactionOverrides, ): IPreparedTransaction { - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); + const contractAddress = getContractAddress(request); const encodedTx = encodeApproveAnyErc20( paymentTokenAddress, contractAddress, @@ -101,8 +112,8 @@ export async function freezeRequest( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodeFreezeRequest(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -125,8 +136,8 @@ export async function payRequestFromEscrow( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodePayRequestFromEscrow(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -149,8 +160,8 @@ export async function initiateEmergencyClaim( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodeInitiateEmergencyClaim(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -173,8 +184,8 @@ export async function completeEmergencyClaim( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodeCompleteEmergencyClaim(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -197,8 +208,8 @@ export async function revertEmergencyClaim( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodeRevertEmergencyClaim(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -221,8 +232,8 @@ export async function refundFrozenFunds( signerOrProvider: providers.Web3Provider | Signer = getProvider(), overrides?: ITransactionOverrides, ): Promise { + const contractAddress = getContractAddress(request); const encodedTx = encodeRefundFrozenFunds(request); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); const signer = getSigner(signerOrProvider); const tx = await signer.sendTransaction({ @@ -281,8 +292,8 @@ export function preparePayEscrow( feeAmount?: BigNumberish, overrides?: ITransactionOverrides, ): IPreparedTransaction { + const contractAddress = getContractAddress(request); const encodedTx = encodePayEscrow(request, amount, feeAmount); - const contractAddress = erc20EscrowToPayArtifact.getAddress(request.currencyInfo.network!); return { data: encodedTx, to: contractAddress, diff --git a/packages/payment-processor/src/payment/erc20-fee-proxy.ts b/packages/payment-processor/src/payment/erc20-fee-proxy.ts index 72174e3d87..bbf203f98a 100644 --- a/packages/payment-processor/src/payment/erc20-fee-proxy.ts +++ b/packages/payment-processor/src/payment/erc20-fee-proxy.ts @@ -4,6 +4,7 @@ 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 { @@ -81,7 +82,9 @@ export function _getErc20FeeProxyPaymentUrl( validateRequest(request, ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT); const { paymentReference, paymentAddress, feeAddress, feeAmount, version } = getRequestPaymentValues(request); - const contractAddress = erc20FeeProxyArtifact.getAddress(request.currencyInfo.network!, version); + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); + const contractAddress = erc20FeeProxyArtifact.getAddress(network, version); const amountToPay = getAmountToPay(request, amount); const feeToPay = feeAmountOverride || BigNumber.from(feeAmount || 0); const parameters = `transferFromWithReferenceAndFee?address=${request.currencyInfo.value}&address=${paymentAddress}&uint256=${amountToPay}&bytes=${paymentReference}&uint256=${feeToPay}&address=${feeAddress}`; @@ -102,9 +105,11 @@ export function prepareErc20FeeProxyPaymentTransaction( ): IPreparedTransaction { validateErc20FeeProxyRequest(request, amount, feeAmountOverride); + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); const encodedTx = encodePayErc20FeeRequest(request, amount, feeAmountOverride); const pn = getPaymentNetworkExtension(request); - const proxyAddress = erc20FeeProxyArtifact.getAddress(request.currencyInfo.network!, pn?.version); + const proxyAddress = erc20FeeProxyArtifact.getAddress(network, pn?.version); return { data: encodedTx, diff --git a/packages/payment-processor/src/payment/near-conversion.ts b/packages/payment-processor/src/payment/near-conversion.ts index 2e24399e6a..6917fabd18 100644 --- a/packages/payment-processor/src/payment/near-conversion.ts +++ b/packages/payment-processor/src/payment/near-conversion.ts @@ -15,7 +15,7 @@ import { processNearPaymentWithConversion, } from './utils-near'; import { IConversionPaymentSettings } from '.'; -import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, NearChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; /** * Processes the transaction to pay a request in NEAR with on-chain conversion. @@ -48,6 +48,7 @@ export async function payNearConversionRequest( if (!network || !isNearNetwork(network)) { throw new Error('Should be a Near network'); } + NearChains.assertChainSupported(network); const amountToPay = getAmountToPay(request, amount).toString(); const version = getPaymentExtensionVersion(request); diff --git a/packages/payment-processor/src/payment/near-input-data.ts b/packages/payment-processor/src/payment/near-input-data.ts index 0fffa8f7c6..7783aaec6a 100644 --- a/packages/payment-processor/src/payment/near-input-data.ts +++ b/packages/payment-processor/src/payment/near-input-data.ts @@ -4,12 +4,13 @@ import { WalletConnection } from 'near-api-js'; import { ClientTypes, ExtensionTypes } from '@requestnetwork/types'; import { - getRequestPaymentValues, - validateRequest, getAmountToPay, getPaymentExtensionVersion, + getRequestPaymentValues, + validateRequest, } from './utils'; import { INearTransactionCallback, isNearNetwork, processNearPayment } from './utils-near'; +import { NearChains } from '@requestnetwork/currency'; /** * processes the transaction to pay a Near request. @@ -27,6 +28,7 @@ export async function payNearInputDataRequest( throw new Error('request.currencyInfo should be a Near network'); } + NearChains.assertChainSupported(request.currencyInfo.network); validateRequest(request, ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN); const { paymentReference, paymentAddress } = getRequestPaymentValues(request); 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 08e9b4f502..bf16e5dfdc 100644 --- a/packages/payment-processor/src/payment/swap-any-to-erc20.ts +++ b/packages/payment-processor/src/payment/swap-any-to-erc20.ts @@ -1,4 +1,4 @@ -import { constants, ContractTransaction, Signer, BigNumber, providers } from 'ethers'; +import { BigNumber, constants, ContractTransaction, providers, Signer } from 'ethers'; import { AnyToERC20PaymentDetector } from '@requestnetwork/payment-detection'; import { erc20SwapConversionArtifact } from '@requestnetwork/smart-contracts'; @@ -13,7 +13,7 @@ import { getSigner, validateConversionFeeProxyRequest, } from './utils'; -import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { IRequestPaymentOptions } from './settings'; import { IPreparedTransaction } from './prepared-transaction'; @@ -91,6 +91,7 @@ export function encodeSwapToPayAnyToErc20Request( if (!network) { throw new Error(`Currency in conversion settings must have a network`); } + EvmChains.assertChainSupported(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 dcf7d8ba21..19b4f41c5c 100644 --- a/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts +++ b/packages/payment-processor/src/payment/swap-erc20-fee-proxy.ts @@ -15,6 +15,7 @@ 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: @@ -83,13 +84,15 @@ export function prepareSwapToPayErc20FeeRequest( swapSettings: ISwapSettings, options?: ISwapTransactionOptions, ): IPreparedTransaction { + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); const encodedTx = encodeSwapToPayErc20FeeRequest( request, signerOrProvider, swapSettings, options, ); - const proxyAddress = erc20SwapToPayArtifact.getAddress(request.currencyInfo.network!); + const proxyAddress = erc20SwapToPayArtifact.getAddress(network); return { data: encodedTx, to: proxyAddress, @@ -111,6 +114,9 @@ export function encodeSwapToPayErc20FeeRequest( swapSettings: ISwapSettings, options?: IRequestPaymentOptions, ): string { + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); + validateErc20FeeProxyRequest(request, options?.amount, options?.feeAmount); const signer = getSigner(signerOrProvider); @@ -138,7 +144,7 @@ export function encodeSwapToPayErc20FeeRequest( Erc20PaymentNetwork.ERC20FeeProxyPaymentDetector.getDeploymentInformation, ); - const swapToPayAddress = erc20FeeProxyArtifact.getAddress(request.currencyInfo.network); + const swapToPayAddress = erc20FeeProxyArtifact.getAddress(network); const swapToPayContract = ERC20SwapToPay__factory.connect(swapToPayAddress, signer); return swapToPayContract.interface.encodeFunctionData('swapTransferWithReference', [ diff --git a/packages/payment-processor/src/payment/swap-erc20.ts b/packages/payment-processor/src/payment/swap-erc20.ts index 54ca6ddbc8..655078de51 100644 --- a/packages/payment-processor/src/payment/swap-erc20.ts +++ b/packages/payment-processor/src/payment/swap-erc20.ts @@ -1,4 +1,4 @@ -import { ContractTransaction, providers, Signer, BigNumberish, BigNumber } from 'ethers'; +import { BigNumber, BigNumberish, ContractTransaction, providers, Signer } from 'ethers'; import { erc20SwapToPayArtifact } from '@requestnetwork/smart-contracts'; import { ClientTypes } from '@requestnetwork/types'; @@ -7,6 +7,7 @@ import { ITransactionOverrides } from './transaction-overrides'; import { 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, @@ -54,12 +55,14 @@ export async function hasApprovalErc20ForSwapToPay( signerOrProvider: providers.Provider | Signer = getProvider(), minAmount: BigNumberish, ): Promise { - if (!request.currencyInfo.network) { + const { network } = request.currencyInfo; + if (!network) { throw new Error('Request currency network is missing'); } + EvmChains.assertChainSupported(network); return checkErc20Allowance( ownerAddress, - erc20SwapToPayArtifact.getAddress(request.currencyInfo.network), + erc20SwapToPayArtifact.getAddress(network), signerOrProvider, paymentTokenAddress, minAmount, @@ -104,9 +107,11 @@ export function prepareApprovalErc20ForSwapToPay( overrides?: ITransactionOverrides, amount?: BigNumber, ): IPreparedTransaction { + const { network } = request.currencyInfo; + EvmChains.assertChainSupported(network!); const encodedTx = encodeApproveAnyErc20( paymentTokenAddress, - erc20SwapToPayArtifact.getAddress(request.currencyInfo.network!), + erc20SwapToPayArtifact.getAddress(network), signerOrProvider, amount, ); diff --git a/packages/payment-processor/src/payment/utils-near.ts b/packages/payment-processor/src/payment/utils-near.ts index 3d12b755b4..1c8bd4b9d2 100644 --- a/packages/payment-processor/src/payment/utils-near.ts +++ b/packages/payment-processor/src/payment/utils-near.ts @@ -1,15 +1,16 @@ import { BigNumber, BigNumberish, ethers } from 'ethers'; -import { Contract } from 'near-api-js'; -import { Near, WalletConnection } from 'near-api-js'; +import { Contract, Near, WalletConnection } from 'near-api-js'; import { - NearNativeTokenPaymentDetector, NearConversionNativeTokenPaymentDetector, + NearNativeTokenPaymentDetector, } from '@requestnetwork/payment-detection'; +import { NearChains } from '@requestnetwork/currency'; +import { CurrencyTypes } from '@requestnetwork/types'; /** * Callback arguments for the Near web wallet. * @member callbackUrl called upon transaction approval - * @member callbackMeta (according to Near docs: `meta` will be attached to the `callbackUrl` as a url search param) + * @member meta (according to Near docs: `meta` will be attached to the `callbackUrl` as a url search param) */ export interface INearTransactionCallback { callbackUrl?: string; @@ -26,10 +27,12 @@ export const isValidNearAddress = async (nearNetwork: Near, address: string): Pr }; export const isNearNetwork = (network?: string): boolean => { - return ( - !!network && - (network === 'near-testnet' || network === 'aurora-testnet' || network === 'aurora') - ); + try { + NearChains.assertChainSupported(network); + return true; + } catch { + return false; + } }; export const isNearAccountSolvent = ( @@ -52,7 +55,7 @@ const GAS_LIMIT_CONVERSION_TO_NATIVE = GAS_LIMIT.mul(2).toString(); export const processNearPayment = async ( walletConnection: WalletConnection, - network: string, + network: CurrencyTypes.NearChainName, amount: BigNumberish, to: string, paymentReference: string, @@ -104,7 +107,7 @@ export const processNearPayment = async ( */ export const processNearPaymentWithConversion = async ( walletConnection: WalletConnection, - network: string, + network: CurrencyTypes.NearChainName, 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 9813634270..c3e8a95e23 100644 --- a/packages/payment-processor/src/payment/utils.ts +++ b/packages/payment-processor/src/payment/utils.ts @@ -1,8 +1,13 @@ import { ethers, Signer, providers, BigNumber, BigNumberish, ContractTransaction } from 'ethers'; import { getDefaultProvider, getPaymentReference } from '@requestnetwork/payment-detection'; -import { ClientTypes, ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; -import { getCurrencyHash } from '@requestnetwork/currency'; +import { + ClientTypes, + CurrencyTypes, + ExtensionTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; +import { EvmChains, getCurrencyHash } from '@requestnetwork/currency'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { getPaymentNetworkExtension } from '@requestnetwork/payment-detection'; import { getReceivableTokenIdForRequest } from './erc20-transferable-receivable'; @@ -75,7 +80,7 @@ export function getRequestPaymentValues(request: ClientTypes.IRequestData): { expectedStartDate?: string; tokensAccepted?: string[]; maxRateTimespan?: string; - network?: string; + network?: CurrencyTypes.ChainName; version: string; } { const extension = getPaymentNetworkExtension(request); @@ -154,10 +159,14 @@ export function getPnAndNetwork(request: ClientTypes.IRequestData): { */ export const getProxyAddress = ( request: ClientTypes.IRequestData, - getDeploymentInformation: (network: string, version: string) => { address: string } | null, + getDeploymentInformation: ( + network: CurrencyTypes.EvmChainName, + 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( diff --git a/packages/payment-processor/test/payment/any-to-erc20-batch-proxy.test.ts b/packages/payment-processor/test/payment/any-to-erc20-batch-proxy.test.ts index 14e5216031..2215c08d29 100644 --- a/packages/payment-processor/test/payment/any-to-erc20-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/any-to-erc20-batch-proxy.test.ts @@ -1,4 +1,4 @@ -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, @@ -6,19 +6,21 @@ import { IdentityTypes, RequestLogicTypes, } from '@requestnetwork/types'; -import { getErc20Balance } from '../../src/payment/erc20'; -import { deepCopy } from '@requestnetwork/utils'; -import { revokeErc20Approval } from '@requestnetwork/payment-processor/src/payment/utils'; -import { EnrichedRequest, IConversionPaymentSettings } from '../../src/index'; -import { batchConversionPaymentsArtifact } from '@requestnetwork/smart-contracts'; -import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { approveErc20BatchConversionIfNeeded, + EnrichedRequest, getBatchConversionProxyAddress, + getErc20Balance, + IConversionPaymentSettings, payBatchConversionProxyRequest, prepareBatchConversionPaymentTransaction, -} from '../../src/payment/batch-conversion-proxy'; +} from '../../src'; +import { deepCopy } from '@requestnetwork/utils'; +import { revokeErc20Approval } from '@requestnetwork/payment-processor/src/payment/utils'; +import { batchConversionPaymentsArtifact } from '@requestnetwork/smart-contracts'; +import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; import { IRequestPaymentOptions } from 'payment-processor/src/payment/settings'; +import { CurrencyTypes } from '@requestnetwork/types/src'; /* eslint-disable no-magic-numbers */ /* eslint-disable @typescript-eslint/no-unused-expressions */ @@ -579,7 +581,7 @@ describe('erc20-batch-conversion-proxy', () => { }); it("should throw an error if one request's currencyInfo has no network", async () => { - FAURequest.currencyInfo.network = ''; + FAURequest.currencyInfo.network = '' as CurrencyTypes.ChainName; await expect( payBatchConversionProxyRequest(enrichedRequests, wallet, options), ).rejects.toThrowError( diff --git a/packages/payment-processor/test/payment/any-to-erc20-proxy.test.ts b/packages/payment-processor/test/payment/any-to-erc20-proxy.test.ts index 48822ca8d1..fc96646aae 100644 --- a/packages/payment-processor/test/payment/any-to-erc20-proxy.test.ts +++ b/packages/payment-processor/test/payment/any-to-erc20-proxy.test.ts @@ -1,4 +1,4 @@ -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, ExtensionTypes, @@ -6,11 +6,13 @@ import { RequestLogicTypes, } from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; -import { approveErc20ForProxyConversionIfNeeded } from '../../src/payment/conversion-erc20'; -import { payAnyToErc20ProxyRequest } from '../../src/payment/any-to-erc20-proxy'; +import { + approveErc20ForProxyConversionIfNeeded, + IConversionPaymentSettings, + payAnyToErc20ProxyRequest, +} from '../../src'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { currencyManager } from './shared'; -import { IConversionPaymentSettings } from '../../src/index'; import { UnsupportedCurrencyError } from '@requestnetwork/currency'; import { AnyToERC20PaymentDetector } from '@requestnetwork/payment-detection'; import { getProxyAddress, MAX_ALLOWANCE, revokeErc20Approval } from '../../src/payment/utils'; diff --git a/packages/payment-processor/test/payment/any-to-eth-proxy.test.ts b/packages/payment-processor/test/payment/any-to-eth-proxy.test.ts index 6d37dcd44d..8df0e87944 100644 --- a/packages/payment-processor/test/payment/any-to-eth-proxy.test.ts +++ b/packages/payment-processor/test/payment/any-to-eth-proxy.test.ts @@ -1,4 +1,4 @@ -import { Wallet, providers } from 'ethers'; +import { providers, Wallet } from 'ethers'; import { ClientTypes, ExtensionTypes, @@ -6,9 +6,8 @@ import { RequestLogicTypes, } from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; -import { payAnyToEthProxyRequest } from '../../src/payment/any-to-eth-proxy'; +import { IConversionPaymentSettings, payAnyToEthProxyRequest } from '../../src'; import { currencyManager } from './shared'; -import { IConversionPaymentSettings } from '../../src/index'; const paymentSettings: IConversionPaymentSettings = { maxToSpend: '2500000000000000', diff --git a/packages/payment-processor/test/payment/any-to-near.test.ts b/packages/payment-processor/test/payment/any-to-near.test.ts index 323bce6a07..0c673127fc 100644 --- a/packages/payment-processor/test/payment/any-to-near.test.ts +++ b/packages/payment-processor/test/payment/any-to-near.test.ts @@ -1,9 +1,8 @@ import { ExtensionTypes, RequestLogicTypes } from '@requestnetwork/types'; import { PaymentReferenceCalculator } from '@requestnetwork/payment-detection'; -import { IConversionPaymentSettings, _getPaymentUrl } from '../../src/payment'; +import { IConversionPaymentSettings, payNearConversionRequest } from '../../src'; import * as nearUtils from '../../src/payment/utils-near'; -import { payNearConversionRequest } from '../../src/payment/near-conversion'; import { deepCopy } from '@requestnetwork/utils'; /* eslint-disable @typescript-eslint/no-unused-expressions */ diff --git a/packages/payment-processor/test/payment/btc-address-based.test.ts b/packages/payment-processor/test/payment/btc-address-based.test.ts index b5edb1eb78..85460778cf 100644 --- a/packages/payment-processor/test/payment/btc-address-based.test.ts +++ b/packages/payment-processor/test/payment/btc-address-based.test.ts @@ -7,7 +7,7 @@ import { RequestLogicTypes, } from '@requestnetwork/types'; -import { getBtcPaymentUrl } from '../../src/payment/btc-address-based'; +import { getBtcPaymentUrl } from '../../src'; /* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/await-thenable */ diff --git a/packages/payment-processor/test/payment/encoder-approval.test.ts b/packages/payment-processor/test/payment/encoder-approval.test.ts index 86de74176a..4e351bd4f8 100644 --- a/packages/payment-processor/test/payment/encoder-approval.test.ts +++ b/packages/payment-processor/test/payment/encoder-approval.test.ts @@ -1,19 +1,20 @@ -import { Wallet, providers, BigNumber, utils } from 'ethers'; +import { BigNumber, providers, utils, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, } from '@requestnetwork/types'; -import { encodeRequestErc20ApprovalIfNeeded } from '../../src'; +import { encodeRequestErc20ApprovalIfNeeded, IPreparedTransaction } from '../../src'; import { getProxyAddress, MAX_ALLOWANCE, revokeErc20Approval } from '../../src/payment/utils'; import { AnyToERC20PaymentDetector, Erc20PaymentNetwork } from '@requestnetwork/payment-detection'; import { currencyManager } from './shared'; -import { IPreparedTransaction } from '../../src/payment/prepared-transaction'; import { - erc20SwapToPayArtifact, erc20SwapConversionArtifact, + erc20SwapToPayArtifact, } from '@requestnetwork/smart-contracts'; +import { IConversionSettings } from '../../src/payment/settings'; /* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/await-thenable */ @@ -23,7 +24,7 @@ const feeAddress = '0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef'; // Cf. ERC20Alpha in TestERC20.sol const alphaContractAddress = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35'; -const alphaConversionSettings = { +const alphaConversionSettings: IConversionSettings = { currency: { type: RequestLogicTypes.CURRENCY.ERC20, value: alphaContractAddress, @@ -254,12 +255,12 @@ beforeAll(async () => { await revokeErc20Approval(proxyERC20Conv, alphaContractAddress, wallet); proxyERC20Swap = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network!, + validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, ); await revokeErc20Approval(proxyERC20Swap, alphaContractAddress, wallet); proxyERC20SwapConv = erc20SwapConversionArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network!, + validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, ); 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 9051c86771..d2a85f9f32 100644 --- a/packages/payment-processor/test/payment/encoder-payment.test.ts +++ b/packages/payment-processor/test/payment/encoder-payment.test.ts @@ -1,6 +1,7 @@ -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -20,9 +21,10 @@ import { } from '@requestnetwork/payment-detection'; import { currencyManager } from './shared'; import { - erc20SwapToPayArtifact, erc20SwapConversionArtifact, + erc20SwapToPayArtifact, } from '@requestnetwork/smart-contracts'; +import { IConversionSettings } from '../../src/payment/settings'; /* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/await-thenable */ @@ -33,7 +35,7 @@ const DAIX_ADDRESS = '0x7D782D2cc2755CA324De57D42e28Cc63278dFE12'; // Cf. ERC20Alpha in TestERC20.sol const alphaContractAddress = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35'; -const alphaConversionSettings = { +const alphaConversionSettings: IConversionSettings = { currency: { type: RequestLogicTypes.CURRENCY.ERC20, value: alphaContractAddress, @@ -314,7 +316,7 @@ describe('Payment encoder handles ERC20 Swap Proxy', () => { }); const proxyAddress = erc20SwapToPayArtifact.getAddress( - validRequestERC20FeeProxy.currencyInfo.network!, + validRequestERC20FeeProxy.currencyInfo.network! as CurrencyTypes.EvmChainName, ); expect(paymentTransaction).toEqual({ @@ -333,7 +335,7 @@ describe('Payment encoder handles ERC20 Swap & Conversion Proxy', () => { }); const proxyAddress = erc20SwapConversionArtifact.getAddress( - alphaConversionSettings.currency.network, + alphaConversionSettings.currency.network as CurrencyTypes.EvmChainName, ); expect(paymentTransaction).toEqual({ diff --git a/packages/payment-processor/test/payment/encoder.test.ts b/packages/payment-processor/test/payment/encoder.test.ts index 44e6e35eec..b4772a0d92 100644 --- a/packages/payment-processor/test/payment/encoder.test.ts +++ b/packages/payment-processor/test/payment/encoder.test.ts @@ -6,7 +6,11 @@ import { RequestLogicTypes, } from '@requestnetwork/types'; import { encodeRequestApprovalAndPayment } from '../../src'; -import { IRequestPaymentOptions } from '../../src/payment/settings'; +import { + IApprovalSettings, + IConversionSettings, + IRequestPaymentOptions, +} from '../../src/payment/settings'; import { currencyManager } from './shared'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; import { MAX_ALLOWANCE } from '../../src/payment/utils'; @@ -19,7 +23,7 @@ const feeAddress = '0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef'; // Cf. ERC20Alpha in TestERC20.sol const alphaContractAddress = '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35'; -const alphaConversionSettings = { +const alphaConversionSettings: IConversionSettings = { currency: { type: RequestLogicTypes.CURRENCY.ERC20, value: alphaContractAddress, @@ -235,9 +239,9 @@ const getOption = (withApproval: boolean, type: Option): IRequestPaymentOptions return { conversion: alphaConversionSettings, approval: withApproval - ? { + ? ({ amount: alphaConversionSettings.maxToSpend, - } + } as IApprovalSettings) : undefined, }; } 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 800685317c..867fa2d718 100644 --- a/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-batch-proxy.test.ts @@ -1,4 +1,4 @@ -import { Wallet, BigNumber, providers } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, @@ -9,14 +9,15 @@ import { import { deepCopy } from '@requestnetwork/utils'; import { batchPaymentsArtifact } from '@requestnetwork/smart-contracts'; -import { getErc20Balance } from '../../src/payment/erc20'; -import { getRequestPaymentValues } from '../../src/payment/utils'; import { - payBatchProxyRequest, approveErc20BatchIfNeeded, - prepareBatchPaymentTransaction, getBatchProxyAddress, -} from '../../src/payment/batch-proxy'; + getErc20Balance, + payBatchProxyRequest, + prepareBatchPaymentTransaction, +} from '../../src'; +import { getRequestPaymentValues } from '../../src/payment/utils'; +import { CurrencyTypes } from '@requestnetwork/types/src'; /* eslint-disable no-magic-numbers */ /* eslint-disable @typescript-eslint/no-unused-expressions */ @@ -138,7 +139,7 @@ const testSuite = ( }); it("should throw an error if one request's currencyInfo has no network", async () => { - request2.currencyInfo.network = ''; + request2.currencyInfo.network = '' as CurrencyTypes.ChainName; 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 1391f50088..489f4c9f1d 100644 --- a/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts +++ b/packages/payment-processor/test/payment/erc20-escrow-payment.test.ts @@ -1,6 +1,7 @@ -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -10,7 +11,7 @@ import { Escrow } from '../../src/'; import { getRequestPaymentValues, getSigner } from '../../src/payment/utils'; import { erc20EscrowToPayArtifact } from '@requestnetwork/smart-contracts'; -import { getErc20Balance } from '../../src/payment/erc20'; +import { getErc20Balance } from '../../src'; /* eslint-disable no-magic-numbers */ /* eslint-disable @typescript-eslint/no-unused-expressions */ @@ -66,7 +67,9 @@ const validRequest: ClientTypes.IRequestData = { version: '1.0', }; -const escrowAddress = erc20EscrowToPayArtifact.getAddress(validRequest.currencyInfo.network!); +const escrowAddress = erc20EscrowToPayArtifact.getAddress( + validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, +); const payerAddress = wallet.address; describe('erc20-escrow-payment tests:', () => { @@ -102,10 +105,8 @@ describe('erc20-escrow-payment tests:', () => { }); it('Should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; - await expect(Escrow.payEscrow(request, wallet)).rejects.toThrowError( - 'request cannot be processed, or is not an pn-erc20-fee-proxy-contract request', - ); + request.currencyInfo.network = '' as CurrencyTypes.ChainName; + await expect(Escrow.payEscrow(request, wallet)).rejects.toThrowError('Unsupported chain '); }); it('Should throw an error if request has no extension', async () => { const request = deepCopy(validRequest); 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 592b5a527f..eaf7f1af5c 100644 --- a/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-fee-proxy.test.ts @@ -1,7 +1,8 @@ -import { Wallet, BigNumber, providers } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -9,12 +10,13 @@ import { import { deepCopy } from '@requestnetwork/utils'; import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; -import { approveErc20, getErc20Balance } from '../../src/payment/erc20'; import { _getErc20FeeProxyPaymentUrl, + approveErc20, + getErc20Balance, payErc20FeeProxyRequest, prepareErc20FeeProxyPaymentTransaction, -} from '../../src/payment/erc20-fee-proxy'; +} from '../../src'; import { getRequestPaymentValues } from '../../src/payment/utils'; /* eslint-disable no-magic-numbers */ @@ -106,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 = ''; + request.currencyInfo.network = '' as CurrencyTypes.ChainName; 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 5139c18ef9..dee210f1c8 100644 --- a/packages/payment-processor/test/payment/erc20-proxy.test.ts +++ b/packages/payment-processor/test/payment/erc20-proxy.test.ts @@ -2,6 +2,7 @@ import { Wallet, BigNumber, providers } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -91,7 +92,7 @@ describe('payErc20ProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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/erc20-transferable-receivable.test.ts b/packages/payment-processor/test/payment/erc20-transferable-receivable.test.ts index 094b350fa4..10563ec6c4 100644 --- a/packages/payment-processor/test/payment/erc20-transferable-receivable.test.ts +++ b/packages/payment-processor/test/payment/erc20-transferable-receivable.test.ts @@ -141,6 +141,7 @@ describe('erc20-transferable-receivable', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); + // @ts-expect-error Type '""' is not assignable to type 'ChainName | undefined' request.currencyInfo.network = ''; await expect(payErc20TransferableReceivableRequest(request, wallet)).rejects.toThrowError( 'Payment currency must have a network', diff --git a/packages/payment-processor/test/payment/erc20.test.ts b/packages/payment-processor/test/payment/erc20.test.ts index d1966ea7e7..2d59e91df8 100644 --- a/packages/payment-processor/test/payment/erc20.test.ts +++ b/packages/payment-processor/test/payment/erc20.test.ts @@ -4,15 +4,15 @@ import { IdentityTypes, RequestLogicTypes, } from '@requestnetwork/types'; -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; import { _getErc20PaymentUrl, approveErc20, + checkErc20Allowance, getErc20Balance, hasErc20Approval, - checkErc20Allowance, -} from '../../src/payment/erc20'; +} from '../../src'; import { getProxyAddress, revokeErc20Approval } from '../../src/payment/utils'; import { Erc20PaymentNetwork } from '@requestnetwork/payment-detection'; diff --git a/packages/payment-processor/test/payment/erc777-stream.test.ts b/packages/payment-processor/test/payment/erc777-stream.test.ts index 762e6ade59..3e1fa26455 100644 --- a/packages/payment-processor/test/payment/erc777-stream.test.ts +++ b/packages/payment-processor/test/payment/erc777-stream.test.ts @@ -3,6 +3,7 @@ import { Framework } from '@superfluid-finance/sdk-core'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -99,18 +100,21 @@ describe('erc777-stream', () => { { network: 'optimism' }, { network: 'avalanche' }, { network: 'arbitrum-one' }, - ])('Should initialize superfluid framework on $network', async ({ network }) => { - const provider = getDefaultProvider(network); - const networkValidRequest = { - ...validRequest, - currencyInfo: { - ...validRequest.currencyInfo, - network, - }, - }; - const sf = await getSuperFluidFramework(networkValidRequest, provider); - expect(sf).toBeDefined(); - }); + ] as Array<{ network: CurrencyTypes.EvmChainName }>)( + 'Should initialize superfluid framework on $network', + async ({ network }) => { + const provider = getDefaultProvider(network); + const networkValidRequest = { + ...validRequest, + currencyInfo: { + ...validRequest.currencyInfo, + network, + }, + }; + const sf = await getSuperFluidFramework(networkValidRequest, provider); + expect(sf).toBeDefined(); + }, + ); }); describe('encodePayErc20FeeRequest (used to pay and swap to pay)', () => { @@ -133,7 +137,7 @@ describe('erc777-stream', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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 f9d461ca3b..20fd0df5f4 100644 --- a/packages/payment-processor/test/payment/eth-batch-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-batch-proxy.test.ts @@ -2,6 +2,7 @@ import { Wallet, providers, BigNumber } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -105,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 = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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 1cc9db6a32..812bfca72a 100644 --- a/packages/payment-processor/test/payment/eth-fee-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-fee-proxy.test.ts @@ -1,6 +1,7 @@ -import { Wallet, providers } from 'ethers'; +import { providers, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -85,7 +86,7 @@ describe('payEthFeeProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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 793dd8e4f1..ea7b18c369 100644 --- a/packages/payment-processor/test/payment/eth-input-data.test.ts +++ b/packages/payment-processor/test/payment/eth-input-data.test.ts @@ -2,6 +2,7 @@ import { Wallet, providers, BigNumber } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -80,7 +81,7 @@ describe('payEthInputDataRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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 a52d6592d7..e620ef284f 100644 --- a/packages/payment-processor/test/payment/eth-proxy.test.ts +++ b/packages/payment-processor/test/payment/eth-proxy.test.ts @@ -2,6 +2,7 @@ import { Wallet, BigNumber, providers } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, @@ -86,7 +87,7 @@ describe('payEthProxyRequest', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; 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/index.test.ts b/packages/payment-processor/test/payment/index.test.ts index 30111fba15..cd3578d96c 100644 --- a/packages/payment-processor/test/payment/index.test.ts +++ b/packages/payment-processor/test/payment/index.test.ts @@ -25,9 +25,9 @@ const wallet = Wallet.fromMnemonic(mnemonic).connect(provider); const fakeErc20: RequestLogicTypes.ICurrency = { type: RequestLogicTypes.CURRENCY.ERC20, value: 'any', - network: 'live', + network: 'mainnet', }; -const nearCurrency = { +const nearCurrency: RequestLogicTypes.ICurrency = { type: RequestLogicTypes.CURRENCY.ETH, network: 'aurora', value: 'near', diff --git a/packages/payment-processor/test/payment/shared.ts b/packages/payment-processor/test/payment/shared.ts index 734381a886..b2a61dce98 100644 --- a/packages/payment-processor/test/payment/shared.ts +++ b/packages/payment-processor/test/payment/shared.ts @@ -3,24 +3,25 @@ import { RequestLogicTypes } from '@requestnetwork/types'; export const currencyManager = new CurrencyManager([ ...CurrencyManager.getDefaultList(), - ...[ - { - network: 'private', - symbol: 'ETH', - decimals: 18, - type: RequestLogicTypes.CURRENCY.ETH, - } as CurrencyDefinition, - ], + { + network: 'private', + symbol: 'ETH', + decimals: 18, + type: RequestLogicTypes.CURRENCY.ETH, + } as CurrencyDefinition, ...[ '0x9FBDa871d559710256a2502A2517b794B482Db40', '0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35', '0x17b4158805772ced11225e77339f90beb5aae968', '0x775eb53d00dd0acd3ec1696472105d579b9b386b', - ].map((address, i) => ({ - address, - network: 'private', - decimals: 18, - symbol: 'ERC20_' + i, - type: RequestLogicTypes.CURRENCY.ERC20, - })), + ].map( + (address, i) => + ({ + address, + network: 'private', + decimals: 18, + symbol: 'ERC20_' + i, + type: RequestLogicTypes.CURRENCY.ERC20, + } as CurrencyDefinition), + ), ]); diff --git a/packages/payment-processor/test/payment/swap-any-to-erc20.test.ts b/packages/payment-processor/test/payment/swap-any-to-erc20.test.ts index a95aec8c21..bf54913f1d 100644 --- a/packages/payment-processor/test/payment/swap-any-to-erc20.test.ts +++ b/packages/payment-processor/test/payment/swap-any-to-erc20.test.ts @@ -139,7 +139,7 @@ describe('swap-any-to-erc20', () => { }); it('should throw an error if the conversion currency is not an acceptedTokens', async () => { - const wrongCurrency = { + const wrongCurrency: RequestLogicTypes.ICurrency = { type: 'ERC20' as any, value: '0x17b4158805772ced11225e77339f90beb5aae968', network: 'private', 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 f87972ce5b..5bd0b1f3a5 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 @@ -1,17 +1,21 @@ -import { Wallet, providers, BigNumber } from 'ethers'; +import { BigNumber, providers, Wallet } from 'ethers'; import { ClientTypes, + CurrencyTypes, ExtensionTypes, IdentityTypes, RequestLogicTypes, } from '@requestnetwork/types'; import { deepCopy } from '@requestnetwork/utils'; -import { getErc20Balance } from '../../src/payment/erc20'; -import { approveErc20ForSwapToPayIfNeeded } from '../../src/payment/swap-erc20'; +import { + approveErc20ForSwapToPayIfNeeded, + getErc20Balance, + ISwapSettings, + swapErc20FeeProxyRequest, +} from '../../src'; import { ERC20__factory } from '@requestnetwork/smart-contracts/types'; -import { ISwapSettings, swapErc20FeeProxyRequest } from '../../src/payment/swap-erc20-fee-proxy'; import { erc20SwapToPayArtifact } from '@requestnetwork/smart-contracts'; import { revokeErc20Approval } from '../../src/payment/utils'; @@ -81,7 +85,9 @@ describe('swap-erc20-fee-proxy', () => { beforeAll(async () => { // revoke erc20SwapToPay approval await revokeErc20Approval( - erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network!), + erc20SwapToPayArtifact.getAddress( + validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, + ), alphaErc20Address, wallet.provider, ); @@ -90,7 +96,9 @@ describe('swap-erc20-fee-proxy', () => { beforeAll(async () => { // revoke erc20SwapToPay approval await revokeErc20Approval( - erc20SwapToPayArtifact.getAddress(validRequest.currencyInfo.network!), + erc20SwapToPayArtifact.getAddress( + validRequest.currencyInfo.network! as CurrencyTypes.EvmChainName, + ), alphaErc20Address, wallet.provider, ); @@ -118,12 +126,10 @@ describe('swap-erc20-fee-proxy', () => { it('should throw an error if currencyInfo has no network', async () => { const request = deepCopy(validRequest); - request.currencyInfo.network = ''; + request.currencyInfo.network = '' as CurrencyTypes.EvmChainName; await expect( swapErc20FeeProxyRequest(request, wallet, validSwapSettings), - ).rejects.toThrowError( - 'request cannot be processed, or is not an pn-erc20-fee-proxy-contract request', - ); + ).rejects.toThrowError('Unsupported chain '); }); it('should throw an error if request has no extension', async () => { diff --git a/packages/request-client.js/src/api/request.ts b/packages/request-client.js/src/api/request.ts index 9d236811b5..66fce5e211 100644 --- a/packages/request-client.js/src/api/request.ts +++ b/packages/request-client.js/src/api/request.ts @@ -3,7 +3,12 @@ import { DeclarativePaymentDetector, EscrowERC20InfoRetriever, } from '@requestnetwork/payment-detection'; -import { IdentityTypes, PaymentTypes, RequestLogicTypes } from '@requestnetwork/types'; +import { + CurrencyTypes, + IdentityTypes, + PaymentTypes, + RequestLogicTypes, +} from '@requestnetwork/types'; import { ICurrencyManager } from '@requestnetwork/currency'; import * as Types from '../types'; import ContentDataExtension from './content-data-extension'; @@ -653,7 +658,7 @@ export default class Request { public async getEscrowData( paymentReference: string, - network: string, + network: CurrencyTypes.EvmChainName, ): 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 ca27f67cfb..bd60090e04 100644 --- a/packages/request-client.js/src/http-metamask-data-access.ts +++ b/packages/request-client.js/src/http-metamask-data-access.ts @@ -1,6 +1,6 @@ import { Block } from '@requestnetwork/data-access'; import { requestHashSubmitterArtifact } from '@requestnetwork/smart-contracts'; -import { ClientTypes, DataAccessTypes, StorageTypes } from '@requestnetwork/types'; +import { ClientTypes, CurrencyTypes, DataAccessTypes, StorageTypes } from '@requestnetwork/types'; import axios, { AxiosRequestConfig } from 'axios'; import { ethers } from 'ethers'; import { EventEmitter } from 'events'; @@ -23,7 +23,7 @@ export default class HttpMetaMaskDataAccess extends HttpDataAccess { private submitterContract: ethers.Contract | undefined; private provider: ethers.providers.JsonRpcProvider | ethers.providers.Web3Provider; - private networkName = ''; + private networkName: CurrencyTypes.EvmChainName = 'private'; /** * Creates an instance of HttpDataAccess. diff --git a/packages/request-client.js/test/index.test.ts b/packages/request-client.js/test/index.test.ts index bfa9f8bd56..e5d334ac58 100644 --- a/packages/request-client.js/test/index.test.ts +++ b/packages/request-client.js/test/index.test.ts @@ -10,7 +10,7 @@ import { RequestLogicTypes, } from '@requestnetwork/types'; import { decrypt, random32Bytes } from '@requestnetwork/utils'; -import { ethers } from 'ethers'; +import { BigNumber, ethers } from 'ethers'; import AxiosMockAdapter from 'axios-mock-adapter'; import { Request, RequestNetwork, RequestNetworkBase } from '../src/index'; @@ -18,13 +18,13 @@ import * as TestData from './data-test'; import * as TestDataRealBTC from './data-test-real-btc'; import { PaymentReferenceCalculator } from '@requestnetwork/payment-detection'; -import { BigNumber } from 'ethers'; import EtherscanProviderMock from './etherscan-mock'; import httpConfigDefaults from '../src/http-config-defaults'; import { IRequestDataWithEvents } from '../src/types'; import HttpMetaMaskDataAccess from '../src/http-metamask-data-access'; import MockDataAccess from '../src/mock-data-access'; import MockStorage from '../src/mock-storage'; +import * as RequestLogic from '@requestnetwork/types/src/request-logic-types'; const packageJson = require('../package.json'); @@ -1826,7 +1826,7 @@ describe('request-client.js', () => { }); describe('Token lists', () => { - const testErc20Data = { + const testErc20Data: RequestLogic.ICreateParameters = { ...TestData.parametersWithoutExtensionsData, currency: { network: 'private', @@ -1834,7 +1834,7 @@ describe('request-client.js', () => { value: '0x9FBDa871d559710256a2502A2517b794B482Db40', // Test Erc20 }, }; - const daiData = { + const daiData: RequestLogic.ICreateParameters = { ...TestData.parametersWithoutExtensionsData, currency: { network: 'mainnet', diff --git a/packages/request-node/src/thegraph-node.ts b/packages/request-node/src/thegraph-node.ts index 757a603329..6c73885178 100644 --- a/packages/request-node/src/thegraph-node.ts +++ b/packages/request-node/src/thegraph-node.ts @@ -7,16 +7,12 @@ import { RequestNodeBase } from './requestNodeBase'; import * as config from './config'; import { getIpfsStorage } from './storageUtils'; import { TheGraphDataAccess } from '@requestnetwork/thegraph-data-access'; -import { EthereumStorageEthers } from '@requestnetwork/ethereum-storage'; +import { + EthereumStorageEthers, + getEthereumStorageNetworkNameFromId, +} from '@requestnetwork/ethereum-storage'; import { SimpleLogger } from '@requestnetwork/utils'; -const getNetworkFromId = (networkId: number) => { - const customNames: Record = { - 0: 'private', - 1: 'mainnet', - }; - return customNames[networkId] || providers.getNetwork(networkId).name; -}; export class TheGraphRequestNode extends RequestNodeBase { constructor(url: string, logger?: LogTypes.ILogger) { const initializationStoragePath = config.getInitializationStorageFilePath(); @@ -28,7 +24,11 @@ export class TheGraphRequestNode extends RequestNodeBase { }) : undefined; - const network = getNetworkFromId(config.getStorageNetworkId()); + const network = getEthereumStorageNetworkNameFromId(config.getStorageNetworkId()); + if (!network) { + throw new Error(`Storage network not supported: ${config.getStorageNetworkId()}`); + } + const wallet = Wallet.fromMnemonic(config.getMnemonic()).connect( new providers.StaticJsonRpcProvider(config.getStorageWeb3ProviderUrl()), ); diff --git a/packages/smart-contracts/scripts-create2/compute-one-address.ts b/packages/smart-contracts/scripts-create2/compute-one-address.ts index 7c3537f7ed..565c987a98 100644 --- a/packages/smart-contracts/scripts-create2/compute-one-address.ts +++ b/packages/smart-contracts/scripts-create2/compute-one-address.ts @@ -1,7 +1,8 @@ -import { IDeploymentParams, HardhatRuntimeEnvironmentExtended } from './types'; +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( @@ -46,6 +47,8 @@ export async function computeCreate2DeploymentAddress( 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; @@ -60,7 +63,7 @@ export const computeCreate2DeploymentAddressesFromList = async ( case 'ERC20SwapToConversion': case 'ERC20TransferableReceivable': { try { - const constructorArgs = getConstructorArgs(contract, hre.network.name); + const constructorArgs = getConstructorArgs(contract, chain); address = await computeCreate2DeploymentAddress({ contract, constructorArgs }, hre); console.log(`${contract.padEnd(36, ' ')}${address}`); } catch (e) { diff --git a/packages/smart-contracts/scripts-create2/constructor-args.ts b/packages/smart-contracts/scripts-create2/constructor-args.ts index df459d352d..58cbd60617 100644 --- a/packages/smart-contracts/scripts-create2/constructor-args.ts +++ b/packages/smart-contracts/scripts-create2/constructor-args.ts @@ -1,4 +1,5 @@ import * as artifacts from '../src/lib'; +import { CurrencyTypes } from '@requestnetwork/types'; const getAdminWalletAddress = (contract: string): string => { if (!process.env.ADMIN_WALLET_ADDRESS) { @@ -7,7 +8,10 @@ const getAdminWalletAddress = (contract: string): string => { return process.env.ADMIN_WALLET_ADDRESS; }; -export const getConstructorArgs = (contract: string, network?: string): string[] => { +export const getConstructorArgs = ( + contract: string, + network?: CurrencyTypes.EvmChainName, +): 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 0b108e548a..6f94045aa7 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/adminTasks.ts @@ -10,6 +10,7 @@ import { getCeloProvider, getDefaultProvider, } from '@requestnetwork/utils'; +import { CurrencyTypes } from '@requestnetwork/types'; // Fees: 0.5% export const REQUEST_SWAP_FEES = 5; @@ -28,7 +29,7 @@ const BATCH_FEE_AMOUNT_USD_LIMIT = parseUnits('150', 8); */ export const updateChainlinkConversionPath = async ( contract: any, - network: string, + network: CurrencyTypes.EvmChainName, txOverrides: Overrides, version?: string, ): Promise => { @@ -120,7 +121,7 @@ export const updateBatchPaymentFeeAmountUSDLimit = async ( */ export const updatePaymentFeeProxyAddress = async ( contract: any, - network: string, + network: CurrencyTypes.EvmChainName, txOverrides: Overrides, proxyType: 'native' | 'erc20', version?: string, @@ -153,7 +154,7 @@ export const updatePaymentFeeProxyAddress = async ( */ export const updateBatchConversionProxy = async ( contract: any, - network: string, + network: CurrencyTypes.EvmChainName, txOverrides: Overrides, proxyName: | 'native' diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts index 66c025f360..06ffdad522 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts @@ -1,14 +1,14 @@ import { batchConversionPaymentsArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; import { - updateBatchPaymentFees, + getSignerAndGasFees, updateBatchConversionProxy, updateBatchPaymentFeeAmountUSDLimit, + updateBatchPaymentFees, updateNativeAndUSDAddress, - getSignerAndGasFees, } from './adminTasks'; -import { CurrencyManager } from '@requestnetwork/currency'; -import { RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; /** * Updates the values of the batch fees of the BatchConversionPayments contract, if needed. @@ -27,7 +27,7 @@ export const setupBatchConversionPayments = async ( // constants related to chainlink and conversion rate const currencyManager = CurrencyManager.getDefault(); - const setUpActions = async (network: string) => { + const setUpActions = async (network: CurrencyTypes.EvmChainName) => { console.log(`Setup BatchConversionPayments on ${network}`); const NativeAddress = currencyManager.getNativeCurrency( @@ -79,11 +79,12 @@ export const setupBatchConversionPayments = async ( }; for (const network of hre.config.xdeploy.networks) { try { + EvmChains.assertChainSupported(network); await Promise.resolve(setUpActions(network)); } catch (err) { console.warn(`An error occurred during the setup of BatchConversion on ${network}`); console.warn(err); } } - console.log('Setup for setupBatchConversionPayment successfull'); + console.log('Setup for setupBatchConversionPayment successful'); }; diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts index 5e8690c071..41763e16f8 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupERC20SwapToConversion.ts @@ -6,6 +6,7 @@ import { updateRequestSwapFees, updateSwapRouter, } from './adminTasks'; +import { EvmChains } from '@requestnetwork/currency'; /** * Updates the values of the chainlinkConversionPath and swap router of the ERC20SwapToConversion contract, if needed @@ -24,6 +25,7 @@ export const setupERC20SwapToConversion = async ( await Promise.all( hre.config.xdeploy.networks.map(async (network) => { try { + EvmChains.assertChainSupported(network); const { signer, txOverrides } = await getSignerAndGasFees(network, hre); const ERC20SwapToConversionConnected = await ERC20SwapToConversionContract.connect(signer); diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupETHConversionProxy.ts index f61318f008..8a97f44050 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 } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { RequestLogicTypes } from '@requestnetwork/types'; import { ethConversionArtifact } from '../../src/lib'; import { HardhatRuntimeEnvironmentExtended } from '../types'; @@ -26,6 +26,7 @@ export const setupETHConversionProxy = async ( await Promise.all( hre.config.xdeploy.networks.map(async (network) => { try { + EvmChains.assertChainSupported(network); const { signer, txOverrides } = await getSignerAndGasFees(network, hre); const nativeTokenHash = CurrencyManager.getDefault().getNativeCurrency( RequestLogicTypes.CURRENCY.ETH, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts index 59095e5f21..e668949390 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupErc20ConversionProxy.ts @@ -5,6 +5,7 @@ import { updateChainlinkConversionPath, updatePaymentFeeProxyAddress, } from './adminTasks'; +import { EvmChains } from '@requestnetwork/currency'; const ERC20ConversionVersion = '0.1.2'; @@ -25,6 +26,7 @@ export const setupErc20ConversionProxy = async ( await Promise.all( hre.config.xdeploy.networks.map(async (network) => { try { + EvmChains.assertChainSupported(network); const { signer, txOverrides } = await getSignerAndGasFees(network, hre); const Erc20ConversionProxyConnected = Erc20ConversionProxyContract.connect(signer); await updatePaymentFeeProxyAddress( diff --git a/packages/smart-contracts/scripts-create2/deploy.ts b/packages/smart-contracts/scripts-create2/deploy.ts index 75511ee12c..117d0ff1ff 100644 --- a/packages/smart-contracts/scripts-create2/deploy.ts +++ b/packages/smart-contracts/scripts-create2/deploy.ts @@ -1,16 +1,16 @@ import { create2ContractDeploymentList, isContractDeployed } from './utils'; -import { IDeploymentParams } from './types'; -import { HardhatRuntimeEnvironmentExtended } from './types'; +import { HardhatRuntimeEnvironmentExtended, IDeploymentParams } from './types'; import { xdeploy } from './xdeployer'; import { getConstructorArgs } from './constructor-args'; import { + setupBatchConversionPayments, + setupChainlinkConversionPath, + setupErc20ConversionProxy, setupERC20SwapToConversion, setupERC20SwapToPay, - setupBatchConversionPayments, setupETHConversionProxy, - setupErc20ConversionProxy, - setupChainlinkConversionPath, } from './contract-setup'; +import { EvmChains } from '@requestnetwork/currency'; // Deploys, set up the contracts and returns the address export const deployOneWithCreate2 = async ( @@ -22,33 +22,27 @@ export const deployOneWithCreate2 = async ( } // Deploy the contract on several network through xdeployer const deploymentResult = await xdeploy(deploymentParams, hre); - for (let i = 0; i < hre.config.xdeploy.networks.length; i++) { + hre.config.xdeploy.networks.forEach((network, i) => { if (deploymentResult[i].deployed) { console.log(`${deploymentParams.contract} successfully deployed:`); - console.log(` On network: ${hre.config.xdeploy.networks[i]}`); + console.log(` On network: ${network}`); console.log(` At address: ${deploymentResult[i].address}`); console.log(` At block: ${deploymentResult[i].receipt.blockNumber}`); } else { - if ( - isContractDeployed( - deploymentParams.contract, - hre.config.xdeploy.networks[i], - deploymentResult[i].address, - ) - ) { + if (isContractDeployed(deploymentParams.contract, network, deploymentResult[i].address)) { console.log(`${deploymentParams.contract} already deployed:`); - console.log(` On network: ${hre.config.xdeploy.networks[i]}`); + console.log(` On network: ${network}`); console.log(` At address: ${deploymentResult[i].address}`); } else { console.log(`${deploymentParams.contract} has not been deployed:`); - console.log(` On network: ${hre.config.xdeploy.networks[i]}`); + console.log(` On network: ${network}`); console.log(` Error: ${deploymentResult[i].error}`); console.log( ` Hint: Check admin wallet balance and that your artifacts are up to date`, ); } } - } + }); return deploymentResult[0].address; }; @@ -97,12 +91,14 @@ export const deployWithCreate2FromList = async ( case 'ERC20EscrowToPay': case 'ERC20TransferableReceivable': { const network = hre.config.xdeploy.networks[0]; + EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); await deployOneWithCreate2({ contract, constructorArgs }, hre); break; } case 'BatchConversionPayments': { const network = hre.config.xdeploy.networks[0]; + EvmChains.assertChainSupported(network); const constructorArgs = getConstructorArgs(contract, network); const address = await deployOneWithCreate2({ contract, constructorArgs }, hre); await setupBatchConversionPayments(address, hre); diff --git a/packages/smart-contracts/scripts-create2/utils.ts b/packages/smart-contracts/scripts-create2/utils.ts index c63ff96dad..3ed10e6d91 100644 --- a/packages/smart-contracts/scripts-create2/utils.ts +++ b/packages/smart-contracts/scripts-create2/utils.ts @@ -1,5 +1,6 @@ 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 @@ -59,7 +60,7 @@ export const getArtifact = (contract: string): artifacts.ContractArtifact { - const contractArtifact = getArtifact(contract); - const addresses = contractArtifact.getAllAddresses(network); - return addresses.some((x) => x.address === computedAddress); + try { + EvmChains.assertChainSupported(network); + const contractArtifact = getArtifact(contract); + const addresses = contractArtifact.getAllAddresses(network); + return addresses.some((x) => x.address === computedAddress); + } catch (e) { + return false; + } }; diff --git a/packages/smart-contracts/scripts-create2/verify.ts b/packages/smart-contracts/scripts-create2/verify.ts index 3e5be641d3..a02707df12 100644 --- a/packages/smart-contracts/scripts-create2/verify.ts +++ b/packages/smart-contracts/scripts-create2/verify.ts @@ -1,8 +1,8 @@ import { computeCreate2DeploymentAddress } from './compute-one-address'; import { getConstructorArgs } from './constructor-args'; -import { HardhatRuntimeEnvironmentExtended } from './types'; -import { IDeploymentParams } from './types'; +import { HardhatRuntimeEnvironmentExtended, IDeploymentParams } from './types'; import { create2ContractDeploymentList } from './utils'; +import { EvmChains } from '@requestnetwork/currency'; export const verifyOne = async ( contractAddress: string, @@ -48,6 +48,7 @@ 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 0f10e76267..1bfb1f04d1 100644 --- a/packages/smart-contracts/scripts/deploy-one.ts +++ b/packages/smart-contracts/scripts/deploy-one.ts @@ -2,6 +2,7 @@ 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; @@ -59,7 +60,9 @@ export async function deployOne( const constructorArguments = options?.constructorArguments ?? []; if (options?.artifact) { try { - address = options.artifact.getAddress(hre.network.name, options.version); + const chain = hre.network.name; + EvmChains.assertChainSupported(chain); + address = options.artifact.getAddress(chain, options.version); const action = args.force ? '(forcing deployment)' : '(skipping)'; console.log( `Found ${contractName}${options.version ? ` v${options.version}` : ''} on ${ 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 ce9bdd5368..cff4bfef7e 100644 --- a/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts +++ b/packages/smart-contracts/scripts/test-deploy-batch-conversion-deployment.ts @@ -5,13 +5,13 @@ import { deployOne } from './deploy-one'; import { batchConversionPaymentsArtifact, chainlinkConversionPath, + chainlinkConversionPath as chainlinkConvArtifact, erc20ConversionProxy, erc20FeeProxyArtifact, ethConversionArtifact, ethereumFeeProxyArtifact, } from '../src/lib'; -import { chainlinkConversionPath as chainlinkConvArtifact } from '../src/lib'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { deployAddressChecking } from './utils'; import { BigNumber } from 'ethers'; import { PRECISION_RATE } from './test-deploy_chainlink_contract'; @@ -25,6 +25,8 @@ export async function deployBatchConversionPayment( ): Promise { 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'); @@ -75,7 +77,7 @@ export async function deployBatchConversionPayment( ); // Initialize batch conversion fee, useful to others packages. - const batchConversion = batchConversionPaymentsArtifact.connect(hre.network.name, owner); + const batchConversion = batchConversionPaymentsArtifact.connect(chain, owner); await batchConversion.connect(owner).setBatchFee(30); await batchConversion .connect(owner) 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 96fa279ccf..2d115a3f07 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,10 +4,13 @@ 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'; @@ -22,7 +25,7 @@ export async function deployBatchPayment(args: any, hre: HardhatRuntimeEnvironme // Initialize batch fee, useful to others packages. const [owner] = await hre.ethers.getSigners(); - const batch = batchPaymentsArtifact.connect(hre.network.name, owner); + const batch = batchPaymentsArtifact.connect(chain, owner); await batch.connect(owner).setBatchFee(10); // ---------------------------------- diff --git a/packages/smart-contracts/src/lib/ContractArtifact.ts b/packages/smart-contracts/src/lib/ContractArtifact.ts index ad2a38de21..54360c4a7f 100644 --- a/packages/smart-contracts/src/lib/ContractArtifact.ts +++ b/packages/smart-contracts/src/lib/ContractArtifact.ts @@ -1,5 +1,6 @@ import { Contract, providers, Signer } from 'ethers'; import type { JsonFragment } from '@ethersproject/abi'; +import type { CurrencyTypes } from '@requestnetwork/types'; /** * Contract information specific to a network @@ -12,15 +13,17 @@ export type ArtifactNetworkInfo = { }; /** Deployment information and ABI per network */ -export type ArtifactDeploymentInfo = { +export type ArtifactDeploymentInfo< + TNetwork extends CurrencyTypes.EvmChainName = CurrencyTypes.EvmChainName, +> = { abi: JsonFragment[]; - deployment: Record; + deployment: Partial>; }; /** Deployment information and ABI per version and network */ export type ArtifactInfo< TVersion extends string = string, - TNetwork extends string = string, + TNetwork extends CurrencyTypes.EvmChainName = CurrencyTypes.EvmChainName, > = Record>; export type DeploymentInformation = { @@ -33,7 +36,7 @@ export type DeploymentInformation = { * and utilities to connect to it **/ export class ContractArtifact { - constructor(private info: ArtifactInfo, private lastVersion: string) { + constructor(private info: ArtifactInfo, private lastVersion: string) { this.connect = this.connect.bind(this); this.getInterface = this.getInterface.bind(this); this.getContractAbi = this.getContractAbi.bind(this); @@ -48,7 +51,7 @@ export class ContractArtifact { * Returns an ethers contract instance for the given `networkName` */ connect( - networkName: string, + networkName: CurrencyTypes.EvmChainName, signerOrProvider: Signer | providers.Provider, version: string = this.lastVersion, ): TContract { @@ -77,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: string, version = this.lastVersion): string { + getAddress(networkName: CurrencyTypes.EvmChainName, version = this.lastVersion): string { return this.getDeploymentInformation(networkName, version).address; } @@ -86,7 +89,9 @@ 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: string): { version: string; address: string }[] { + getAllAddresses( + networkName: CurrencyTypes.EvmChainName, + ): { version: string; address: string | undefined }[] { const entries = Object.entries(this.info); return entries.map(([version, { deployment }]) => ({ version, @@ -100,7 +105,10 @@ 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: string, version = this.lastVersion): number { + getCreationBlockNumber( + networkName: CurrencyTypes.EvmChainName, + version = this.lastVersion, + ): number { return this.getDeploymentInformation(networkName, version).creationBlockNumber; } @@ -110,7 +118,10 @@ 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: string, version = this.lastVersion): DeploymentInformation { + getDeploymentInformation( + networkName: CurrencyTypes.EvmChainName, + version = this.lastVersion, + ): DeploymentInformation { const versionInfo = this.info[version]; if (!versionInfo) { throw Error(`No deployment for version: ${version}.`); @@ -130,7 +141,7 @@ export class ContractArtifact { * @returns The address and the number of the creation block, or null if not found */ getOptionalDeploymentInformation( - networkName: string, + networkName: CurrencyTypes.EvmChainName, 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 70b56b41a7..8e74d5f268 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 } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } 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,6 +29,7 @@ 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; @@ -123,6 +124,7 @@ 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 eb02ac317a..ba5cdfeb0f 100644 --- a/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts +++ b/packages/smart-contracts/test/contracts/BatchNoConversionErc20Payments.test.ts @@ -2,17 +2,17 @@ import { ethers, network } from 'hardhat'; import { BigNumber, Signer } from 'ethers'; import { expect } from 'chai'; import { - TestERC20__factory, - TestERC20, - ERC20FeeProxy, - EthereumFeeProxy__factory, BatchNoConversionPayments, - ERC20FeeProxy__factory, BatchNoConversionPayments__factory, ChainlinkConversionPath, + ERC20FeeProxy, + ERC20FeeProxy__factory, + EthereumFeeProxy__factory, + TestERC20, + TestERC20__factory, } from '../../src/types'; import { chainlinkConversionPath } from '../../src/lib'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { RequestDetail } from 'types/dist/payment-types'; const logGasInfos = false; @@ -67,6 +67,7 @@ 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 93288dcaa7..e3d977802b 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 'types/dist'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; const logGasInfos = false; @@ -65,6 +65,7 @@ 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 60c46c716c..faf6f2de35 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 } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { ethers, network } from 'hardhat'; import '@nomiclabs/hardhat-ethers'; import { chainlinkConversionPath as chainlinkConvArtifact } from '../../src/lib'; @@ -25,6 +25,7 @@ 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 66fd72f83a..768f7987b3 100644 --- a/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts +++ b/packages/smart-contracts/test/contracts/ERC20SwapToConversion.test.ts @@ -2,16 +2,16 @@ import { ethers, network } from 'hardhat'; import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { - TestERC20__factory, - TestERC20, - FakeSwapRouter__factory, - FakeSwapRouter, AggregatorMock__factory, + ChainlinkConversionPath, Erc20ConversionProxy, ERC20SwapToConversion, - ChainlinkConversionPath, + FakeSwapRouter, + FakeSwapRouter__factory, + TestERC20, + TestERC20__factory, } from '../../src/types'; import { chainlinkConversionPath as chainlinkConvArtifact, @@ -49,12 +49,12 @@ 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); erc20ConversionProxy = erc20ConversionProxyArtifact.connect(network.name, adminSigner); swapConversionProxy = erc20SwapConversionArtifact.connect(network.name, adminSigner); - await swapConversionProxy.updateConversionPathAddress(chainlinkConversion.address); await swapConversionProxy.updateRequestSwapFees(requestSwapFees); }); diff --git a/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts b/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts index 431e08353c..072ed2bfde 100644 --- a/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts +++ b/packages/smart-contracts/test/contracts/ERC20SwapToPay.test.ts @@ -3,16 +3,17 @@ import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; import { - TestERC20__factory, - TestERC20, - FakeSwapRouter__factory, - FakeSwapRouter, - BadERC20__factory, BadERC20, - ERC20SwapToPay, + BadERC20__factory, ERC20FeeProxy, + ERC20SwapToPay, + FakeSwapRouter, + FakeSwapRouter__factory, + TestERC20, + TestERC20__factory, } from '../../src/types'; import { erc20FeeProxyArtifact, erc20SwapToPayArtifact } from '../../src/lib'; +import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -38,9 +39,9 @@ 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); testSwapToPay = erc20SwapToPayArtifact.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 6807e26347..b0ccaba8b5 100644 --- a/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts +++ b/packages/smart-contracts/test/contracts/Erc20ConversionProxy.test.ts @@ -1,17 +1,17 @@ import { ethers, network } from 'hardhat'; import { - ERC20FeeProxy__factory, + ChainlinkConversionPath, + Erc20ConversionProxy, Erc20ConversionProxy__factory, ERC20FeeProxy, - ChainlinkConversionPath, + ERC20FeeProxy__factory, TestERC20, - Erc20ConversionProxy, TestERC20__factory, } from '../../src/types'; import { BigNumber, Signer } from 'ethers'; import { expect, use } from 'chai'; import { solidity } from 'ethereum-waffle'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { chainlinkConversionPath } from '../../src/lib'; import { localERC20AlphaArtifact } from './localArtifacts'; @@ -41,9 +41,9 @@ 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); erc20FeeProxy = await new ERC20FeeProxy__factory(signer).deploy(); testErc20ConversionProxy = await new Erc20ConversionProxy__factory(signer).deploy( diff --git a/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts b/packages/smart-contracts/test/contracts/EthConversionProxy.test.ts index 3f4e70b0dd..0a1fcb9a05 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 } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; import { chainlinkConversionPath } from '../../src/lib'; import { HttpNetworkConfig } from 'hardhat/types'; @@ -45,9 +45,9 @@ 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); ethFeeProxy = await new EthereumFeeProxy__factory(signer).deploy(); testEthConversionProxy = await new EthConversionProxy__factory(signer).deploy( diff --git a/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts b/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts index 261c310002..395a5b3827 100644 --- a/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts +++ b/packages/smart-contracts/test/contracts/EthereumFeeProxy.test.ts @@ -11,6 +11,7 @@ import { } from '../../src/types'; import { ethereumFeeProxyArtifact } from '../../src/lib/'; import { HttpNetworkConfig } from 'hardhat/types'; +import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -28,6 +29,7 @@ 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 17d0f19d14..5946e0c3fd 100644 --- a/packages/smart-contracts/test/contracts/EthereumProxy.test.ts +++ b/packages/smart-contracts/test/contracts/EthereumProxy.test.ts @@ -11,6 +11,7 @@ import { } from '../../src/types'; import { ethereumProxyArtifact } from '../../src/lib/'; import { HttpNetworkConfig } from 'hardhat/types'; +import { EvmChains } from '@requestnetwork/currency'; use(solidity); @@ -28,6 +29,7 @@ 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 1d4059cd2c..dd98e3475e 100644 --- a/packages/smart-contracts/test/lib/artifact.test.ts +++ b/packages/smart-contracts/test/lib/artifact.test.ts @@ -1,6 +1,7 @@ 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', () => { @@ -55,9 +56,9 @@ describe('Artifact', () => { }); it('throws for a non-existing network', () => { - expect(() => erc20ProxyArtifact.getDeploymentInformation('fakenetwork')).toThrowError( - `No deployment for network: fakenetwork`, - ); + expect(() => + erc20ProxyArtifact.getDeploymentInformation('fakenetwork' as CurrencyTypes.EvmChainName), + ).toThrowError(`No deployment for network: fakenetwork`); }); it('throws for a non-existing version', () => { diff --git a/packages/toolbox/src/chainlinkConversionPathTools.ts b/packages/toolbox/src/chainlinkConversionPathTools.ts index b92a3ea419..e3816684dd 100644 --- a/packages/toolbox/src/chainlinkConversionPathTools.ts +++ b/packages/toolbox/src/chainlinkConversionPathTools.ts @@ -2,13 +2,14 @@ import { ethers, providers } from 'ethers'; import { chainlinkConversionPath } from '@requestnetwork/smart-contracts'; import { getDefaultProvider, parseLogArgs } from '@requestnetwork/payment-detection'; import { - ChainlinkConversionPath__factory, ChainlinkConversionPath, + ChainlinkConversionPath__factory, } from '@requestnetwork/smart-contracts/types'; -import { CurrencyManager, UnsupportedCurrencyError } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains, UnsupportedCurrencyError } from '@requestnetwork/currency'; import Bluebird from 'bluebird'; import chunk from 'lodash/chunk'; import { retry } from '@requestnetwork/utils'; +import { CurrencyTypes } from '@requestnetwork/types'; export interface IOptions { network?: string; @@ -37,7 +38,7 @@ class ChainlinkConversionPathTools { * @param network The Ethereum network to use */ constructor( - private network: string, + private network: CurrencyTypes.EvmChainName, options?: { web3Url?: string; lastBlock?: number; maxRange?: number }, ) { const web3Url = @@ -142,7 +143,11 @@ const getCurrency = (symbol: string) => { }; export const listAggregators = async (options?: IOptions): Promise => { - const networks = options?.network ? [options.network] : ['private', 'rinkeby', 'mainnet']; + let networks: CurrencyTypes.EvmChainName[] = ['private', 'rinkeby', 'mainnet']; + if (options?.network) { + EvmChains.assertChainSupported(options.network); + networks = [options.network]; + } // Create an Object to be used by a dijkstra algorithm to find the best path between two currencies const allAggregators: Record>> = {}; diff --git a/packages/toolbox/src/commands/chainlink/addAggregator.ts b/packages/toolbox/src/commands/chainlink/addAggregator.ts index 7d355a0431..27ed22fe9c 100644 --- a/packages/toolbox/src/commands/chainlink/addAggregator.ts +++ b/packages/toolbox/src/commands/chainlink/addAggregator.ts @@ -2,6 +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'; type Options = { dryRun: boolean; @@ -60,6 +61,8 @@ export const handler = async (args: Options): Promise => { const { network, list } = args; const currencyManager = await getCurrencyManager(list); + + EvmChains.assertChainSupported(network); const inputCcy = currencyManager.from(input, network) || currencyManager.from(input); const outputCcy = currencyManager.from(output, network) || currencyManager.from(output); diff --git a/packages/toolbox/src/commands/chainlink/addAggregators.ts b/packages/toolbox/src/commands/chainlink/addAggregators.ts index 93eba581e6..0b036e8988 100644 --- a/packages/toolbox/src/commands/chainlink/addAggregators.ts +++ b/packages/toolbox/src/commands/chainlink/addAggregators.ts @@ -2,7 +2,7 @@ import * as yargs from 'yargs'; import inquirer from 'inquirer'; import { runUpdate } from './contractUtils'; import { Aggregator, getAvailableAggregators, getCurrencyManager } from './aggregatorsUtils'; -import { conversionSupportedNetworks } from '@requestnetwork/currency'; +import { conversionSupportedNetworks, EvmChains } from '@requestnetwork/currency'; type Options = { dryRun: boolean; @@ -73,6 +73,7 @@ export const handler = async (args: Options): Promise => { const currencyManager = await getCurrencyManager(args.list); + EvmChains.assertChainSupported(network); if (!conversionSupportedNetworks.includes(network)) { console.warn( `WARNING: ${network} is missing in conversionSupportedNetworks from the Currency package.`, diff --git a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts index 5480dc3c3b..46071b459a 100644 --- a/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts +++ b/packages/toolbox/src/commands/chainlink/aggregatorsUtils.ts @@ -1,6 +1,6 @@ -import { CurrencyManager, CurrencyInput, AggregatorsMap } from '@requestnetwork/currency'; +import { AggregatorsMap, CurrencyInput, CurrencyManager } from '@requestnetwork/currency'; import axios from 'axios'; -import { RequestLogicTypes } from '@requestnetwork/types'; +import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types'; type Proxy = { pair: string; @@ -26,7 +26,9 @@ export type Aggregator = { aggregator: string; }; -const feedMap: Record = { +const feedMap: Partial< + Record +> = { mainnet: ['ethereum', 'Ethereum Mainnet'], goerli: ['ethereum', 'Goerli Testnet'], rinkeby: ['ethereum', 'Rinkeby Testnet'], @@ -40,7 +42,7 @@ const feedMap: Record = { moonbeam: ['moonbeam', 'Moonbeam Mainnet'], }; -export const getAllAggregators = async (network: string): Promise => { +export const getAllAggregators = async (network: CurrencyTypes.EvmChainName): Promise => { const [feedName, networkName] = feedMap[network] || []; if (!feedName || !networkName) { throw new Error( @@ -59,7 +61,7 @@ export const getAllAggregators = async (network: string): Promise => { }; export const getAvailableAggregators = async ( - network: string, + network: CurrencyTypes.EvmChainName, cm: CurrencyManager, pairs?: string[], listAll?: boolean, diff --git a/packages/toolbox/src/commands/chainlink/contractUtils.ts b/packages/toolbox/src/commands/chainlink/contractUtils.ts index 9edf6e5a08..833e26ccd0 100644 --- a/packages/toolbox/src/commands/chainlink/contractUtils.ts +++ b/packages/toolbox/src/commands/chainlink/contractUtils.ts @@ -4,6 +4,7 @@ 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'; export const runUpdate = async ( method: T, @@ -73,6 +74,8 @@ const connectChainlinkContracts = ({ dryRun, network, }: SharedOptions): ChainlinkContractWithVersion[] => { + EvmChains.assertChainSupported(network); + const provider = getDefaultProvider(network); const wallet = privateKey @@ -94,7 +97,7 @@ const connectChainlinkContracts = ({ return versions.map((version) => { return { version, - contract: chainlinkConversionPath.connect(network, wallet as any, version) as any, // TODO} + contract: chainlinkConversionPath.connect(network, wallet as any, version) as any, // TODO }; }); }; diff --git a/packages/toolbox/src/commands/chainlink/getConversionPath.ts b/packages/toolbox/src/commands/chainlink/getConversionPath.ts index c44a699262..b4bfee0728 100644 --- a/packages/toolbox/src/commands/chainlink/getConversionPath.ts +++ b/packages/toolbox/src/commands/chainlink/getConversionPath.ts @@ -1,5 +1,5 @@ import * as yargs from 'yargs'; -import { CurrencyManager } from '@requestnetwork/currency'; +import { CurrencyManager, EvmChains } from '@requestnetwork/currency'; type Options = { to: string; from: string; network: string }; @@ -27,5 +27,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)); }; diff --git a/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts b/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts index 04b01f5b7b..c7816cca14 100644 --- a/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts +++ b/packages/toolbox/src/commands/chainlink/listMissingAggregators.ts @@ -1,5 +1,6 @@ import * as yargs from 'yargs'; import { getAvailableAggregators, getCurrencyManager } from './aggregatorsUtils'; +import { EvmChains } from '@requestnetwork/currency'; type Options = { network: string[]; @@ -30,6 +31,7 @@ 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); if (available.length > 0) { console.log(network); diff --git a/packages/toolbox/src/commands/hash/submit.ts b/packages/toolbox/src/commands/hash/submit.ts index 2005788730..3b345da6fa 100644 --- a/packages/toolbox/src/commands/hash/submit.ts +++ b/packages/toolbox/src/commands/hash/submit.ts @@ -6,6 +6,7 @@ import yargs from 'yargs'; import { getWallet } from '../transaction/utils'; import { EthereumTransactionSubmitter, IpfsStorage } from '@requestnetwork/ethereum-storage'; import { StorageTypes } from '@requestnetwork/types'; +import { EvmChains } from '@requestnetwork/currency'; export const command = 'hash submit '; export const describe = 'Forces the submission of an IPFS hash to the Request HashStorage contract'; @@ -17,6 +18,8 @@ export const builder = (y: yargs.Argv) => .option('dryRun', { type: 'boolean', default: false }); export const handler = async (argv: yargs.Arguments>>) => { + EvmChains.assertChainSupported(argv.chainName); + const wallet = await getWallet({ chainName: argv.chainName, dryRun: argv.dryRun }); const ipfsStorage = new IpfsStorage({ ipfsGatewayConnection: { diff --git a/packages/types/src/advanced-logic-types.ts b/packages/types/src/advanced-logic-types.ts index 0aeb381c0a..4f63f378b9 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 { ChainName } from './currency-types'; /** Advanced Logic extensions */ export interface IAdvancedLogicExtensions { @@ -32,10 +33,10 @@ export interface IAdvancedLogic { timestamp: number, ) => RequestLogic.IExtensionStates; getNativeTokenExtensionForNetwork: ( - network: string, + network: ChainName, ) => Extension.IExtension | undefined; getAnyToNativeTokenExtensionForNetwork: ( - network: string, + network: ChainName, ) => Extension.IExtension | undefined; extensions: IAdvancedLogicExtensions; } diff --git a/packages/types/src/currency-types.ts b/packages/types/src/currency-types.ts new file mode 100644 index 0000000000..94843e4917 --- /dev/null +++ b/packages/types/src/currency-types.ts @@ -0,0 +1,41 @@ +/** + * List of supported EVM chains + */ +export type EvmChainName = + | 'alfajores' + | 'arbitrum-one' + | 'arbitrum-rinkeby' + | 'avalanche' + | 'bsc' + | 'bsctest' + | 'celo' + | 'fantom' + | 'fuse' + | 'goerli' + | 'mainnet' + | 'matic' + | 'moonbeam' + | 'mumbai' + | 'optimism' + | 'private' + | 'rinkeby' // FIXME: Rinkeby is deprecated + | 'ronin' + | 'sokol' + | 'tombchain' + | 'xdai'; + +/** + * List of supported BTC chains + */ +export type BtcChainName = 'mainnet' | 'testnet'; + +/** + * List of supported NEAR chains + */ +export type NearChainName = + | 'aurora' + | 'aurora-testnet' + // | 'near' // TODO: add support for near + | 'near-testnet'; + +export type ChainName = EvmChainName | BtcChainName | 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 a45bae072d..b9861a38d3 100644 --- a/packages/types/src/extensions/pn-any-reference-based-types.ts +++ b/packages/types/src/extensions/pn-any-reference-based-types.ts @@ -1,4 +1,5 @@ import { PnAddressBased } from '../extension-types'; +import { ChainName } from '../currency-types'; export { ACTION, IAddPaymentAddressParameters, @@ -17,5 +18,5 @@ export interface IValues extends PnAddressBased.IValues { /** Parameters of creation action */ export interface ICreationParameters extends PnAddressBased.ICreationParameters { salt?: string; - paymentNetworkName?: string; + paymentNetworkName?: ChainName; } 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 abd5da04b3..93460d3f7d 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,4 +1,5 @@ import { PnFeeReferenceBased } from '../extension-types'; +import { ChainName } from '../currency-types'; export { IAddPaymentAddressParameters, IAddRefundAddressParameters, @@ -12,5 +13,5 @@ export type IConversionReferenceBased /** Parameters for the creation action */ export interface ICreationParameters extends PnFeeReferenceBased.ICreationParameters { maxRateTimespan?: number; - network?: string; + network?: ChainName; } 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 dbdbd96a9f..143c8619dc 100644 --- a/packages/types/src/extensions/pn-any-to-erc20-types.ts +++ b/packages/types/src/extensions/pn-any-to-erc20-types.ts @@ -1,10 +1,12 @@ import * as PnAnyToAnyConversion from './pn-any-to-any-conversion-types'; +import { EvmChainName } from '../currency-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; // 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 eeb0627617..fbe554d28a 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,5 +1,6 @@ import * as AdvancedLogicTypes from './advanced-logic-types'; import * as ClientTypes from './client-types'; +import * as CurrencyTypes from './currency-types'; import * as DataAccessTypes from './data-access-types'; import * as DecryptionProviderTypes from './decryption-provider-types'; import * as EncryptionTypes from './encryption-types'; @@ -18,6 +19,7 @@ import * as TypesUtils from './utils'; export { AdvancedLogicTypes, ClientTypes, + CurrencyTypes, DataAccessTypes, DecryptionProviderTypes, EncryptionTypes, diff --git a/packages/types/src/payment-types.ts b/packages/types/src/payment-types.ts index a0a6ca1643..5cd91e44d1 100644 --- a/packages/types/src/payment-types.ts +++ b/packages/types/src/payment-types.ts @@ -3,6 +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'; /** Interface for payment network extensions state and interpretation */ export interface IPaymentNetwork { @@ -34,6 +35,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; } /** diff --git a/packages/types/src/request-logic-types.ts b/packages/types/src/request-logic-types.ts index f008317f4d..008d3d7b7c 100644 --- a/packages/types/src/request-logic-types.ts +++ b/packages/types/src/request-logic-types.ts @@ -5,6 +5,7 @@ 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 { @@ -254,7 +255,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?: string; + network?: CurrencyTypes.ChainName; } /** Enum of name possible in a action */ diff --git a/packages/types/src/storage-types.ts b/packages/types/src/storage-types.ts index d4902f1fc2..e60405e840 100644 --- a/packages/types/src/storage-types.ts +++ b/packages/types/src/storage-types.ts @@ -144,8 +144,6 @@ export enum EthereumNetwork { MAINNET = 1, RINKEBY = 4, GOERLI = 5, - KOVAN = 42, - SOKOL = 77, XDAI = 100, }