diff --git a/src/client/core-api/api-client-caching.ts b/src/client/core-api/api-client-caching.ts index f7ef3307..999d7a14 100644 --- a/src/client/core-api/api-client-caching.ts +++ b/src/client/core-api/api-client-caching.ts @@ -3,6 +3,7 @@ import { ChainSymbol } from "../../chains"; import { PoolInfoMap, PoolKeyObject } from "../../tokens-info"; import { ApiClient, TokenInfo } from "./api-client"; import { + GasBalanceResponse, PendingInfoResponse, ReceiveTransactionCostRequest, ReceiveTransactionCostResponse, @@ -15,12 +16,14 @@ const _55_SECONDS_TTL = 55 * 1000; export class ApiClientCaching implements ApiClient { private tokenInfoCache: Cache>; private pendingInfoCache: Cache>; + private gasBalanceCache: Cache>; private receivedTransactionCache: Cache; constructor(private apiClient: ApiClient) { - this.tokenInfoCache = new Cache>({ defaultTtl: _55_SECONDS_TTL }); - this.receivedTransactionCache = new Cache({ defaultTtl: _20_SECONDS_TTL }); - this.pendingInfoCache = new Cache>({ defaultTtl: _20_SECONDS_TTL }); + this.tokenInfoCache = new Cache({ defaultTtl: _55_SECONDS_TTL }); + this.receivedTransactionCache = new Cache({ defaultTtl: _20_SECONDS_TTL }); + this.pendingInfoCache = new Cache({ defaultTtl: _20_SECONDS_TTL }); + this.gasBalanceCache = new Cache({ defaultTtl: _20_SECONDS_TTL }); } getTokenInfo(): Promise { @@ -34,6 +37,17 @@ export class ApiClientCaching implements ApiClient { return tokenInfoPromise; } + async getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + const GAS_BALANCE_CACHE_KEY = `GAS_BALANCE_${chainSymbol}_${address}`; + const gasBalance = this.gasBalanceCache.get(GAS_BALANCE_CACHE_KEY); + if (gasBalance) { + return gasBalance; + } + const gasBalancePromise = this.apiClient.getGasBalance(chainSymbol, address); + this.gasBalanceCache.put(GAS_BALANCE_CACHE_KEY, gasBalancePromise); + return gasBalancePromise; + } + async getPendingInfo(): Promise { const PENDING_INFO_CACHE_KEY = "PENDING_INFO_CACHE_KEY"; const pendingInfo = this.pendingInfoCache.get(PENDING_INFO_CACHE_KEY); diff --git a/src/client/core-api/api-client.ts b/src/client/core-api/api-client.ts index 4809a975..60dc1a23 100644 --- a/src/client/core-api/api-client.ts +++ b/src/client/core-api/api-client.ts @@ -9,6 +9,7 @@ import { } from "./core-api-mapper"; import { ChainDetailsResponse, + GasBalanceResponse, PendingInfoResponse, PoolInfoResponse, ReceiveTransactionCostRequest, @@ -25,6 +26,7 @@ export interface TokenInfo { export interface ApiClient { getTokenInfo(): Promise; getPendingInfo(): Promise; + getGasBalance(chainSymbol: ChainSymbol, address: string): Promise; getTransferStatus(chainSymbol: ChainSymbol, txId: string): Promise; getReceiveTransactionCost(args: ReceiveTransactionCostRequest): Promise; getPoolInfoMap(pools: PoolKeyObject[] | PoolKeyObject): Promise; @@ -58,6 +60,11 @@ export class ApiClientImpl implements ApiClient { return data; } + async getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + const { data } = await this.api.get(`/chain/${chainSymbol}/${address}`); + return data; + } + async getTransferStatus(chainSymbol: ChainSymbol, txId: string): Promise { const { data } = await this.api.get(`/chain/${chainSymbol}/${txId}`); return data; diff --git a/src/client/core-api/core-api.model.ts b/src/client/core-api/core-api.model.ts index 58cf3e6d..37e7e3c4 100644 --- a/src/client/core-api/core-api.model.ts +++ b/src/client/core-api/core-api.model.ts @@ -72,6 +72,10 @@ export interface ReceiveTransactionCostResponse { sourceNativeTokenPrice: string; } +export interface GasBalanceResponse { + gasBalance: string; +} + export interface TransferStatusResponse { txId: string; diff --git a/src/client/core-api/core-client-pool-info-caching.ts b/src/client/core-api/core-client-pool-info-caching.ts index 3c70b525..39da4357 100644 --- a/src/client/core-api/core-client-pool-info-caching.ts +++ b/src/client/core-api/core-client-pool-info-caching.ts @@ -3,6 +3,7 @@ import { ChainSymbol } from "../../chains"; import { ChainDetailsMap, PoolInfo, PoolInfoMap, PoolKeyObject, TokenWithChainDetails } from "../../tokens-info"; import { mapChainDetailsMapToPoolKeyObjects, mapPoolKeyObjectToPoolKey } from "./core-api-mapper"; import { + GasBalanceResponse, PendingInfoResponse, ReceiveTransactionCostRequest, ReceiveTransactionCostResponse, @@ -39,6 +40,10 @@ export class AllbridgeCoreClientPoolInfoCaching implements AllbridgeCoreClient { return this.client.getPendingInfo(); } + getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + return this.client.getGasBalance(chainSymbol, address); + } + async getPoolInfoByKey(poolKeyObject: PoolKeyObject): Promise { this.poolInfoCache.putAllIfNotExists((await this.client.getChainDetailsMapAndPoolInfoMap()).poolInfoMap); const poolInfo = this.poolInfoCache.get(poolKeyObject); diff --git a/src/client/core-api/index.ts b/src/client/core-api/index.ts index 5450e9bf..acd8dfc5 100644 --- a/src/client/core-api/index.ts +++ b/src/client/core-api/index.ts @@ -2,6 +2,7 @@ import { ChainSymbol } from "../../chains"; import { ChainDetailsMap, PoolInfoMap, PoolKeyObject, TokenWithChainDetails } from "../../tokens-info"; import { ApiClient } from "./api-client"; import { + GasBalanceResponse, PendingInfoResponse, ReceiveTransactionCostRequest, ReceiveTransactionCostResponse, @@ -23,6 +24,8 @@ export interface AllbridgeCoreClient { getTransferStatus(chainSymbol: ChainSymbol, txId: string): Promise; getReceiveTransactionCost(args: ReceiveTransactionCostRequest): Promise; + + getGasBalance(chainSymbol: ChainSymbol, address: string): Promise; } export class AllbridgeCoreClientImpl implements AllbridgeCoreClient { @@ -41,6 +44,10 @@ export class AllbridgeCoreClientImpl implements AllbridgeCoreClient { return this.apiClient.getPendingInfo(); } + async getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + return this.apiClient.getGasBalance(chainSymbol, address); + } + async getChainDetailsMapAndPoolInfoMap(): Promise<{ chainDetailsMap: ChainDetailsMap; poolInfoMap: PoolInfoMap; diff --git a/src/index.ts b/src/index.ts index b30b354f..f9769f25 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,7 @@ import { SwapAndBridgeCalculationData, TokenWithChainDetails, TransferStatusResponse, + GasBalanceResponse, } from "./models"; import { AllbridgeCoreSdkService, NodeRpcUrlsConfig } from "./services"; import { DefaultUtils, Utils } from "./utils"; @@ -125,6 +126,15 @@ export class AllbridgeCoreSdk { return this.service.getTransferStatus(chainSymbol, txId); } + /** + * Get gas balance + * @param chainSymbol + * @param address + */ + async getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + return this.service.getGasBalance(chainSymbol, address); + } + /** * Returns information about pending transactions for the same destination chain and the amount of tokens can be received as a result of transfer considering pending transactions. * @param amount the amount of tokens that will be sent diff --git a/src/models/index.ts b/src/models/index.ts index ef1f1961..e0fdf6d5 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -11,7 +11,12 @@ export { export { BridgeService } from "../services/bridge/index"; export { LiquidityPoolService } from "../services/liquidity-pool/index"; export { TransactionResponse } from "../services/models/index"; -export { Messenger, TransferStatusResponse, BridgeTransaction } from "../client/core-api/core-api.model"; +export { + Messenger, + TransferStatusResponse, + BridgeTransaction, + GasBalanceResponse, +} from "../client/core-api/core-api.model"; export { ChainSymbol, ChainType } from "../chains/index"; export { RawBridgeTransactionBuilder } from "../services/bridge/raw-bridge-transaction-builder"; export { RawPoolTransactionBuilder } from "../services/liquidity-pool/raw-pool-transaction-builder"; diff --git a/src/services/index.ts b/src/services/index.ts index 4bb22595..928aa7fb 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -3,7 +3,12 @@ import { ChainSymbol } from "../chains"; import { AllbridgeCoreClientImpl } from "../client/core-api"; import { ApiClientImpl } from "../client/core-api/api-client"; import { ApiClientCaching } from "../client/core-api/api-client-caching"; -import { Messenger, PendingInfoDTO, TransferStatusResponse } from "../client/core-api/core-api.model"; +import { + GasBalanceResponse, + Messenger, + PendingInfoDTO, + TransferStatusResponse, +} from "../client/core-api/core-api.model"; import { AllbridgeCoreClientPoolInfoCaching } from "../client/core-api/core-client-pool-info-caching"; import { mainnet } from "../configs"; import { AllbridgeCoreSdkOptions, NodeRpcUrls } from "../index"; @@ -75,8 +80,8 @@ export class AllbridgeCoreSdkService { constructor(nodeRpcUrlsConfig: NodeRpcUrlsConfig, params: AllbridgeCoreSdkOptions = mainnet) { const apiClient = new ApiClientImpl(params); - const apiClientTokenInfoCaching = new ApiClientCaching(apiClient); - const coreClient = new AllbridgeCoreClientImpl(apiClientTokenInfoCaching); + const apiClientCaching = new ApiClientCaching(apiClient); + const coreClient = new AllbridgeCoreClientImpl(apiClientCaching); this.api = new AllbridgeCoreClientPoolInfoCaching(coreClient); const solBridgeParams: SolanaBridgeParams = { @@ -106,6 +111,10 @@ export class AllbridgeCoreSdkService { return this.api.getTransferStatus(chainSymbol, txId); } + async getGasBalance(chainSymbol: ChainSymbol, address: string): Promise { + return this.api.getGasBalance(chainSymbol, address); + } + async getPendingStatusInfo( amount: string, amountFormat: AmountFormat,