diff --git a/packages/currency/package.json b/packages/currency/package.json index 40798401e0..8befb4bff6 100644 --- a/packages/currency/package.json +++ b/packages/currency/package.json @@ -45,7 +45,7 @@ "@metamask/contract-metadata": "1.31.0", "@requestnetwork/types": "0.36.0", "@requestnetwork/utils": "0.36.0", - "multicoin-address-validator": "0.5.2", + "multicoin-address-validator": "0.5.12", "node-dijkstra": "2.5.0", "tslib": "2.5.0" }, diff --git a/packages/currency/src/chains/declarative/data/solana.ts b/packages/currency/src/chains/declarative/data/solana.ts new file mode 100644 index 0000000000..0a9e21bcf6 --- /dev/null +++ b/packages/currency/src/chains/declarative/data/solana.ts @@ -0,0 +1 @@ +export const chainId = 'solana'; diff --git a/packages/currency/src/chains/declarative/index.ts b/packages/currency/src/chains/declarative/index.ts index 804ccf2be9..6e38952bd8 100644 --- a/packages/currency/src/chains/declarative/index.ts +++ b/packages/currency/src/chains/declarative/index.ts @@ -2,9 +2,11 @@ import { CurrencyTypes } from '@requestnetwork/types'; import { Chain } from '../../types'; import * as TronDefinition from './data/tron'; +import * as SolanaDefinition from './data/solana'; export type DeclarativeChain = Chain; export const chains: Record = { tron: TronDefinition, + solana: SolanaDefinition, }; diff --git a/packages/currency/src/currencyManager.ts b/packages/currency/src/currencyManager.ts index b69c5a50f0..8afdba3b4e 100644 --- a/packages/currency/src/currencyManager.ts +++ b/packages/currency/src/currencyManager.ts @@ -246,7 +246,7 @@ export class CurrencyManager implements ICurrencyManager case RequestLogicTypes.CURRENCY.ERC777: if (NearChains.isChainSupported(currency.network)) { return isValidNearAddress(address, currency.network); - } else if (currency.network === 'tron') { + } else if (currency.network === 'tron' || currency.network === 'solana') { return addressValidator.validate(address, currency.network); } return addressValidator.validate(address, 'ETH'); diff --git a/packages/request-client.js/test/index.test.ts b/packages/request-client.js/test/index.test.ts index a4601f372e..643d0913fa 100644 --- a/packages/request-client.js/test/index.test.ts +++ b/packages/request-client.js/test/index.test.ts @@ -1635,7 +1635,7 @@ describe('request-client.js', () => { }); }); - it('Can create ERC20 declarative requests with non-evm currency', async () => { + it('Can create ERC20 declarative requests with non-evm currency - near', async () => { const testErc20TokenAddress = 'usdc.near'; const requestNetwork = new RequestNetwork({ signatureProvider: TestData.fakeSignatureProvider, @@ -1679,6 +1679,50 @@ describe('request-client.js', () => { expect(data.expectedAmount).toBe(requestParameters.expectedAmount); }); + it('Can create ERC20 declarative requests with non-evm currency - solana', async () => { + const testErc20TokenAddress = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; + const requestNetwork = new RequestNetwork({ + signatureProvider: TestData.fakeSignatureProvider, + useMockStorage: true, + }); + + const paymentNetwork: PaymentTypes.PaymentNetworkCreateParameters = { + id: ExtensionTypes.PAYMENT_NETWORK_ID.ANY_DECLARATIVE, + parameters: {}, + }; + + const requestInfo = Object.assign({}, TestData.parametersWithoutExtensionsData, { + currency: { + network: 'solana', + type: RequestLogicTypes.CURRENCY.ERC20, + value: testErc20TokenAddress, + }, + }); + + const request = await requestNetwork.createRequest({ + paymentNetwork, + requestInfo, + signer: TestData.payee.identity, + }); + + await new Promise((resolve): any => setTimeout(resolve, 150)); + let data = await request.refresh(); + + expect(data).toBeDefined(); + expect(data.balance?.balance).toBe('0'); + expect(data.balance?.events.length).toBe(0); + expect(data.meta).toBeDefined(); + expect(data.currency).toBe('unknown'); + + expect(data.extensions[ExtensionTypes.PAYMENT_NETWORK_ID.ANY_DECLARATIVE].values).toEqual({ + receivedPaymentAmount: '0', + receivedRefundAmount: '0', + sentPaymentAmount: '0', + sentRefundAmount: '0', + }); + expect(data.expectedAmount).toBe(requestParameters.expectedAmount); + }); + it('cannot create ERC20 address based requests with invalid currency', async () => { const testErc20TokenAddress = 'invalidErc20Address'; diff --git a/packages/types/src/currency-types.ts b/packages/types/src/currency-types.ts index 059bb0cb5e..af22547aed 100644 --- a/packages/types/src/currency-types.ts +++ b/packages/types/src/currency-types.ts @@ -34,7 +34,7 @@ export type BtcChainName = 'mainnet' | 'testnet'; /** * List of supported Declarative chains */ -export type DeclarativeChainName = 'tron'; +export type DeclarativeChainName = 'tron' | 'solana'; /** * List of supported NEAR chains diff --git a/yarn.lock b/yarn.lock index 79d5e32842..842ceaf503 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6904,6 +6904,13 @@ base-x@^3.0.2, base-x@^3.0.8: dependencies: safe-buffer "^5.0.1" +base-x@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + base64-js@0.0.8: version "0.0.8" resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz" @@ -16497,12 +16504,12 @@ multicodec@^1.0.0: buffer "^5.6.0" varint "^5.0.0" -multicoin-address-validator@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/multicoin-address-validator/-/multicoin-address-validator-0.5.2.tgz" - integrity sha512-0X0g1dhWKhtpadIe+cwTonTObw7FrHZkJVfd9yjlPFnictOrVZOaMFWLU0iV1Ok9vl4oi8H0t4OWAAMRAuYwJw== +multicoin-address-validator@0.5.12: + version "0.5.12" + resolved "https://registry.yarnpkg.com/multicoin-address-validator/-/multicoin-address-validator-0.5.12.tgz#348d549f8816cb9141c06a5e401879aabe8775d1" + integrity sha512-lL8vr/2ZYB84KkYfwuxGWFXkskTG04Np1Tq3VLnK3p1cocNH2QOC7AL+ND8GUR3Ju+yDDBw+VV20AaT2MhRLIQ== dependencies: - base-x "^3.0.8" + base-x "^3.0.9" browserify-bignum "^1.3.0-2" bundle "^2.1.0" cbor-js "^0.1.0"