@skip-go/client 1.2.1 → 1.2.3

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.
@@ -0,0 +1,180 @@
1
+ import { getCosmosGasAmountForMessage } from './chunk-TV2XPAIF.js';
2
+ import { BigNumber } from './chunk-VQ5SIQWU.js';
3
+ import { getSigningStargateClient } from './chunk-EHKR7I66.js';
4
+ import { ClientState, balances } from './chunk-4XUWIG3Z.js';
5
+ import { GasPrice, calculateFee } from '@cosmjs/stargate';
6
+ import { Decimal } from '@cosmjs/math';
7
+
8
+ var validateCosmosGasBalance = async ({
9
+ chainId,
10
+ signerAddress,
11
+ messages,
12
+ getFallbackGasAmount,
13
+ getOfflineSigner,
14
+ txIndex,
15
+ simulate,
16
+ getCosmosPriorityFeeDenom
17
+ }) => {
18
+ const skipAssets = (await ClientState.getSkipAssets({ chainId }))?.[chainId];
19
+ const skipChains = await ClientState.getSkipChains();
20
+ const prioFeeDenom = await getCosmosPriorityFeeDenom?.(chainId);
21
+ const chain = skipChains?.find((c) => c.chainId === chainId);
22
+ if (!chain) {
23
+ throw new Error(`failed to find chain id '${chainId}'`);
24
+ }
25
+ const { feeAssets } = chain;
26
+ if (!feeAssets) {
27
+ throw new Error(`failed to find fee assets for chain id '${chainId}'`);
28
+ }
29
+ const estimatedGasAmount = await (async () => {
30
+ try {
31
+ if (!simulate) throw new Error("simulate");
32
+ if (txIndex !== 0 && chainId === "noble-1") {
33
+ return "0";
34
+ }
35
+ const { stargateClient } = await getSigningStargateClient({
36
+ chainId,
37
+ getOfflineSigner
38
+ });
39
+ const estimatedGas = await getCosmosGasAmountForMessage(
40
+ stargateClient,
41
+ signerAddress,
42
+ chainId,
43
+ messages
44
+ );
45
+ return estimatedGas;
46
+ } catch (e) {
47
+ const error = e;
48
+ if (error.message === "simulate" && !getFallbackGasAmount) {
49
+ throw new Error(`unable to get gas amount for ${chainId}'s message(s)`);
50
+ }
51
+ if (getFallbackGasAmount) {
52
+ const fallbackGasAmount = await getFallbackGasAmount(
53
+ chainId,
54
+ "cosmos" /* Cosmos */
55
+ );
56
+ if (!fallbackGasAmount) {
57
+ throw new Error(`unable to estimate gas for message(s) ${messages}`);
58
+ }
59
+ return String(fallbackGasAmount);
60
+ }
61
+ throw error;
62
+ }
63
+ })();
64
+ const fees = feeAssets.map((asset) => {
65
+ const gasPrice = (() => {
66
+ if (!asset?.gasPrice) return void 0;
67
+ let price = asset.gasPrice.average;
68
+ if (price === "") {
69
+ price = asset.gasPrice.high;
70
+ }
71
+ if (price === "") {
72
+ price = asset.gasPrice.low;
73
+ }
74
+ if (!price) return;
75
+ return new GasPrice(
76
+ Decimal.fromUserInput(BigNumber(price).toFixed(), 18),
77
+ asset?.denom ?? ""
78
+ );
79
+ })();
80
+ if (!gasPrice) {
81
+ return null;
82
+ }
83
+ if (chainId === "noble-1") {
84
+ if (asset.denom.toLowerCase() === "ibc/EF48E6B1A1A19F47ECAEA62F5670C37C0580E86A9E88498B7E393EB6F49F33C0".toLowerCase()) {
85
+ const fee2 = calculateFee(2e6, gasPrice);
86
+ return fee2;
87
+ }
88
+ const fee = calculateFee(2e5, gasPrice);
89
+ return fee;
90
+ }
91
+ return calculateFee(Math.ceil(parseFloat(estimatedGasAmount)), gasPrice);
92
+ });
93
+ const feeBalance = await balances({
94
+ chains: {
95
+ [chainId]: {
96
+ address: signerAddress,
97
+ denoms: feeAssets.map((asset) => asset.denom ?? "")
98
+ }
99
+ }
100
+ });
101
+ const validatedAssets = feeAssets.map((asset, index) => {
102
+ const chainAsset = skipAssets?.find((x) => x.denom === asset.denom);
103
+ const symbol = chainAsset?.recommendedSymbol?.toUpperCase();
104
+ const decimal = Number(chainAsset?.decimals);
105
+ if (!chainAsset) {
106
+ return {
107
+ error: `(${chain?.prettyName}) Unable to find asset for ${asset.denom}`
108
+ };
109
+ }
110
+ if (isNaN(decimal))
111
+ return {
112
+ error: `(${chain?.prettyName}) Unable to find decimal for ${symbol}`
113
+ };
114
+ const fee = fees[index];
115
+ if (!fee) {
116
+ return {
117
+ error: `(${chain?.prettyName}) Unable to calculate fee for ${symbol}`,
118
+ asset
119
+ };
120
+ }
121
+ if (txIndex !== 0 && chainId === "noble-1") {
122
+ return {
123
+ error: null,
124
+ asset,
125
+ fee
126
+ };
127
+ }
128
+ let balance = feeBalance?.chains?.[chainId]?.denoms?.[asset?.denom ?? ""];
129
+ if (!balance) {
130
+ balance = {
131
+ amount: "0",
132
+ formattedAmount: "0"
133
+ };
134
+ }
135
+ if (!fee.amount[0]?.amount) {
136
+ return {
137
+ error: `(${chain?.prettyName}) Unable to get fee for ${symbol}`,
138
+ asset
139
+ };
140
+ }
141
+ if (parseInt(balance?.amount ?? "") < parseInt(fee.amount[0]?.amount)) {
142
+ const userAmount = new BigNumber(parseFloat(balance?.amount ?? "")).shiftedBy(-decimal).toFixed(decimal);
143
+ const feeAmount = new BigNumber(parseFloat(fee.amount[0]?.amount)).shiftedBy(-decimal).toFixed(decimal);
144
+ return {
145
+ error: `Insufficient balance for gas on ${chain?.prettyName}. Need ${feeAmount} ${symbol} but only have ${userAmount} ${symbol}.`,
146
+ asset
147
+ };
148
+ }
149
+ return {
150
+ error: null,
151
+ asset,
152
+ fee
153
+ };
154
+ });
155
+ if (prioFeeDenom) {
156
+ const availableAssets = validatedAssets.filter(
157
+ (res) => res?.error === null
158
+ );
159
+ const prioFeeAsset = availableAssets.find(
160
+ (res) => res?.asset?.denom === prioFeeDenom
161
+ );
162
+ if (prioFeeAsset) {
163
+ return prioFeeAsset;
164
+ }
165
+ }
166
+ const feeUsed = validatedAssets.find((res) => res?.error === null);
167
+ if (!feeUsed) {
168
+ if (validatedAssets.length > 1) {
169
+ throw new Error(
170
+ validatedAssets[0]?.error || `Insufficient fee token to initiate transfer on ${chain.prettyName}.`
171
+ );
172
+ }
173
+ throw new Error(
174
+ validatedAssets[0]?.error || `Insufficient fee token to initiate transfer on ${chain.prettyName}.`
175
+ );
176
+ }
177
+ return feeUsed;
178
+ };
179
+
180
+ export { validateCosmosGasBalance };