@swapkit/toolboxes 0.0.0-nightly-20250304130539

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/chunk-fazw0jvt.js +3 -0
  2. package/dist/chunk-fazw0jvt.js.map +9 -0
  3. package/dist/chunk-tvrdndbw.js +4 -0
  4. package/dist/chunk-tvrdndbw.js.map +9 -0
  5. package/dist/cosmos/index.cjs +3 -0
  6. package/dist/cosmos/index.cjs.map +19 -0
  7. package/dist/cosmos/index.js +3 -0
  8. package/dist/cosmos/index.js.map +19 -0
  9. package/dist/evm/index.cjs +3 -0
  10. package/dist/evm/index.cjs.map +18 -0
  11. package/dist/evm/index.js +3 -0
  12. package/dist/evm/index.js.map +18 -0
  13. package/dist/index.cjs +3 -0
  14. package/dist/index.cjs.map +9 -0
  15. package/dist/index.js +3 -0
  16. package/dist/index.js.map +9 -0
  17. package/dist/radix/index.cjs +3 -0
  18. package/dist/radix/index.cjs.map +10 -0
  19. package/dist/radix/index.js +3 -0
  20. package/dist/radix/index.js.map +10 -0
  21. package/dist/solana/index.cjs +3 -0
  22. package/dist/solana/index.cjs.map +10 -0
  23. package/dist/solana/index.js +3 -0
  24. package/dist/solana/index.js.map +10 -0
  25. package/dist/substrate/index.cjs +3 -0
  26. package/dist/substrate/index.cjs.map +12 -0
  27. package/dist/substrate/index.js +3 -0
  28. package/dist/substrate/index.js.map +12 -0
  29. package/dist/utxo/index.cjs +3 -0
  30. package/dist/utxo/index.cjs.map +17 -0
  31. package/dist/utxo/index.js +3 -0
  32. package/dist/utxo/index.js.map +17 -0
  33. package/package.json +102 -0
  34. package/src/cosmos/index.ts +8 -0
  35. package/src/cosmos/thorchainUtils/addressFormat.ts +23 -0
  36. package/src/cosmos/thorchainUtils/index.ts +4 -0
  37. package/src/cosmos/thorchainUtils/messages.ts +244 -0
  38. package/src/cosmos/thorchainUtils/registry.ts +47 -0
  39. package/src/cosmos/thorchainUtils/types/client-types.ts +79 -0
  40. package/src/cosmos/thorchainUtils/types/index.ts +1 -0
  41. package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.js +2806 -0
  42. package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.ts +2802 -0
  43. package/src/cosmos/thorchainUtils/util.ts +46 -0
  44. package/src/cosmos/toolbox/BaseCosmosToolbox.ts +257 -0
  45. package/src/cosmos/toolbox/gaia.ts +39 -0
  46. package/src/cosmos/toolbox/getToolboxByChain.ts +29 -0
  47. package/src/cosmos/toolbox/kujira.ts +61 -0
  48. package/src/cosmos/toolbox/thorchain.ts +305 -0
  49. package/src/cosmos/types.ts +42 -0
  50. package/src/cosmos/util.ts +230 -0
  51. package/src/evm/__tests__/ethereum.test.ts +147 -0
  52. package/src/evm/api.ts +157 -0
  53. package/src/evm/contracts/eth/multicall.ts +165 -0
  54. package/src/evm/contracts/op/gasOracle.ts +151 -0
  55. package/src/evm/helpers.ts +213 -0
  56. package/src/evm/index.ts +15 -0
  57. package/src/evm/toolbox/baseEVMToolbox.ts +670 -0
  58. package/src/evm/toolbox/evm.ts +89 -0
  59. package/src/evm/toolbox/getToolboxByChain.ts +37 -0
  60. package/src/evm/toolbox/op.ts +152 -0
  61. package/src/evm/types.ts +110 -0
  62. package/src/index.ts +0 -0
  63. package/src/radix/index.ts +151 -0
  64. package/src/radix/toolbox.ts +693 -0
  65. package/src/solana/index.ts +49 -0
  66. package/src/solana/toolbox.ts +271 -0
  67. package/src/substrate/index.ts +3 -0
  68. package/src/substrate/toolbox/baseSubstrateToolbox.ts +288 -0
  69. package/src/substrate/toolbox/index.ts +40 -0
  70. package/src/substrate/types/index.ts +2 -0
  71. package/src/substrate/types/network.ts +42 -0
  72. package/src/substrate/types/wallet.ts +78 -0
  73. package/src/utxo/helpers/api.ts +431 -0
  74. package/src/utxo/helpers/bchaddrjs.ts +177 -0
  75. package/src/utxo/helpers/coinselect.ts +96 -0
  76. package/src/utxo/helpers/index.ts +5 -0
  77. package/src/utxo/helpers/txSize.ts +103 -0
  78. package/src/utxo/helpers/utils.ts +48 -0
  79. package/src/utxo/index.ts +7 -0
  80. package/src/utxo/toolbox/bitcoinCash.ts +268 -0
  81. package/src/utxo/toolbox/index.ts +41 -0
  82. package/src/utxo/toolbox/utxo.ts +372 -0
  83. package/src/utxo/types.ts +51 -0
@@ -0,0 +1,89 @@
1
+ import { Chain, type EVMChain, FeeOption } from "@swapkit/helpers";
2
+ import type { BrowserProvider, JsonRpcProvider, Signer } from "ethers";
3
+ import { multicallAbi } from "../contracts/eth/multicall";
4
+ import {
5
+ getBalance,
6
+ getEstimateTransactionFee,
7
+ getIsEIP1559Compatible,
8
+ getNetworkParams,
9
+ } from "../helpers";
10
+ import { BaseEVMToolbox } from "./baseEVMToolbox";
11
+
12
+ export function ETHToolbox<P extends JsonRpcProvider | BrowserProvider, S extends Signer>({
13
+ provider,
14
+ signer,
15
+ }: { signer?: S; provider: P }) {
16
+ const evmToolbox = createEvmToolbox(Chain.Ethereum)({
17
+ provider,
18
+ signer,
19
+ });
20
+ async function multicall(
21
+ callTuples: { address: string; data: string }[],
22
+ multicallAddress = "0x5ba1e12693dc8f9c48aad8770482f4739beed696",
23
+ funcName = "aggregate",
24
+ feeOptionKey: FeeOption = FeeOption.Fast,
25
+ ) {
26
+ const txObject = await evmToolbox.createContractTxObject({
27
+ contractAddress: multicallAddress,
28
+ abi: multicallAbi,
29
+ funcName,
30
+ funcParams: [callTuples],
31
+ });
32
+
33
+ return evmToolbox.sendTransaction({ ...txObject, feeOptionKey });
34
+ }
35
+
36
+ return { ...evmToolbox, multicall };
37
+ }
38
+
39
+ export function ARBToolbox<P extends JsonRpcProvider | BrowserProvider, S extends Signer>({
40
+ provider,
41
+ signer,
42
+ }: { signer?: S; provider: P }) {
43
+ const { estimateGasPrices: _, ...evmToolbox } = createEvmToolbox(Chain.Arbitrum)({
44
+ provider,
45
+ signer,
46
+ });
47
+
48
+ async function estimateGasPrices() {
49
+ try {
50
+ const { gasPrice } = await provider.getFeeData();
51
+
52
+ if (!gasPrice) throw new Error("No fee data available");
53
+
54
+ return {
55
+ [FeeOption.Average]: { gasPrice },
56
+ [FeeOption.Fast]: { gasPrice },
57
+ [FeeOption.Fastest]: { gasPrice },
58
+ };
59
+ } catch (error) {
60
+ throw new Error(
61
+ `Failed to estimate gas price: ${(error as any).msg ?? (error as any).toString()}`,
62
+ );
63
+ }
64
+ }
65
+
66
+ return { ...evmToolbox, estimateGasPrices };
67
+ }
68
+
69
+ export const AVAXToolbox = createEvmToolbox(Chain.Avalanche);
70
+ export const BASEToolbox = createEvmToolbox(Chain.Base);
71
+ export const BSCToolbox = createEvmToolbox(Chain.BinanceSmartChain);
72
+ export const MATICToolbox = createEvmToolbox(Chain.Polygon);
73
+
74
+ function createEvmToolbox<C extends EVMChain>(chain: C) {
75
+ return function createEvmToolbox<P extends JsonRpcProvider | BrowserProvider, S extends Signer>({
76
+ provider,
77
+ signer,
78
+ }: { provider: P; signer?: S }) {
79
+ const isEIP1559Compatible = getIsEIP1559Compatible(chain);
80
+ const evmToolbox = BaseEVMToolbox({ provider, signer, isEIP1559Compatible });
81
+
82
+ return {
83
+ ...evmToolbox,
84
+ estimateTransactionFee: getEstimateTransactionFee({ provider, isEIP1559Compatible }),
85
+ getNetworkParams: getNetworkParams(chain),
86
+ getBalance: getBalance({ provider, chain }),
87
+ };
88
+ };
89
+ }
@@ -0,0 +1,37 @@
1
+ import { Chain } from "@swapkit/helpers";
2
+
3
+ import { ARBToolbox, AVAXToolbox, BASEToolbox, BSCToolbox, ETHToolbox, MATICToolbox } from "./evm";
4
+ import { OPToolbox } from "./op";
5
+
6
+ type ToolboxType = {
7
+ ARB: typeof ARBToolbox;
8
+ AVAX: typeof AVAXToolbox;
9
+ BASE: typeof BASEToolbox;
10
+ BSC: typeof BSCToolbox;
11
+ ETH: typeof ETHToolbox;
12
+ MATIC: typeof MATICToolbox;
13
+ OP: typeof OPToolbox;
14
+ };
15
+
16
+ export const getToolboxByChain = <T extends keyof ToolboxType>(chain: T): ToolboxType[T] => {
17
+ switch (chain) {
18
+ case Chain.Avalanche:
19
+ return AVAXToolbox as ToolboxType[T];
20
+ case Chain.Arbitrum:
21
+ return ARBToolbox as ToolboxType[T];
22
+ case Chain.Base:
23
+ return BASEToolbox as ToolboxType[T];
24
+ case Chain.Optimism:
25
+ return OPToolbox as ToolboxType[T];
26
+ case Chain.Polygon:
27
+ return MATICToolbox as ToolboxType[T];
28
+ case Chain.BinanceSmartChain:
29
+ return BSCToolbox as ToolboxType[T];
30
+ case Chain.Ethereum:
31
+ return ETHToolbox as ToolboxType[T];
32
+ default:
33
+ throw new Error(`Chain ${chain} is not supported`);
34
+ }
35
+ };
36
+
37
+ export { evmValidateAddress } from "./baseEVMToolbox";
@@ -0,0 +1,152 @@
1
+ import {
2
+ BaseDecimal,
3
+ Chain,
4
+ ChainId,
5
+ ChainToExplorerUrl,
6
+ FeeOption,
7
+ SKConfig,
8
+ } from "@swapkit/helpers";
9
+ import type { BrowserProvider, JsonRpcProvider, Signer, TransactionRequest } from "ethers";
10
+ import { Contract } from "ethers";
11
+
12
+ import { gasOracleAbi } from "../contracts/op/gasOracle";
13
+ import { getBalance } from "../helpers";
14
+ import { BaseEVMToolbox } from "./baseEVMToolbox";
15
+
16
+ const GAS_PRICE_ORACLE_ADDRESS = "0x420000000000000000000000000000000000000f";
17
+
18
+ function connectGasPriceOracle<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
19
+ return new Contract(GAS_PRICE_ORACLE_ADDRESS, gasOracleAbi, provider);
20
+ }
21
+
22
+ function getL1GasPriceFetcher<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
23
+ return function getL1GasPrice() {
24
+ const gasPriceOracle = connectGasPriceOracle(provider);
25
+
26
+ if (gasPriceOracle && "l1BaseFee" in gasPriceOracle) {
27
+ return gasPriceOracle?.l1BaseFee() as unknown as bigint;
28
+ }
29
+
30
+ return undefined;
31
+ };
32
+ }
33
+
34
+ function serializeTx<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
35
+ return async function serializeTx({ from, to, nonce, ...tx }: TransactionRequest) {
36
+ const { Transaction } = await import("ethers");
37
+
38
+ if (!to) throw new Error("Missing to address");
39
+ const txParams = {
40
+ ...tx,
41
+ to: to as string,
42
+ nonce: nonce ? nonce : from ? await provider.getTransactionCount(from) : 0,
43
+ };
44
+
45
+ return Transaction.from(txParams).serialized;
46
+ };
47
+ }
48
+
49
+ function estimateL1GasCost<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
50
+ return async function estimateL1GasCost(tx: TransactionRequest) {
51
+ const gasPriceOracle = connectGasPriceOracle(provider);
52
+ const serializedTx = await serializeTx(provider)(tx);
53
+
54
+ if (gasPriceOracle && "getL1Fee" in gasPriceOracle) {
55
+ return gasPriceOracle.getL1Fee(serializedTx);
56
+ }
57
+ };
58
+ }
59
+
60
+ function estimateL2GasCost<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
61
+ return async function estimateL2GasCost(tx: TransactionRequest) {
62
+ const l2GasPrice = await provider.send("eth_gasPrice", []);
63
+ const l2GasCost = await provider.estimateGas(tx);
64
+ return l2GasPrice.mul(l2GasCost);
65
+ };
66
+ }
67
+
68
+ function estimateTotalGasCost<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
69
+ return async function estimateTotalGasCost(tx: TransactionRequest) {
70
+ const l1GasCost = await estimateL1GasCost(provider)(tx);
71
+ const l2GasCost = await estimateL2GasCost(provider)(tx);
72
+ return l1GasCost.add(l2GasCost);
73
+ };
74
+ }
75
+
76
+ export function estimateL1Gas<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
77
+ return async function estimateL1Gas(tx: TransactionRequest) {
78
+ const gasPriceOracle = connectGasPriceOracle(provider);
79
+ const serializedTx = await serializeTx(provider)(tx);
80
+
81
+ if (gasPriceOracle && "getL1GasUsed" in gasPriceOracle) {
82
+ return gasPriceOracle.getL1GasUsed(serializedTx);
83
+ }
84
+ };
85
+ }
86
+
87
+ const getNetworkParams = () => ({
88
+ chainId: ChainId.OptimismHex,
89
+ chainName: "Optimism",
90
+ nativeCurrency: { name: "Ethereum", symbol: Chain.Ethereum, decimals: BaseDecimal.ETH },
91
+ rpcUrls: [SKConfig.get("rpcUrls")[Chain.Optimism]],
92
+ blockExplorerUrls: [ChainToExplorerUrl[Chain.Optimism]],
93
+ });
94
+
95
+ function estimateGasPrices<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
96
+ return async function estimateGasPrices() {
97
+ try {
98
+ const { maxFeePerGas, maxPriorityFeePerGas, gasPrice } = await provider.getFeeData();
99
+ const l1GasPrice = getL1GasPriceFetcher(provider)();
100
+ const price = gasPrice as bigint;
101
+
102
+ if (!(maxFeePerGas && maxPriorityFeePerGas)) {
103
+ throw new Error("No fee data available");
104
+ }
105
+
106
+ return {
107
+ [FeeOption.Average]: {
108
+ l1GasPrice,
109
+ gasPrice,
110
+ maxFeePerGas,
111
+ maxPriorityFeePerGas,
112
+ },
113
+ [FeeOption.Fast]: {
114
+ l1GasPrice: ((l1GasPrice || 0n) * 15n) / 10n,
115
+ gasPrice: (price * 15n) / 10n,
116
+ maxFeePerGas,
117
+ maxPriorityFeePerGas: (maxPriorityFeePerGas * 15n) / 10n,
118
+ },
119
+ [FeeOption.Fastest]: {
120
+ l1GasPrice: (l1GasPrice || 0n) * 2n,
121
+ gasPrice: price * 2n,
122
+ maxFeePerGas,
123
+ maxPriorityFeePerGas: maxPriorityFeePerGas * 2n,
124
+ },
125
+ };
126
+ } catch (error) {
127
+ throw new Error(
128
+ `Failed to estimate gas price: ${(error as any).msg ?? (error as any).toString()}`,
129
+ );
130
+ }
131
+ };
132
+ }
133
+
134
+ export function OPToolbox<P extends JsonRpcProvider | BrowserProvider, S extends Signer>({
135
+ provider,
136
+ signer,
137
+ }: { signer?: S; provider: P }) {
138
+ const evmToolbox = BaseEVMToolbox({ provider, signer });
139
+ const getL1GasPrice = getL1GasPriceFetcher(provider);
140
+
141
+ return {
142
+ ...evmToolbox,
143
+ estimateGasPrices: estimateGasPrices(provider),
144
+ estimateL1Gas: estimateL1Gas(provider),
145
+ estimateL1GasCost: estimateL1GasCost(provider),
146
+ estimateL2GasCost: estimateL2GasCost(provider),
147
+ estimateTotalGasCost: estimateTotalGasCost(provider),
148
+ getBalance: getBalance({ provider, chain: Chain.Optimism }),
149
+ getL1GasPrice,
150
+ getNetworkParams,
151
+ };
152
+ }
@@ -0,0 +1,110 @@
1
+ import type { AssetValue, FeeOption, WalletTxParams } from "@swapkit/helpers";
2
+ import type { BigNumberish, JsonFragment, Transaction } from "ethers";
3
+
4
+ import type {
5
+ ARBToolbox,
6
+ AVAXToolbox,
7
+ BASEToolbox,
8
+ BSCToolbox,
9
+ ETHToolbox,
10
+ MATICToolbox,
11
+ OPToolbox,
12
+ getProvider,
13
+ } from "./index";
14
+
15
+ export enum EthNetwork {
16
+ Test = "goerli",
17
+ Main = "homestead",
18
+ }
19
+
20
+ export type ApproveParams = {
21
+ assetAddress: string;
22
+ spenderAddress: string;
23
+ feeOptionKey?: FeeOption;
24
+ amount?: BigNumberish;
25
+ from: string;
26
+ // Optional fallback in case estimation for gas limit fails
27
+ gasLimitFallback?: BigNumberish;
28
+ nonce?: number;
29
+ };
30
+
31
+ export type ApprovedParams = {
32
+ assetAddress: string;
33
+ spenderAddress: string;
34
+ from: string;
35
+ };
36
+
37
+ export type IsApprovedParams = ApprovedParams & {
38
+ amount?: BigNumberish;
39
+ };
40
+
41
+ export type CallParams = {
42
+ callProvider?: ReturnType<typeof getProvider>;
43
+ contractAddress: string;
44
+ abi: readonly JsonFragment[];
45
+ funcName: string;
46
+ funcParams?: unknown[];
47
+ txOverrides?: Partial<Transaction>;
48
+ feeOption?: FeeOption;
49
+ };
50
+
51
+ export type EstimateCallParams = Pick<
52
+ CallParams,
53
+ "contractAddress" | "abi" | "funcName" | "funcParams" | "txOverrides"
54
+ >;
55
+
56
+ export type TransferParams = WalletTxParams & {
57
+ gasLimit?: bigint;
58
+ gasPrice?: bigint;
59
+ maxFeePerGas?: bigint;
60
+ maxPriorityFeePerGas?: bigint;
61
+ data?: string;
62
+ from: string;
63
+ nonce?: number;
64
+ assetValue: AssetValue;
65
+ };
66
+
67
+ export type BaseEVMToolboxType = ReturnType<
68
+ | typeof ARBToolbox
69
+ | typeof AVAXToolbox
70
+ | typeof BASEToolbox
71
+ | typeof BSCToolbox
72
+ | typeof ETHToolbox
73
+ | typeof MATICToolbox
74
+ | typeof OPToolbox
75
+ >;
76
+
77
+ export type EVMMaxSendableAmountsParams = {
78
+ from: string;
79
+ toolbox: BaseEVMToolboxType;
80
+ assetValue: AssetValue;
81
+ feeOptionKey?: FeeOption;
82
+ memo?: string;
83
+ abi?: readonly JsonFragment[];
84
+ funcName?: string;
85
+ contractAddress?: string;
86
+ funcParams?: unknown[];
87
+ txOverrides?: Partial<Transaction>;
88
+ };
89
+
90
+ export type EVMTxBaseParams<T = bigint> = {
91
+ to?: string;
92
+ from?: string;
93
+ nonce?: number;
94
+ gasLimit?: T;
95
+ data?: string;
96
+ value?: T;
97
+ chainId?: T;
98
+ };
99
+
100
+ export type EIP1559TxParams<T = bigint> = EVMTxBaseParams<T> & {
101
+ type?: number;
102
+ maxFeePerGas?: T;
103
+ maxPriorityFeePerGas?: T;
104
+ };
105
+
106
+ export type LegacyEVMTxParams<T = bigint> = EVMTxBaseParams<T> & {
107
+ gasPrice?: T;
108
+ };
109
+
110
+ export type EVMTxParams = EIP1559TxParams | LegacyEVMTxParams;
package/src/index.ts ADDED
File without changes
@@ -0,0 +1,151 @@
1
+ import type {
2
+ FungibleResourcesCollectionItem,
3
+ GatewayApiClient,
4
+ StateEntityDetailsVaultResponseItem,
5
+ StateEntityFungiblesPageRequest,
6
+ StateEntityFungiblesPageResponse,
7
+ } from "@radixdlt/babylon-gateway-api-sdk";
8
+ import { AssetValue, Chain, type SKConfigIntegrations } from "@swapkit/helpers";
9
+
10
+ export type RadixWallets = {
11
+ [Chain.Radix]: Awaited<ReturnType<typeof RadixToolbox>>;
12
+ };
13
+
14
+ type RadixGetBalanceParams = {
15
+ address: string;
16
+ networkApi: GatewayApiClient;
17
+ };
18
+ // Could not find anything sync in SDK, ask Radix team
19
+ export function validateAddress(address: string) {
20
+ return address.startsWith("account_rdx1") && address.length === 66;
21
+ }
22
+
23
+ function getBalance({ networkApi }: { networkApi: GatewayApiClient }) {
24
+ return async function getBalance(address: string) {
25
+ const fungibleResources = await fetchFungibleResources({ address, networkApi });
26
+ const fungibleBalances = convertResourcesToBalances({
27
+ resources: fungibleResources,
28
+ networkApi,
29
+ });
30
+ return fungibleBalances;
31
+ };
32
+ }
33
+
34
+ async function fetchFungibleResources({
35
+ address,
36
+ networkApi,
37
+ }: RadixGetBalanceParams): Promise<FungibleResourcesCollectionItem[]> {
38
+ let hasNextPage = true;
39
+ let nextCursor: string | undefined;
40
+ let fungibleResources: FungibleResourcesCollectionItem[] = [];
41
+ const stateVersion = await currentStateVersion(networkApi);
42
+ while (hasNextPage) {
43
+ const stateEntityFungiblesPageRequest: StateEntityFungiblesPageRequest = {
44
+ address: address,
45
+ limit_per_page: 100,
46
+ cursor: nextCursor,
47
+ at_ledger_state: {
48
+ state_version: stateVersion,
49
+ },
50
+ };
51
+
52
+ const stateEntityFungiblesPageResponse: StateEntityFungiblesPageResponse =
53
+ await networkApi.state.innerClient.entityFungiblesPage({
54
+ stateEntityFungiblesPageRequest: stateEntityFungiblesPageRequest,
55
+ });
56
+
57
+ fungibleResources = fungibleResources.concat(stateEntityFungiblesPageResponse.items);
58
+ if (stateEntityFungiblesPageResponse.next_cursor) {
59
+ nextCursor = stateEntityFungiblesPageResponse.next_cursor;
60
+ } else {
61
+ hasNextPage = false;
62
+ }
63
+ }
64
+ return fungibleResources;
65
+ }
66
+
67
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
68
+ async function convertResourcesToBalances({
69
+ resources,
70
+ networkApi,
71
+ }: {
72
+ resources: FungibleResourcesCollectionItem[]; //| NonFungibleResourcesCollectionItem[];
73
+ networkApi: GatewayApiClient;
74
+ }): Promise<AssetValue[]> {
75
+ const balances: AssetValue[] = [];
76
+ const BATCH_SIZE = 50;
77
+
78
+ // Split resources into batches of up to 50 items
79
+ const resourceBatches: FungibleResourcesCollectionItem[][] = [];
80
+ for (let i = 0; i < resources.length; i += BATCH_SIZE) {
81
+ resourceBatches.push(resources.slice(i, i + BATCH_SIZE));
82
+ }
83
+
84
+ for (const batch of resourceBatches) {
85
+ const addresses = batch.map((item) => item.resource_address);
86
+ const response: StateEntityDetailsVaultResponseItem[] =
87
+ await networkApi.state.getEntityDetailsVaultAggregated(addresses);
88
+
89
+ const divisibilities = new Map<string, { decimals: number; symbol: string }>();
90
+
91
+ for (const result of response) {
92
+ if (result.details !== undefined) {
93
+ const metaDataSymbol = result.metadata?.items.find((item) => item.key === "symbol");
94
+ const symbol =
95
+ metaDataSymbol?.value.typed.type === "String" ? metaDataSymbol.value.typed.value : "?";
96
+
97
+ if (result.details.type === "FungibleResource") {
98
+ divisibilities.set(result.address, {
99
+ decimals: result.details.divisibility,
100
+ symbol,
101
+ });
102
+ }
103
+ }
104
+ }
105
+
106
+ for (const item of batch) {
107
+ if (item.aggregation_level === "Global") {
108
+ const assetInfo = divisibilities.get(item.resource_address) || { decimals: 0, symbol: "?" };
109
+
110
+ const balance = AssetValue.from({
111
+ asset:
112
+ assetInfo.symbol !== Chain.Radix
113
+ ? `${Chain.Radix}.${assetInfo.symbol}-${item.resource_address}`
114
+ : "XRD.XRD",
115
+ value: item.amount,
116
+ });
117
+ balances.push(balance);
118
+ }
119
+ }
120
+ }
121
+
122
+ return balances;
123
+ }
124
+
125
+ async function currentStateVersion(networkApi: GatewayApiClient) {
126
+ return networkApi.status.getCurrent().then((status) => status.ledger_state.state_version);
127
+ }
128
+
129
+ export const RadixToolbox = async ({
130
+ dappConfig,
131
+ }: { dappConfig: SKConfigIntegrations["radix"] }) => {
132
+ const { RadixDappToolkit } = await import("@radixdlt/radix-dapp-toolkit");
133
+ const { GatewayApiClient } = await import("@radixdlt/babylon-gateway-api-sdk");
134
+
135
+ const radixToolkit = RadixDappToolkit({
136
+ ...dappConfig,
137
+ networkId: dappConfig.network?.networkId || 1,
138
+ });
139
+
140
+ const networkApi = GatewayApiClient.initialize(radixToolkit.gatewayApi.clientConfig);
141
+
142
+ return {
143
+ getAddress: () => "",
144
+ getBalance: getBalance({ networkApi }),
145
+ networkApi,
146
+ validateAddress,
147
+ signAndBroadcast: (() => {
148
+ throw new Error("Not implemented");
149
+ }) as (params: any) => Promise<string>,
150
+ };
151
+ };