From 062c28ff4e318a30762755d9ef11229a2c8557ad Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 19 Nov 2024 15:44:05 +0300 Subject: [PATCH 1/3] fix solana rpc --- package.json | 2 +- .../web3-public-service/constants/rpc-errors.ts | 3 ++- .../solana-web3-public/solana-web3-public.ts | 11 ++++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0c0c38b5ae..7e597261d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.45.0", + "version": "5.45.2-alpha-solana-rpc-fix.2", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/core/blockchain/web3-public-service/constants/rpc-errors.ts b/src/core/blockchain/web3-public-service/constants/rpc-errors.ts index b35827d7f8..14eca1b4f8 100644 --- a/src/core/blockchain/web3-public-service/constants/rpc-errors.ts +++ b/src/core/blockchain/web3-public-service/constants/rpc-errors.ts @@ -8,5 +8,6 @@ export const rpcErrors = [ 'your account has been suspended', 'too many requests, we recommend you to use free api key', 'origin not allowed', - 'api key disabled' + 'api key disabled', + 'access forbidden' ]; diff --git a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts index 427aceee21..c4f7d6e671 100644 --- a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts +++ b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts @@ -13,6 +13,7 @@ import { NATIVE_SOLANA_MINT_ADDRESS } from 'src/core/blockchain/constants/solana import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; import { ReturnValue } from 'src/core/blockchain/models/solana-web3-types'; import { Web3PrimitiveType } from 'src/core/blockchain/models/web3-primitive-type'; +import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { ContractMulticallResponse } from 'src/core/blockchain/web3-public-service/web3-public/models/contract-multicall-response'; import { MethodData } from 'src/core/blockchain/web3-public-service/web3-public/models/method-data'; import { SupportedTokenField } from 'src/core/blockchain/web3-public-service/web3-public/models/supported-token-field'; @@ -77,7 +78,15 @@ export class SolanaWeb3Public extends Web3Public { ); const mints = filteredTokenAddresses.map(address => new PublicKey(address)); - const tokenSdk = new TokenSdk(); + const tokenSdk = new TokenSdk({ + chainId: 101, + connection: this.connection, + apiUrl: 'https://token-list-api.solana.cloud', + cdnUrl: 'https://cdn.jsdelivr.net/gh/solflare-wallet/token-list/solana-tokenlist.json', + metaplexTimeout: 5000, + timeout: 5000 + }); + const tokensMint = await tokenSdk.fetchMints(mints); const tokens = tokensMint.map(token => { From 701f2afa9fe196d8b90830ebc6c593b356fd53a0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 20 Nov 2024 12:36:59 +0300 Subject: [PATCH 2/3] implement custom fetchMints method --- .../solana-web3-public/models/solana-token.ts | 9 ++++ .../services/solana-tokens-api-service.ts | 21 ++++++++++ .../solana-web3-public/solana-web3-public.ts | 42 ++++++++++++++----- 3 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 src/core/blockchain/web3-public-service/web3-public/solana-web3-public/models/solana-token.ts create mode 100644 src/core/blockchain/web3-public-service/web3-public/solana-web3-public/services/solana-tokens-api-service.ts diff --git a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/models/solana-token.ts b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/models/solana-token.ts new file mode 100644 index 0000000000..77c06cd06e --- /dev/null +++ b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/models/solana-token.ts @@ -0,0 +1,9 @@ +export interface SolanaToken { + name: string; + symbol: string; + logoURI: string | null; + verified?: boolean; + address: string; + decimals: number | null; + holders?: number | null; +} diff --git a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/services/solana-tokens-api-service.ts b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/services/solana-tokens-api-service.ts new file mode 100644 index 0000000000..379f52ebfc --- /dev/null +++ b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/services/solana-tokens-api-service.ts @@ -0,0 +1,21 @@ +import { Injector } from 'src/core/injector/injector'; + +import { SolanaToken } from '../models/solana-token'; + +export class SolanaTokensApiService { + private static readonly apiEndpoint = 'https://x-api.rubic.exchange/sol_token_list'; + + private static readonly xApiKey = 'sndfje3u4b3fnNSDNFUSDNVSunw345842hrnfd3b4nt4'; + + public static getTokensList(tokenAddresses: string[]): Promise<{ content: SolanaToken[] }> { + return Injector.httpClient.post( + `${this.apiEndpoint}/v1/mints?chainId=101`, + { addresses: tokenAddresses }, + { + headers: { + apiKey: this.xApiKey + } + } + ); + } +} diff --git a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts index c4f7d6e671..0a23110cec 100644 --- a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts +++ b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts @@ -4,16 +4,16 @@ import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { BlockhashWithExpiryBlockHeight, Connection, PublicKey } from '@solana/web3.js'; -import { Client as TokenSdk } from '@solflare-wallet/utl-sdk'; +import { Client as TokenSdk, UtlConfig } from '@solflare-wallet/utl-sdk'; import BigNumber from 'bignumber.js'; import { catchError, firstValueFrom, from, map, of, timeout } from 'rxjs'; import { nativeTokensList } from 'src/common/tokens/constants/native-tokens'; +import { compareAddresses } from 'src/common/utils/blockchain'; import { Cache } from 'src/common/utils/decorators'; import { NATIVE_SOLANA_MINT_ADDRESS } from 'src/core/blockchain/constants/solana/native-solana-mint-address'; import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; import { ReturnValue } from 'src/core/blockchain/models/solana-web3-types'; import { Web3PrimitiveType } from 'src/core/blockchain/models/web3-primitive-type'; -import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { ContractMulticallResponse } from 'src/core/blockchain/web3-public-service/web3-public/models/contract-multicall-response'; import { MethodData } from 'src/core/blockchain/web3-public-service/web3-public/models/method-data'; import { SupportedTokenField } from 'src/core/blockchain/web3-public-service/web3-public/models/supported-token-field'; @@ -25,6 +25,8 @@ import { Web3Public } from 'src/core/blockchain/web3-public-service/web3-public/ import { SolanaWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/solana-web3-pure/solana-web3-pure'; import { AbiItem } from 'web3-utils'; +import { SolanaToken } from './models/solana-token'; +import { SolanaTokensApiService } from './services/solana-tokens-api-service'; /** * Class containing methods for calling contracts in order to obtain information from the blockchain. * To send transaction or execute contract method use {@link Web3Private}. @@ -78,16 +80,8 @@ export class SolanaWeb3Public extends Web3Public { ); const mints = filteredTokenAddresses.map(address => new PublicKey(address)); - const tokenSdk = new TokenSdk({ - chainId: 101, - connection: this.connection, - apiUrl: 'https://token-list-api.solana.cloud', - cdnUrl: 'https://cdn.jsdelivr.net/gh/solflare-wallet/token-list/solana-tokenlist.json', - metaplexTimeout: 5000, - timeout: 5000 - }); - const tokensMint = await tokenSdk.fetchMints(mints); + const tokensMint = await this.fetchMints(mints); const tokens = tokensMint.map(token => { const entries = tokenFields.map(field => [field, token?.[field]]); @@ -140,6 +134,32 @@ export class SolanaWeb3Public extends Web3Public { throw new Error('Method call is not supported'); } + private async fetchMints(mints: PublicKey[]): Promise { + const tokensAddresses = mints.map(mint => mint.toString()); + + let tokensList: SolanaToken[] = []; + + try { + const { content } = await SolanaTokensApiService.getTokensList(tokensAddresses); + tokensList = content; + } catch {} + + const tokensNotFetched = mints.filter(mint => + tokensList.some(token => !compareAddresses(token.address, mint.toString())) + ); + + const config = new UtlConfig({ + connection: this.connection, + timeout: 5000 + }); + + const tokenSDK = new TokenSdk(config); + + const metaplexTokens = await tokenSDK.getFromMetaplex(tokensNotFetched); + + return [...tokensList, ...metaplexTokens]; + } + public healthCheck(timeoutMs: number = 4000): Promise { const request = this.connection.getBalanceAndContext( new PublicKey('DVLwQbEaw5txuduQwvfbNP3sXvjawHqaoMuGMKZx15bQ'), From be510015713aaede336280932f644d5f2bb6fe37 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 20 Nov 2024 13:03:40 +0300 Subject: [PATCH 3/3] set sdk release version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7e597261d5..53026462df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.45.2-alpha-solana-rpc-fix.2", + "version": "5.45.3", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts",