@skip-go/client 1.5.3-alpha.0 → 1.5.3-alpha.1

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 (47) hide show
  1. package/dist/cjs/{chunk-CZKIE576.cjs → chunk-APJDSXWR.cjs} +2 -2
  2. package/dist/cjs/{chunk-GWRZ6MPC.cjs → chunk-I2FDWZZJ.cjs} +16 -16
  3. package/dist/cjs/{chunk-GGSF5JZH.cjs → chunk-NWD4MAMT.cjs} +4 -4
  4. package/dist/cjs/{chunk-J7HZ6VJE.cjs → chunk-PDTIT3JO.cjs} +3 -3
  5. package/dist/cjs/{chunk-MOWOIPUG.cjs → chunk-RC73RNNQ.cjs} +2 -2
  6. package/dist/cjs/chunk-UMBMSRZZ.cjs +185 -0
  7. package/dist/cjs/index.cjs +35 -35
  8. package/dist/cjs/public-functions/executeMultipleRoutes.cjs +7 -7
  9. package/dist/cjs/public-functions/executeRoute.cjs +7 -7
  10. package/dist/cjs/public-functions/getFeeInfoForChain.cjs +3 -3
  11. package/dist/cjs/public-functions/getRecommendedGasPrice.cjs +4 -4
  12. package/dist/cjs/public-functions/getRouteWithGasOnReceive.cjs +7 -7
  13. package/dist/cjs/public-functions/getSigningStargateClient.cjs +3 -3
  14. package/dist/cjs/public-functions/validateCosmosGasBalance.cjs +4 -4
  15. package/dist/esm/{chunk-SOVU5NCL.js → chunk-2PWROHHX.js} +1 -1
  16. package/dist/esm/{chunk-RJ35JBT4.js → chunk-IKWC55JU.js} +4 -4
  17. package/dist/esm/chunk-O4J7DHZA.js +180 -0
  18. package/dist/esm/{chunk-YWG4XR5A.js → chunk-QRKO56DH.js} +1 -1
  19. package/dist/esm/{chunk-47HN6VKU.js → chunk-SFWTQBQT.js} +1 -1
  20. package/dist/esm/{chunk-JNVGNIOE.js → chunk-V7VKYD4J.js} +1 -1
  21. package/dist/esm/index.js +6 -6
  22. package/dist/esm/public-functions/executeMultipleRoutes.js +6 -6
  23. package/dist/esm/public-functions/executeRoute.js +6 -6
  24. package/dist/esm/public-functions/getFeeInfoForChain.js +2 -2
  25. package/dist/esm/public-functions/getRecommendedGasPrice.js +3 -3
  26. package/dist/esm/public-functions/getRouteWithGasOnReceive.js +6 -6
  27. package/dist/esm/public-functions/getSigningStargateClient.js +2 -2
  28. package/dist/esm/public-functions/validateCosmosGasBalance.js +3 -3
  29. package/package.json +1 -1
  30. package/dist/cjs/chunk-ARCCHERF.cjs +0 -1478
  31. package/dist/cjs/chunk-BQDOKZFX.cjs +0 -214
  32. package/dist/cjs/chunk-EVEVOW2U.cjs +0 -2179
  33. package/dist/cjs/chunk-H2T4LMS2.cjs +0 -55
  34. package/dist/cjs/chunk-I6VYDEUV.cjs +0 -454
  35. package/dist/cjs/chunk-KSJ5QYMR.cjs +0 -185
  36. package/dist/cjs/chunk-KZOSEIWH.cjs +0 -10
  37. package/dist/cjs/chunk-UY5LWG5D.cjs +0 -95
  38. package/dist/cjs/chunk-W6ID22B6.cjs +0 -24
  39. package/dist/esm/chunk-DL374PFE.js +0 -53
  40. package/dist/esm/chunk-FDRLM2JD.js +0 -431
  41. package/dist/esm/chunk-H3MY23AH.js +0 -93
  42. package/dist/esm/chunk-IGK7LJCM.js +0 -1475
  43. package/dist/esm/chunk-RHGDUD76.js +0 -180
  44. package/dist/esm/chunk-RHLE3EW7.js +0 -212
  45. package/dist/esm/chunk-SWYON2RG.js +0 -7
  46. package/dist/esm/chunk-X2IBEHMZ.js +0 -2154
  47. package/dist/esm/chunk-XHLXJGVB.js +0 -22
@@ -1,1475 +0,0 @@
1
- import { updateRouteDetails } from './chunk-5IXH2QPF.js';
2
- import { validateCosmosGasBalance } from './chunk-47HN6VKU.js';
3
- import { getEncodeObjectFromCosmosMessage } from './chunk-KNXMSLOB.js';
4
- import { getEVMGasAmountForMessage } from './chunk-GV2QOWB4.js';
5
- import { BigNumber } from './chunk-JYYCFKB4.js';
6
- import { GAS_STATION_CHAIN_IDS } from './chunk-SWYON2RG.js';
7
- import { getRpcEndpointForChain, accountParser, getSigningStargateClient } from './chunk-SOVU5NCL.js';
8
- import { chains, findFirstWorkingEndpoint, getIsEthermint, getIsInitia } from './chunk-RHGDUD76.js';
9
- import { submitTransaction } from './chunk-HDW6XFWX.js';
10
- import { venues } from './chunk-FNTPI2AV.js';
11
- import { ClientState, balances } from './chunk-MYGJGC62.js';
12
- import { wait, toCamel } from './chunk-VGCTTJO7.js';
13
- import { StargateClient } from '@cosmjs/stargate';
14
- import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx.js';
15
- import { isOfflineDirectSigner, makeAuthInfoBytes, makeSignDoc, encodePubkey } from '@cosmjs/proto-signing';
16
- import { pubkeyType as pubkeyType$1, makeSignDoc as makeSignDoc$1, encodeSecp256k1Pubkey } from '@cosmjs/amino';
17
- import { fromBase64, toBase64 } from '@cosmjs/encoding';
18
- import { PubKey } from 'cosmjs-types/cosmos/crypto/secp256k1/keys.js';
19
- import { Any } from 'cosmjs-types/google/protobuf/any.js';
20
- import { Int53 } from '@cosmjs/math';
21
- import { SignMode } from 'cosmjs-types/cosmos/tx/signing/v1beta1/signing.js';
22
- import { isAddress, publicActions, maxUint256, formatUnits } from 'viem';
23
- import { Transaction, PublicKey, Connection, LAMPORTS_PER_SOL } from '@solana/web3.js';
24
- import { bech32m, bech32 } from 'bech32';
25
-
26
- // src/private-functions/getRestEndpointForChain.ts
27
- var getRestEndpointForChain = async (chainId) => {
28
- if (ClientState.endpointOptions.getRestEndpointForChain) {
29
- return ClientState.endpointOptions.getRestEndpointForChain(chainId);
30
- }
31
- if (ClientState.endpointOptions.endpoints && ClientState.endpointOptions.endpoints[chainId]) {
32
- const endpointOptions = ClientState.endpointOptions.endpoints[chainId];
33
- if (endpointOptions?.rest) {
34
- return endpointOptions.rest;
35
- }
36
- }
37
- const chain = chains().find((chain2) => chain2.chainId === chainId);
38
- if (!chain) {
39
- throw new Error(
40
- `getRestEndpointForChain error: failed to find chain id '${chainId}' in registry`
41
- );
42
- }
43
- if (chain.apis?.rest?.length === 0 || !chain.apis?.rest) {
44
- throw new Error(
45
- `getRestEndpointForChain error: failed to find REST endpoint for chain id '${chainId}'`
46
- );
47
- }
48
- const endpoints = chain.apis?.rest?.map((api) => api.address);
49
- const endpoint = await findFirstWorkingEndpoint(endpoints, "rest");
50
- if (!endpoint) {
51
- throw new Error(
52
- `getRestEndpointForChain error: failed to find REST endpoint for chain id '${chainId}'`
53
- );
54
- }
55
- return endpoint;
56
- };
57
-
58
- // src/private-functions/getAccountNumberAndSequence.ts
59
- var getAccountNumberAndSequence = async (address, chainId) => {
60
- if (chainId.includes("dymension")) {
61
- return getAccountNumberAndSequenceFromDymension(address, chainId);
62
- }
63
- const endpoint = await getRpcEndpointForChain(chainId);
64
- const client = ClientState.signingStargateClientByChainId[chainId] ?? await StargateClient.connect(endpoint, {
65
- accountParser
66
- });
67
- const account = await client.getAccount(address);
68
- if (!account) {
69
- throw new Error("getAccountNumberAndSequence: failed to retrieve account");
70
- }
71
- client.disconnect();
72
- return {
73
- accountNumber: account.accountNumber,
74
- sequence: account.sequence
75
- };
76
- };
77
- var getAccountNumberAndSequenceFromDymension = async (address, chainId) => {
78
- const endpoint = await getRestEndpointForChain(chainId);
79
- const res = await fetch(
80
- `${endpoint}/cosmos/auth/v1beta1/accounts/${address}`,
81
- {
82
- headers: {
83
- "Content-Type": "application/json"
84
- }
85
- }
86
- );
87
- if (!res.ok) {
88
- throw new Error(`Failed to fetch account data: ${res.statusText}`);
89
- }
90
- const jsonResponse = await res.json();
91
- const response = toCamel(jsonResponse);
92
- let sequence = 0;
93
- let accountNumber = 0;
94
- if (response.account.baseAccount) {
95
- sequence = response.account.baseAccount.sequence;
96
- accountNumber = response.account.baseAccount.accountNumber;
97
- } else {
98
- sequence = response.account.sequence;
99
- accountNumber = response.account.accountNumber;
100
- }
101
- return {
102
- accountNumber,
103
- sequence
104
- };
105
- };
106
- var pubkeyType = {
107
- ethsecp256k1: "ethermint/PubKeyEthSecp256k1",
108
- ...pubkeyType$1
109
- };
110
-
111
- // src/amino/encoding.ts
112
- function encodeEthSecp256k1Pubkey(pubkey) {
113
- if (pubkey.length !== 33 || pubkey[0] !== 2 && pubkey[0] !== 3) {
114
- throw new Error(
115
- "Public key must be compressed secp256k1, i.e. 33 bytes starting with 0x02 or 0x03"
116
- );
117
- }
118
- return {
119
- type: pubkeyType.ethsecp256k1,
120
- value: toBase64(pubkey)
121
- };
122
- }
123
-
124
- // src/proto-signing/pubkey.ts
125
- function makePubkeyAnyFromAccount(account, chainId) {
126
- const isEthermint = getIsEthermint(chainId);
127
- const pubkey = isEthermint ? encodeEthSecp256k1Pubkey(account.pubkey) : encodeSecp256k1Pubkey(account.pubkey);
128
- const pubkeyAny = encodePubkeyToAny(pubkey, chainId, isEthermint);
129
- return pubkeyAny;
130
- }
131
- function encodePubkeyToAny(pubkey, chainId, isEthermint) {
132
- if (isEthermint) {
133
- const pubkeyProto = PubKey.fromPartial({
134
- key: fromBase64(pubkey.value)
135
- });
136
- let typeUrl = "";
137
- if (chainId?.includes("injective")) {
138
- typeUrl = "/injective.crypto.v1beta1.ethsecp256k1.PubKey";
139
- } else {
140
- typeUrl = "/ethermint.crypto.v1.ethsecp256k1.PubKey";
141
- }
142
- return Any.fromPartial({
143
- typeUrl,
144
- value: Uint8Array.from(PubKey.encode(pubkeyProto).finish())
145
- });
146
- } else {
147
- const isInitia = getIsInitia(chainId);
148
- const pubkeyProto = PubKey.fromPartial({
149
- key: fromBase64(pubkey.value)
150
- });
151
- if (isInitia) {
152
- return Any.fromPartial({
153
- typeUrl: "/initia.crypto.v1beta1.ethsecp256k1.PubKey",
154
- value: Uint8Array.from(PubKey.encode(pubkeyProto).finish())
155
- });
156
- }
157
- return encodePubkey(pubkey);
158
- }
159
- }
160
- var signCosmosMessageDirect = async (options) => {
161
- const {
162
- signer,
163
- signerAddress,
164
- chainId,
165
- cosmosMsgs,
166
- fee,
167
- signerData: { accountNumber, sequence, chainId: signerChainId }
168
- } = options;
169
- const accounts = await signer.getAccounts();
170
- const accountFromSigner = accounts.find((account) => account.address === signerAddress);
171
- if (!accountFromSigner) {
172
- throw new Error("signCosmosMessageDirect error: failed to retrieve account from signer");
173
- }
174
- const messages = cosmosMsgs.map((cosmosMsg) => getEncodeObjectFromCosmosMessage(cosmosMsg));
175
- const txBodyEncodeObject = {
176
- typeUrl: "/cosmos.tx.v1beta1.TxBody",
177
- value: {
178
- messages
179
- }
180
- };
181
- const txBodyBytes = ClientState.registry.encode(txBodyEncodeObject);
182
- const gasLimit = Int53.fromString(fee.gas).toNumber();
183
- const pubkeyAny = makePubkeyAnyFromAccount(accountFromSigner, chainId);
184
- const authInfoBytes = makeAuthInfoBytes(
185
- [{ pubkey: pubkeyAny, sequence }],
186
- fee.amount,
187
- gasLimit,
188
- fee.granter,
189
- fee.payer
190
- );
191
- const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber);
192
- const { signature, signed } = await signer.signDirect(signerAddress, signDoc);
193
- return TxRaw.fromPartial({
194
- bodyBytes: signed.bodyBytes,
195
- authInfoBytes: signed.authInfoBytes,
196
- signatures: [fromBase64(signature.signature)]
197
- });
198
- };
199
- var signCosmosMessageAmino = async (options) => {
200
- const {
201
- signer,
202
- signerAddress,
203
- chainId,
204
- cosmosMsgs,
205
- fee,
206
- signerData: { accountNumber, sequence, chainId: signerChainId }
207
- } = options;
208
- const accounts = await signer.getAccounts();
209
- const accountFromSigner = accounts.find(
210
- (account) => account.address === signerAddress
211
- );
212
- if (!accountFromSigner) {
213
- throw new Error(
214
- "signCosmosMessageAmino: failed to retrieve account from signer"
215
- );
216
- }
217
- const messages = cosmosMsgs.map(
218
- (cosmosMsg) => getEncodeObjectFromCosmosMessage(cosmosMsg)
219
- );
220
- const signMode = SignMode.SIGN_MODE_LEGACY_AMINO_JSON;
221
- const msgs = messages.map((msg) => ClientState.aminoTypes.toAmino(msg));
222
- const signDoc = makeSignDoc$1(
223
- msgs,
224
- fee,
225
- signerChainId,
226
- "",
227
- accountNumber,
228
- sequence
229
- );
230
- const { signature, signed } = await signer.signAmino(signerAddress, signDoc);
231
- const signedTxBody = {
232
- messages: signed.msgs.map((msg) => ClientState.aminoTypes.fromAmino(msg)),
233
- memo: signed.memo
234
- };
235
- signedTxBody.messages[0].value.memo = messages[0].value.memo;
236
- const signedTxBodyEncodeObject = {
237
- typeUrl: "/cosmos.tx.v1beta1.TxBody",
238
- value: signedTxBody
239
- };
240
- const signedTxBodyBytes = ClientState.registry.encode(
241
- signedTxBodyEncodeObject
242
- );
243
- const signedGasLimit = Int53.fromString(signed.fee.gas).toNumber();
244
- const signedSequence = Int53.fromString(signed.sequence).toNumber();
245
- const pubkeyAny = makePubkeyAnyFromAccount(accountFromSigner, chainId);
246
- const signedAuthInfoBytes = makeAuthInfoBytes(
247
- [{ pubkey: pubkeyAny, sequence: signedSequence }],
248
- signed.fee.amount,
249
- signedGasLimit,
250
- signed.fee.granter,
251
- signed.fee.payer,
252
- signMode
253
- );
254
- return TxRaw.fromPartial({
255
- bodyBytes: signedTxBodyBytes,
256
- authInfoBytes: signedAuthInfoBytes,
257
- signatures: [fromBase64(signature.signature)]
258
- });
259
- };
260
-
261
- // src/private-functions/cosmos/signCosmosTransaction.ts
262
- var signCosmosTransaction = async ({
263
- tx,
264
- options,
265
- index,
266
- routeId
267
- }) => {
268
- const { userAddresses } = options;
269
- if (tx === void 0) {
270
- throw new Error("executeCosmosTransaction error: tx is undefined");
271
- }
272
- const chainId = tx.cosmosTx?.chainId;
273
- const messages = tx.cosmosTx?.msgs;
274
- const currentUserAddress = userAddresses.find((x) => x.chainId === tx.cosmosTx?.chainId)?.address;
275
- const gasArray = ClientState.validateGasResults;
276
- const gas = gasArray?.find((gas2) => gas2?.error !== null && gas2?.error !== void 0);
277
- if (typeof gas?.error === "string") {
278
- throw new Error(gas?.error);
279
- }
280
- const gasUsed = gasArray?.[index];
281
- if (!gasUsed) {
282
- throw new Error(`executeRoute error: invalid gas at index ${index}`);
283
- }
284
- if (chainId === void 0) {
285
- throw new Error("no chainId found for tx");
286
- }
287
- if (messages === void 0) {
288
- throw new Error("no messages found for tx");
289
- }
290
- const { signer } = await getSigningStargateClient({
291
- chainId,
292
- getOfflineSigner: options?.getCosmosSigner
293
- });
294
- if (!currentUserAddress) {
295
- throw new Error(
296
- `executeCosmosTransaction error: invalid address for chain '${tx.cosmosTx?.chainId}'`
297
- );
298
- }
299
- const accounts = await signer.getAccounts();
300
- const accountFromSigner = accounts.find((account) => account.address === currentUserAddress);
301
- if (!accountFromSigner) {
302
- throw new Error("executeCosmosTransaction error: failed to retrieve account from signer");
303
- }
304
- const fee = gasUsed?.fee;
305
- if (!fee) {
306
- throw new Error("executeCosmosTransaction error: failed to retrieve fee from gas");
307
- }
308
- const { accountNumber, sequence } = await getAccountNumberAndSequence(
309
- currentUserAddress,
310
- chainId
311
- );
312
- let rawTx;
313
- const commonRawTxBody = {
314
- signerAddress: currentUserAddress,
315
- chainId,
316
- cosmosMsgs: messages,
317
- fee,
318
- signerData: {
319
- accountNumber,
320
- sequence,
321
- chainId
322
- }
323
- };
324
- options.onTransactionSignRequested?.({
325
- chainId,
326
- txIndex: index,
327
- signerAddress: currentUserAddress
328
- });
329
- updateRouteDetails({
330
- status: "signing",
331
- routeId,
332
- options
333
- });
334
- if (isOfflineDirectSigner(signer)) {
335
- rawTx = await signCosmosMessageDirect({
336
- ...commonRawTxBody,
337
- signer
338
- });
339
- } else {
340
- rawTx = await signCosmosMessageAmino({ ...commonRawTxBody, signer });
341
- }
342
- options?.onTransactionSigned?.({
343
- chainId
344
- });
345
- updateRouteDetails({
346
- status: "pending",
347
- routeId,
348
- options
349
- });
350
- const txBytes = TxRaw.encode(rawTx).finish();
351
- const rawTxBase64 = Buffer.from(txBytes).toString("base64");
352
- return rawTxBase64;
353
- };
354
-
355
- // src/private-functions/cosmos/executeCosmosTransaction.ts
356
- var executeCosmosTransaction = async ({
357
- tx,
358
- options,
359
- index,
360
- routeId
361
- }) => {
362
- if (tx === void 0) {
363
- throw new Error("executeCosmosTransaction error: tx is undefined");
364
- }
365
- const rawTxBase64 = await signCosmosTransaction({
366
- tx,
367
- options,
368
- index,
369
- routeId
370
- });
371
- const chainId = tx.cosmosTx?.chainId;
372
- const txResponse = await submitTransaction({
373
- chainId,
374
- tx: rawTxBase64
375
- });
376
- return {
377
- chainId: tx?.cosmosTx?.chainId ?? "",
378
- txHash: txResponse?.txHash ?? "",
379
- explorerLink: txResponse?.explorerLink ?? ""
380
- };
381
- };
382
- function createAbi(abi) {
383
- return abi;
384
- }
385
- var erc20ABI = /* @__PURE__ */ createAbi([
386
- {
387
- type: "event",
388
- name: "Approval",
389
- inputs: [
390
- {
391
- indexed: true,
392
- name: "owner",
393
- type: "address"
394
- },
395
- {
396
- indexed: true,
397
- name: "spender",
398
- type: "address"
399
- },
400
- {
401
- indexed: false,
402
- name: "value",
403
- type: "uint256"
404
- }
405
- ]
406
- },
407
- {
408
- type: "event",
409
- name: "Transfer",
410
- inputs: [
411
- {
412
- indexed: true,
413
- name: "from",
414
- type: "address"
415
- },
416
- {
417
- indexed: true,
418
- name: "to",
419
- type: "address"
420
- },
421
- {
422
- indexed: false,
423
- name: "value",
424
- type: "uint256"
425
- }
426
- ]
427
- },
428
- {
429
- type: "function",
430
- name: "allowance",
431
- stateMutability: "view",
432
- inputs: [
433
- {
434
- name: "owner",
435
- type: "address"
436
- },
437
- {
438
- name: "spender",
439
- type: "address"
440
- }
441
- ],
442
- outputs: [
443
- {
444
- name: "",
445
- type: "uint256"
446
- }
447
- ]
448
- },
449
- {
450
- type: "function",
451
- name: "approve",
452
- stateMutability: "nonpayable",
453
- inputs: [
454
- {
455
- name: "spender",
456
- type: "address"
457
- },
458
- {
459
- name: "amount",
460
- type: "uint256"
461
- }
462
- ],
463
- outputs: [
464
- {
465
- name: "",
466
- type: "bool"
467
- }
468
- ]
469
- },
470
- {
471
- type: "function",
472
- name: "balanceOf",
473
- stateMutability: "view",
474
- inputs: [
475
- {
476
- name: "account",
477
- type: "address"
478
- }
479
- ],
480
- outputs: [
481
- {
482
- name: "",
483
- type: "uint256"
484
- }
485
- ]
486
- },
487
- {
488
- type: "function",
489
- name: "decimals",
490
- stateMutability: "view",
491
- inputs: [],
492
- outputs: [
493
- {
494
- name: "",
495
- type: "uint8"
496
- }
497
- ]
498
- },
499
- {
500
- type: "function",
501
- name: "name",
502
- stateMutability: "view",
503
- inputs: [],
504
- outputs: [
505
- {
506
- name: "",
507
- type: "string"
508
- }
509
- ]
510
- },
511
- {
512
- type: "function",
513
- name: "symbol",
514
- stateMutability: "view",
515
- inputs: [],
516
- outputs: [
517
- {
518
- name: "",
519
- type: "string"
520
- }
521
- ]
522
- },
523
- {
524
- type: "function",
525
- name: "totalSupply",
526
- stateMutability: "view",
527
- inputs: [],
528
- outputs: [
529
- {
530
- name: "",
531
- type: "uint256"
532
- }
533
- ]
534
- },
535
- {
536
- type: "function",
537
- name: "transfer",
538
- stateMutability: "nonpayable",
539
- inputs: [
540
- {
541
- name: "recipient",
542
- type: "address"
543
- },
544
- {
545
- name: "amount",
546
- type: "uint256"
547
- }
548
- ],
549
- outputs: [
550
- {
551
- name: "",
552
- type: "bool"
553
- }
554
- ]
555
- },
556
- {
557
- type: "function",
558
- name: "transferFrom",
559
- stateMutability: "nonpayable",
560
- inputs: [
561
- {
562
- name: "sender",
563
- type: "address"
564
- },
565
- {
566
- name: "recipient",
567
- type: "address"
568
- },
569
- {
570
- name: "amount",
571
- type: "uint256"
572
- }
573
- ],
574
- outputs: [
575
- {
576
- name: "",
577
- type: "bool"
578
- }
579
- ]
580
- }
581
- ]);
582
-
583
- // src/private-functions/evm/executeEvmTransaction.ts
584
- var executeEvmTransaction = async (message, options, index, routeId) => {
585
- const gasArray = ClientState.validateGasResults;
586
- const gas = gasArray?.find((gas2) => gas2?.error !== null && gas2?.error !== void 0);
587
- if (typeof gas?.error === "string") {
588
- throw new Error(gas?.error);
589
- }
590
- const { evmTx } = message;
591
- const getEvmSigner = options.getEvmSigner;
592
- if (!getEvmSigner) {
593
- throw new Error("executeEVMTransaction error: getEvmSigner is not provided");
594
- }
595
- if (!evmTx?.chainId) {
596
- throw new Error("chain id not found in evmTx");
597
- }
598
- const evmSigner = await getEvmSigner(evmTx.chainId);
599
- if (!evmSigner.account) {
600
- throw new Error("executeEVMTransaction error: failed to retrieve account from signer");
601
- }
602
- if (!evmTx.chainId) {
603
- throw new Error("executeEVMTransaction error: chainId not found for evmTx");
604
- }
605
- if (!evmTx.value && evmTx.value !== "") {
606
- throw new Error("executeEVMTransaction error: no value found in evmTx");
607
- }
608
- const { onApproveAllowance, onTransactionSigned, bypassApprovalCheck, useUnlimitedApproval } = options;
609
- const extendedSigner = evmSigner.extend(publicActions);
610
- if (!bypassApprovalCheck && evmTx.requiredErc20Approvals) {
611
- for (const requiredApproval of evmTx.requiredErc20Approvals) {
612
- const allowance = await extendedSigner.readContract({
613
- address: requiredApproval.tokenContract,
614
- abi: erc20ABI,
615
- functionName: "allowance",
616
- args: [
617
- evmSigner.account.address,
618
- requiredApproval.spender
619
- ]
620
- });
621
- if (!requiredApproval.amount) {
622
- throw new Error("executeEVMTransaction error: no amount found in a requiredApproval");
623
- }
624
- if (allowance > BigInt(requiredApproval.amount)) {
625
- continue;
626
- }
627
- onApproveAllowance?.({
628
- status: "pending",
629
- allowance: requiredApproval
630
- });
631
- updateRouteDetails({
632
- status: "allowance",
633
- routeId,
634
- options
635
- });
636
- const txHash2 = await extendedSigner.writeContract({
637
- account: evmSigner.account,
638
- address: requiredApproval.tokenContract,
639
- abi: erc20ABI,
640
- functionName: "approve",
641
- args: [
642
- requiredApproval.spender,
643
- useUnlimitedApproval ? maxUint256 : BigInt(requiredApproval.amount) + BigInt(1e3)
644
- ],
645
- chain: evmSigner.chain
646
- });
647
- const receipt2 = await extendedSigner.waitForTransactionReceipt({
648
- hash: txHash2
649
- });
650
- if (receipt2.status === "reverted") {
651
- throw new Error(
652
- `executeEVMTransaction error: evm tx reverted for hash ${receipt2.transactionHash}`
653
- );
654
- }
655
- }
656
- onApproveAllowance?.({
657
- status: "completed"
658
- });
659
- }
660
- options?.onTransactionSignRequested?.({
661
- chainId: evmTx.chainId,
662
- signerAddress: evmSigner.account.address,
663
- txIndex: index
664
- });
665
- updateRouteDetails({
666
- status: "signing",
667
- routeId,
668
- options
669
- });
670
- const txHash = await extendedSigner.sendTransaction({
671
- account: evmSigner.account,
672
- to: evmTx.to,
673
- data: `0x${evmTx.data}`,
674
- chain: evmSigner.chain,
675
- value: evmTx.value === "" ? void 0 : BigInt(evmTx.value)
676
- });
677
- updateRouteDetails({
678
- status: "pending",
679
- routeId,
680
- options
681
- });
682
- onTransactionSigned?.({
683
- chainId: evmTx.chainId
684
- });
685
- const receipt = await extendedSigner.waitForTransactionReceipt({
686
- hash: txHash
687
- });
688
- return receipt;
689
- };
690
- var signSvmTransaction = async ({
691
- tx,
692
- options,
693
- index,
694
- routeId
695
- }) => {
696
- const gasArray = ClientState.validateGasResults;
697
- if (tx === void 0) {
698
- throw new Error("executeSvmTransaction error: tx is undefined");
699
- }
700
- const gas = gasArray?.find(
701
- (gas2) => gas2?.error !== null && gas2?.error !== void 0
702
- );
703
- if (typeof gas?.error === "string") {
704
- throw new Error(gas?.error);
705
- }
706
- const svmTx = tx?.svmTx;
707
- const getSvmSigner = options?.getSvmSigner;
708
- if (!getSvmSigner) {
709
- throw new Error(
710
- "executeSvmTransaction error: getSvmSigner is not provided"
711
- );
712
- }
713
- const signer = await getSvmSigner();
714
- if (!svmTx?.chainId) {
715
- throw new Error("executeSvmTransaction error: chainId not found in svmTx");
716
- }
717
- const txBuffer = Buffer.from(svmTx.tx ?? "", "base64");
718
- const transaction = Transaction.from(txBuffer);
719
- if (options.svmFeePayer) {
720
- const message = transaction.serializeMessage();
721
- const resSignTx = await options.svmFeePayer.signTransaction(message);
722
- transaction.addSignature(
723
- new PublicKey(options.svmFeePayer.address),
724
- Buffer.from(resSignTx)
725
- );
726
- }
727
- if (!("signTransaction" in signer)) return;
728
- options?.onTransactionSignRequested?.({
729
- chainId: svmTx.chainId,
730
- signerAddress: signer.publicKey?.toBase58(),
731
- txIndex: index
732
- });
733
- updateRouteDetails({
734
- status: "signing",
735
- routeId,
736
- options
737
- });
738
- const signedTx = await signer.signTransaction(transaction);
739
- options?.onTransactionSigned?.({ chainId: svmTx.chainId });
740
- updateRouteDetails({
741
- status: "pending",
742
- routeId,
743
- options
744
- });
745
- const serializedTx = signedTx.serialize();
746
- return serializedTx;
747
- };
748
-
749
- // src/private-functions/svm/executeSvmTransaction.ts
750
- var executeSvmTransaction = async (tx, options, index, routeId) => {
751
- const svmTx = tx?.svmTx;
752
- if (!svmTx?.chainId) {
753
- throw new Error("executeSvmTransaction error: chainId not found in svmTx");
754
- }
755
- const signedTx = await signSvmTransaction({ tx, options, index, routeId });
756
- if (!signedTx) {
757
- throw new Error("executeSvmTransaction error: signedTx is undefined");
758
- }
759
- const endpoint = await getRpcEndpointForChain(svmTx.chainId);
760
- const connection = new Connection(endpoint);
761
- let signature;
762
- const submitTxResponse = await submitTransaction({
763
- chainId: svmTx.chainId,
764
- tx: signedTx.toString("base64")
765
- });
766
- signature = submitTxResponse?.txHash;
767
- const rpcSig = await connection.sendRawTransaction(signedTx, {
768
- preflightCommitment: "confirmed",
769
- maxRetries: 5
770
- });
771
- signature = rpcSig;
772
- if (!signature) {
773
- throw new Error("executeSvmTransaction error: signature not found");
774
- }
775
- let getStatusCount = 0;
776
- let errorCount = 0;
777
- while (true) {
778
- try {
779
- const status = await connection.getSignatureStatus(signature, {
780
- searchTransactionHistory: true
781
- });
782
- if (status?.value?.confirmationStatus === "confirmed") {
783
- return {
784
- chainId: svmTx.chainId,
785
- txHash: signature,
786
- explorerLink: submitTxResponse?.explorerLink ?? ""
787
- };
788
- }
789
- if (getStatusCount > 12) {
790
- await wait(3e3);
791
- throw new Error(
792
- `executeSvmTransaction error: waiting finalized status timed out for ${signature}`
793
- );
794
- }
795
- getStatusCount++;
796
- await wait(3e3);
797
- } catch (error) {
798
- errorCount++;
799
- if (errorCount > 12) {
800
- throw error;
801
- }
802
- }
803
- }
804
- };
805
- var validateEvmTokenApproval = async ({
806
- requiredErc20Approvals,
807
- signer,
808
- chain,
809
- gasBalance,
810
- tx,
811
- useUnlimitedApproval
812
- }) => {
813
- if (!signer.account?.address) {
814
- throw new Error("validateEvmGasBalance: Signer address not found");
815
- }
816
- for (const requiredApproval of requiredErc20Approvals) {
817
- const extendedSigner = signer.extend(publicActions);
818
- const allowance = await extendedSigner.readContract({
819
- address: requiredApproval.tokenContract,
820
- abi: erc20ABI,
821
- functionName: "allowance",
822
- args: [signer.account?.address, requiredApproval.spender]
823
- });
824
- if (allowance > BigInt(requiredApproval.amount)) {
825
- continue;
826
- }
827
- const fee = await extendedSigner.estimateFeesPerGas();
828
- const allowanceGasFee = BigInt(fee.maxFeePerGas) * BigInt(1e5);
829
- if (!gasBalance) {
830
- const chainAssets = (await ClientState.getSkipAssets({ chainId: tx.chainId }))[tx.chainId];
831
- const nativeAsset = chainAssets?.find((x) => x.denom.includes("-native"));
832
- const zeroAddressAsset = chainAssets?.find(
833
- (x) => x.denom.toLowerCase() === "0x0000000000000000000000000000000000000000"
834
- );
835
- const asset = nativeAsset || zeroAddressAsset;
836
- if (!asset?.decimals) {
837
- throw new Error(
838
- `Insufficient balance for gas on ${chain.prettyName}. Need ${allowanceGasFee} gwei.`
839
- );
840
- }
841
- const formattedGasAmount = formatUnits(allowanceGasFee, asset?.decimals);
842
- throw new Error(
843
- `Insufficient balance for gas on ${chain.prettyName}. Need ${formattedGasAmount} ${asset.symbol}.`
844
- );
845
- }
846
- if (BigNumber(gasBalance.amount).lt(Number(allowanceGasFee))) {
847
- const chainAssets = (await ClientState.getSkipAssets({ chainId: tx.chainId }))[tx.chainId];
848
- const asset = chainAssets?.find(
849
- (x) => x.denom.includes("-native") || x.denom.toLowerCase() === "0x0000000000000000000000000000000000000000"
850
- );
851
- if (!asset?.decimals) {
852
- return {
853
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${allowanceGasFee} gwei but only have ${gasBalance.amount} gwei.`,
854
- asset: null,
855
- fee: null
856
- };
857
- }
858
- const formattedGasAmount = formatUnits(allowanceGasFee, asset?.decimals);
859
- return {
860
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${formattedGasAmount} ${asset.symbol} but only have ${gasBalance.formattedAmount} ${asset.symbol}.`,
861
- asset: null,
862
- fee: null
863
- };
864
- }
865
- const txHash = await extendedSigner.writeContract({
866
- account: signer.account,
867
- address: requiredApproval.tokenContract,
868
- abi: erc20ABI,
869
- functionName: "approve",
870
- args: [
871
- requiredApproval.spender,
872
- useUnlimitedApproval ? maxUint256 : BigInt(requiredApproval.amount) + BigInt(1e3)
873
- ],
874
- chain: signer.chain
875
- });
876
- const receipt = await extendedSigner.waitForTransactionReceipt({
877
- hash: txHash
878
- });
879
- if (receipt.status === "reverted") {
880
- throw new Error(
881
- `executeEVMTransaction error: evm tx reverted for hash ${receipt.transactionHash}`
882
- );
883
- }
884
- }
885
- };
886
-
887
- // src/private-functions/evm/validateEvmGasBalance.ts
888
- var validateEvmGasBalance = async ({
889
- signer,
890
- tx,
891
- getFallbackGasAmount,
892
- useUnlimitedApproval,
893
- bypassApprovalCheck
894
- }) => {
895
- const chainId = tx?.chainId ?? "";
896
- const skipAssets = (await ClientState.getSkipAssets({ chainId }))?.[chainId];
897
- const skipChains = await ClientState.getSkipChains();
898
- const chain = skipChains?.find?.((chain2) => chain2.chainId === chainId);
899
- if (!chain) {
900
- throw new Error(`failed to find chain for chainId: '${chainId}'`);
901
- }
902
- if (!signer.account?.address) {
903
- throw new Error("validateEvmGasBalance: Signer address not found");
904
- }
905
- const skipBalances = (await balances({
906
- chains: {
907
- [tx?.chainId ?? ""]: {
908
- address: signer.account?.address
909
- }
910
- }
911
- }))?.chains?.[tx?.chainId ?? ""]?.denoms;
912
- const nativeGasBalance = skipBalances && Object.entries(skipBalances).find(([denom]) => denom.includes("-native"))?.[1];
913
- const zeroAddressGasBalance = skipBalances && Object.entries(skipBalances).find(
914
- ([denom]) => denom.toLowerCase() === "0x0000000000000000000000000000000000000000"
915
- )?.[1];
916
- const gasBalance = nativeGasBalance || zeroAddressGasBalance;
917
- const { requiredErc20Approvals } = tx;
918
- if (!bypassApprovalCheck && requiredErc20Approvals) {
919
- try {
920
- await validateEvmTokenApproval({
921
- requiredErc20Approvals,
922
- signer,
923
- chain,
924
- gasBalance,
925
- tx,
926
- useUnlimitedApproval
927
- });
928
- } catch (error) {
929
- const err = error;
930
- return {
931
- error: err.message,
932
- asset: null,
933
- fee: null
934
- };
935
- }
936
- }
937
- const gasAmount = await getEVMGasAmountForMessage(signer, tx, getFallbackGasAmount);
938
- if (!gasBalance) {
939
- const nativeAsset = skipAssets?.find((x) => x.denom?.includes("-native"));
940
- const zeroAddressAsset = skipAssets?.find(
941
- (x) => x.denom?.toLowerCase() === "0x0000000000000000000000000000000000000000"
942
- );
943
- const asset = nativeAsset || zeroAddressAsset;
944
- if (!asset?.decimals) {
945
- return {
946
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${gasAmount} gwei.`,
947
- asset: null,
948
- fee: null
949
- };
950
- }
951
- const formattedGasAmount = formatUnits(gasAmount, asset?.decimals);
952
- return {
953
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${formattedGasAmount} ${asset.symbol}.`,
954
- asset: null,
955
- fee: null
956
- };
957
- }
958
- if (BigNumber(gasBalance.amount ?? "").lt(Number(gasAmount))) {
959
- const asset = skipAssets?.find(
960
- (x) => x.denom?.includes("-native") || x.denom?.toLowerCase() === "0x0000000000000000000000000000000000000000"
961
- );
962
- if (!asset?.decimals) {
963
- return {
964
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${gasAmount} gwei but only have ${gasBalance.amount} gwei.`,
965
- asset: null,
966
- fee: null
967
- };
968
- }
969
- const formattedGasAmount = formatUnits(gasAmount, asset?.decimals);
970
- return {
971
- error: `Insufficient balance for gas on ${chain.prettyName}. Need ${formattedGasAmount} ${asset.symbol} but only have ${gasBalance.formattedAmount} ${asset.symbol}.`,
972
- asset: null,
973
- fee: null
974
- };
975
- }
976
- };
977
- var validateSvmGasBalance = async ({
978
- tx,
979
- simulate
980
- }) => {
981
- if (!tx) throw new Error("Transaction is required");
982
- if (simulate === false) {
983
- return {
984
- success: true,
985
- logs: [],
986
- error: null,
987
- asset: null,
988
- fee: null
989
- };
990
- }
991
- const endpoint = await getRpcEndpointForChain(tx.chainId ?? "");
992
- const connection = new Connection(endpoint);
993
- if (!connection) throw new Error(`Failed to connect to ${tx.chainId}`);
994
- if (!tx.tx) {
995
- throw new Error("Transaction is required");
996
- }
997
- const txBuffer = Buffer.from(tx.tx, "base64");
998
- let transaction;
999
- try {
1000
- transaction = Transaction.from(txBuffer);
1001
- } catch (decodeError) {
1002
- return {
1003
- success: false,
1004
- error: { decodeError: decodeError.message },
1005
- asset: null,
1006
- fee: null
1007
- };
1008
- }
1009
- const simulation = await connection.simulateTransaction(transaction);
1010
- if (simulation.value.err) {
1011
- const logs = simulation.value.logs ?? [];
1012
- const shortfall = getSolShortfall(logs);
1013
- const insufficientLamports = logs.some((log) => log.includes("insufficient lamports")) && shortfall !== null;
1014
- const insufficientFundsForRent = Object.keys(simulation.value.err).includes(
1015
- "InsufficientFundsForRent"
1016
- );
1017
- const errMsg = insufficientLamports ? `Insufficient balance for gas on Solana. You need ${shortfall.toFixed(6)} SOL to proceed.` : insufficientFundsForRent ? "Insufficient funds for rent on Solana. You need to fund your account." : "Simulation failed";
1018
- return {
1019
- success: false,
1020
- logs,
1021
- error: errMsg,
1022
- asset: null,
1023
- fee: null
1024
- };
1025
- }
1026
- return {
1027
- success: true,
1028
- logs: simulation.value.logs ?? [],
1029
- error: null,
1030
- asset: null,
1031
- fee: null
1032
- };
1033
- };
1034
- function getSolShortfall(logs) {
1035
- const line = logs.find((l) => l.includes("insufficient lamports"));
1036
- if (!line) return null;
1037
- const m = line.match(/insufficient lamports (\d+), need (\d+)/);
1038
- if (!m) return null;
1039
- const have = parseInt(m[1] ?? "0", 10);
1040
- const need = parseInt(m[2] ?? "0", 10);
1041
- const shortfallLamports = need - have;
1042
- return shortfallLamports / LAMPORTS_PER_SOL;
1043
- }
1044
-
1045
- // src/private-functions/validateGasBalances.ts
1046
- var validateGasBalances = async ({
1047
- txs,
1048
- onValidateGasBalance,
1049
- getFallbackGasAmount,
1050
- getCosmosSigner,
1051
- getEvmSigner,
1052
- simulate,
1053
- disabledChainIds,
1054
- enabledChainIds,
1055
- getCosmosPriorityFeeDenom,
1056
- routeId,
1057
- options,
1058
- isMultiRoutes
1059
- }) => {
1060
- const validateResult = await Promise.all(
1061
- txs.map(async (tx, i) => {
1062
- if (!tx) {
1063
- throw new Error(`invalid tx at index ${i}`);
1064
- }
1065
- if ("cosmosTx" in tx && !disabledChainIds?.includes(tx?.cosmosTx?.chainId ?? "") && (enabledChainIds === void 0 || enabledChainIds.includes(tx?.cosmosTx?.chainId ?? ""))) {
1066
- onValidateGasBalance?.({
1067
- status: "pending"
1068
- });
1069
- updateRouteDetails({
1070
- status: "validating",
1071
- routeId,
1072
- options
1073
- });
1074
- if (!tx?.cosmosTx?.msgs) {
1075
- throw new Error(`invalid msgs ${tx?.cosmosTx?.msgs}`);
1076
- }
1077
- try {
1078
- const res = await validateCosmosGasBalance({
1079
- chainId: tx.cosmosTx.chainId ?? "",
1080
- signerAddress: tx.cosmosTx.signerAddress ?? "",
1081
- messages: tx.cosmosTx.msgs,
1082
- getFallbackGasAmount,
1083
- getOfflineSigner: getCosmosSigner,
1084
- txIndex: i,
1085
- simulate,
1086
- getCosmosPriorityFeeDenom,
1087
- isMultiRoutes
1088
- });
1089
- return res;
1090
- } catch (e) {
1091
- const error = e;
1092
- return {
1093
- error: error.message,
1094
- asset: null,
1095
- fee: null
1096
- };
1097
- }
1098
- }
1099
- if ("evmTx" in tx && !disabledChainIds?.includes(tx?.evmTx?.chainId ?? "") && (enabledChainIds === void 0 || enabledChainIds.includes(tx?.evmTx?.chainId ?? ""))) {
1100
- onValidateGasBalance?.({
1101
- status: "pending"
1102
- });
1103
- updateRouteDetails({
1104
- status: "validating",
1105
- routeId,
1106
- options
1107
- });
1108
- const signer = await getEvmSigner?.(tx?.evmTx?.chainId ?? "");
1109
- if (!signer) {
1110
- throw new Error(
1111
- `failed to get signer for chain ${tx?.evmTx?.chainId}`
1112
- );
1113
- }
1114
- try {
1115
- const res = await validateEvmGasBalance({
1116
- tx: tx.evmTx,
1117
- signer,
1118
- getFallbackGasAmount,
1119
- useUnlimitedApproval: options?.useUnlimitedApproval,
1120
- bypassApprovalCheck: options?.bypassApprovalCheck
1121
- });
1122
- return res;
1123
- } catch (e) {
1124
- const error = e;
1125
- return {
1126
- error: error.message,
1127
- asset: null,
1128
- fee: null
1129
- };
1130
- }
1131
- }
1132
- if ("svmTx" in tx && !disabledChainIds?.includes(tx?.svmTx?.chainId ?? "") && (enabledChainIds === void 0 || enabledChainIds.includes(tx?.svmTx?.chainId ?? ""))) {
1133
- onValidateGasBalance?.({
1134
- status: "pending"
1135
- });
1136
- updateRouteDetails({
1137
- status: "validating",
1138
- routeId,
1139
- options
1140
- });
1141
- try {
1142
- const res = await validateSvmGasBalance({
1143
- tx: tx.svmTx,
1144
- simulate
1145
- });
1146
- return res;
1147
- } catch (e) {
1148
- const error = e;
1149
- return {
1150
- error: error.message,
1151
- asset: null,
1152
- fee: null
1153
- };
1154
- }
1155
- }
1156
- })
1157
- );
1158
- if (validateResult.filter(Boolean).length === 0) {
1159
- return;
1160
- }
1161
- const txError = validateResult.find((res) => res && res?.error !== null);
1162
- if (txError) {
1163
- onValidateGasBalance?.({
1164
- status: "error"
1165
- });
1166
- ClientState.validateGasResults = validateResult;
1167
- throw new Error(`${txError.error}`);
1168
- }
1169
- onValidateGasBalance?.({
1170
- status: "completed"
1171
- });
1172
- ClientState.validateGasResults = validateResult;
1173
- };
1174
-
1175
- // src/private-functions/getChainIdsFromTxs.ts
1176
- var getChainIdsFromTxs = (txs) => {
1177
- return txs.map((tx) => {
1178
- if ("cosmosTx" in tx) {
1179
- return {
1180
- chainType: "cosmos" /* Cosmos */,
1181
- chainId: tx.cosmosTx?.chainId
1182
- };
1183
- }
1184
- if ("svmTx" in tx) {
1185
- return {
1186
- chainType: "svm" /* Svm */,
1187
- chainId: tx.svmTx?.chainId
1188
- };
1189
- }
1190
- if ("evmTx" in tx) {
1191
- return {
1192
- chainType: "evm" /* Evm */,
1193
- chainId: tx.evmTx?.chainId
1194
- };
1195
- }
1196
- });
1197
- };
1198
-
1199
- // src/private-functions/executeTransactions.ts
1200
- var executeTransactions = async (options) => {
1201
- const {
1202
- txs,
1203
- onTransactionBroadcast,
1204
- simulate = true,
1205
- batchSimulate = true,
1206
- getFallbackGasAmount = getDefaultFallbackGasAmount,
1207
- getCosmosSigner,
1208
- getEvmSigner,
1209
- onValidateGasBalance,
1210
- trackTxPollingOptions,
1211
- batchSignTxs = true,
1212
- routeId,
1213
- isMultiRoutes
1214
- } = options;
1215
- if (txs === void 0) {
1216
- throw new Error(
1217
- "executeTransactions error: txs is undefined in executeTransactions"
1218
- );
1219
- }
1220
- const chainIds = getChainIdsFromTxs(txs);
1221
- const transactionDetails = txs.map((tx) => {
1222
- if ("cosmosTx" in tx) {
1223
- return { chainId: tx.cosmosTx?.chainId, chainType: "cosmos" /* Cosmos */ };
1224
- } else if ("evmTx" in tx) {
1225
- return { chainId: tx.evmTx?.chainId, chainType: "evm" /* Evm */ };
1226
- } else if ("svmTx" in tx) {
1227
- return { chainId: tx.svmTx?.chainId, chainType: "svm" /* Svm */ };
1228
- } else {
1229
- throw new Error("executeRoute error: invalid message type");
1230
- }
1231
- });
1232
- updateRouteDetails({
1233
- transactionDetails,
1234
- routeId,
1235
- options
1236
- });
1237
- const isGasStationSourceEVM = chainIds.find((item, i, array) => {
1238
- return GAS_STATION_CHAIN_IDS.includes(item?.chainId ?? "") && array[i - 1]?.chainType === "evm" /* Evm */;
1239
- });
1240
- ClientState.validateGasResults = void 0;
1241
- const validateChainIds = !batchSimulate ? chainIds.map((x) => x?.chainId ?? "") : isGasStationSourceEVM ? GAS_STATION_CHAIN_IDS : [];
1242
- await validateGasBalances({
1243
- txs,
1244
- getFallbackGasAmount,
1245
- getCosmosSigner,
1246
- getEvmSigner,
1247
- onValidateGasBalance,
1248
- simulate,
1249
- disabledChainIds: validateChainIds,
1250
- getCosmosPriorityFeeDenom: options.getCosmosPriorityFeeDenom,
1251
- options,
1252
- routeId,
1253
- isMultiRoutes
1254
- });
1255
- const validateEnabledChainIds = async (chainId) => {
1256
- await validateGasBalances({
1257
- txs,
1258
- getFallbackGasAmount,
1259
- getCosmosSigner,
1260
- getEvmSigner,
1261
- onValidateGasBalance,
1262
- simulate,
1263
- enabledChainIds: !batchSimulate ? [chainId] : validateChainIds,
1264
- getCosmosPriorityFeeDenom: options.getCosmosPriorityFeeDenom,
1265
- options,
1266
- routeId,
1267
- isMultiRoutes
1268
- });
1269
- };
1270
- let signedTxs = [];
1271
- if (batchSignTxs) {
1272
- for (let i = 0; i < txs.length; i++) {
1273
- const tx = txs[i];
1274
- if (!tx) {
1275
- throw new Error(`executeRoute error: invalid message at index ${i}`);
1276
- }
1277
- if ("cosmosTx" in tx) {
1278
- await validateEnabledChainIds(tx.cosmosTx?.chainId ?? "");
1279
- const isAllowedToBatchSignTxsUpfront = await (async () => {
1280
- try {
1281
- const currentUserAddress = options.userAddresses.find(
1282
- (x) => x.chainId === tx.cosmosTx?.chainId
1283
- )?.address;
1284
- if (!currentUserAddress) {
1285
- return false;
1286
- }
1287
- const { accountNumber } = await getAccountNumberAndSequence(
1288
- currentUserAddress,
1289
- tx.cosmosTx?.chainId
1290
- );
1291
- if (accountNumber) {
1292
- return true;
1293
- }
1294
- return false;
1295
- } catch (_error) {
1296
- return false;
1297
- }
1298
- })();
1299
- if (!isAllowedToBatchSignTxsUpfront) {
1300
- continue;
1301
- }
1302
- const signedTx = await signCosmosTransaction({
1303
- tx,
1304
- options,
1305
- index: i,
1306
- routeId
1307
- });
1308
- signedTxs.push({
1309
- index: i,
1310
- chainId: tx.cosmosTx?.chainId ?? "",
1311
- tx: signedTx,
1312
- chainType: "cosmos" /* Cosmos */
1313
- });
1314
- }
1315
- if ("svmTx" in tx) {
1316
- await validateEnabledChainIds(tx.svmTx?.chainId ?? "");
1317
- const signedTx = await signSvmTransaction({
1318
- tx,
1319
- options,
1320
- index: i,
1321
- routeId
1322
- });
1323
- if (!signedTx) {
1324
- throw new Error(`executeRoute error: signedTx is undefined`);
1325
- }
1326
- signedTxs.push({
1327
- index: i,
1328
- chainId: tx.svmTx?.chainId ?? "",
1329
- tx: signedTx.toString("base64"),
1330
- chainType: "svm" /* Svm */
1331
- });
1332
- }
1333
- }
1334
- }
1335
- const executeTransaction = async (index) => {
1336
- const tx = txs[index];
1337
- if (!tx) {
1338
- throw new Error(`executeRoute error: invalid message at index ${index}`);
1339
- }
1340
- let txResult;
1341
- const txSigned = signedTxs.find((item) => item.index === index);
1342
- if (txSigned) {
1343
- const txResponse = await submitTransaction({
1344
- chainId: txSigned.chainId,
1345
- tx: txSigned.tx
1346
- });
1347
- txResult = {
1348
- chainId: txSigned.chainId,
1349
- txHash: txResponse?.txHash ?? "",
1350
- explorerLink: txResponse?.explorerLink ?? ""
1351
- };
1352
- } else {
1353
- if ("cosmosTx" in tx) {
1354
- await validateEnabledChainIds(tx.cosmosTx?.chainId ?? "");
1355
- txResult = await executeCosmosTransaction({
1356
- tx,
1357
- options,
1358
- index,
1359
- routeId
1360
- });
1361
- } else if ("evmTx" in tx) {
1362
- await validateEnabledChainIds(tx.evmTx?.chainId ?? "");
1363
- const txResponse = await executeEvmTransaction(
1364
- tx,
1365
- options,
1366
- index,
1367
- routeId
1368
- );
1369
- txResult = {
1370
- chainId: tx?.evmTx?.chainId ?? "",
1371
- txHash: txResponse.transactionHash
1372
- };
1373
- } else if ("svmTx" in tx) {
1374
- await validateEnabledChainIds(tx.svmTx?.chainId ?? "");
1375
- txResult = await executeSvmTransaction(tx, options, index, routeId);
1376
- } else {
1377
- throw new Error("executeRoute error: invalid message type");
1378
- }
1379
- }
1380
- await onTransactionBroadcast?.({ ...txResult });
1381
- return txResult;
1382
- };
1383
- return {
1384
- transactionDetails,
1385
- executeTransaction
1386
- };
1387
- };
1388
- var EVM_GAS_AMOUNT = 15e4;
1389
- var COSMOS_GAS_AMOUNT = {
1390
- DEFAULT: 3e5,
1391
- SWAP: 28e5,
1392
- CARBON: 1e6
1393
- };
1394
- var getDefaultFallbackGasAmount = async (chainId, chainType) => {
1395
- if (chainType === "evm" /* Evm */) {
1396
- return EVM_GAS_AMOUNT;
1397
- }
1398
- if (chainType !== "cosmos" /* Cosmos */) return void 0;
1399
- const venuesResult = await venues();
1400
- const isSwapChain = venuesResult?.some(
1401
- (venue) => venue.chainId === chainId
1402
- ) ?? false;
1403
- const defaultGasAmount = Math.ceil(
1404
- isSwapChain ? COSMOS_GAS_AMOUNT.SWAP : COSMOS_GAS_AMOUNT.DEFAULT
1405
- );
1406
- if (chainId === "carbon-1") {
1407
- return COSMOS_GAS_AMOUNT.CARBON;
1408
- }
1409
- return defaultGasAmount;
1410
- };
1411
- var validateUserAddresses = async (userAddresses) => {
1412
- const chains2 = await ClientState.getSkipChains();
1413
- const validations = userAddresses.map((userAddress) => {
1414
- const chain = chains2.find((chain2) => chain2.chainId === userAddress.chainId);
1415
- switch (chain?.chainType) {
1416
- case "cosmos" /* Cosmos */:
1417
- try {
1418
- if (chain.chainId?.includes("penumbra")) {
1419
- try {
1420
- return chain.bech32Prefix === bech32m.decode(userAddress.address, 143)?.prefix;
1421
- } catch {
1422
- return ["penumbracompat1", "tpenumbra"].includes(
1423
- bech32.decode(userAddress.address, 1023).prefix
1424
- );
1425
- }
1426
- }
1427
- return chain.bech32Prefix === bech32.decode(userAddress.address, 1023).prefix;
1428
- } catch {
1429
- return false;
1430
- }
1431
- case "evm" /* Evm */:
1432
- try {
1433
- return isAddress(userAddress.address);
1434
- } catch (_error) {
1435
- return false;
1436
- }
1437
- case "svm" /* Svm */:
1438
- try {
1439
- const publicKey = new PublicKey(userAddress.address);
1440
- return PublicKey.isOnCurve(publicKey);
1441
- } catch (_error) {
1442
- return false;
1443
- }
1444
- default:
1445
- return false;
1446
- }
1447
- });
1448
- return validations.every((validation) => validation);
1449
- };
1450
- var createValidAddressList = async ({
1451
- userAddresses,
1452
- route
1453
- }) => {
1454
- let addressList = [];
1455
- userAddresses.forEach((userAddress, index) => {
1456
- const requiredChainAddress = route.requiredChainAddresses[index];
1457
- if (requiredChainAddress === userAddress?.chainId) {
1458
- addressList.push(userAddress.address);
1459
- }
1460
- });
1461
- if (addressList.length !== route.requiredChainAddresses.length) {
1462
- addressList = userAddresses.map((x) => x.address);
1463
- }
1464
- const validLength = addressList.length === route.requiredChainAddresses.length || addressList.length === route.chainIds?.length;
1465
- if (!validLength) {
1466
- throw new Error("createValidAddressList error: invalid address list");
1467
- }
1468
- const isUserAddressesValid = await validateUserAddresses(userAddresses);
1469
- if (!isUserAddressesValid) {
1470
- throw new Error("createValidAddressList error: invalid user addresses");
1471
- }
1472
- return addressList;
1473
- };
1474
-
1475
- export { createValidAddressList, executeTransactions };