@trustware/sdk-staging 1.1.9-staging.6 → 1.1.10-staging.0

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 (40) hide show
  1. package/LICENSE +5 -4
  2. package/README.md +32 -1
  3. package/THIRD_PARTY_NOTICES.md +118 -0
  4. package/dist/constants.cjs +1 -1
  5. package/dist/constants.mjs +1 -1
  6. package/dist/{core-BTPkApRH.d.cts → core-B7Ez-5-r.d.cts} +3 -2
  7. package/dist/{core-2oZuxC1J.d.ts → core-BPLiD1UG.d.ts} +3 -2
  8. package/dist/core.cjs +246 -48
  9. package/dist/core.cjs.map +1 -1
  10. package/dist/core.d.cts +2 -2
  11. package/dist/core.d.ts +2 -2
  12. package/dist/core.mjs +247 -48
  13. package/dist/core.mjs.map +1 -1
  14. package/dist/index.cjs +300 -76
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +5 -5
  17. package/dist/index.d.ts +5 -5
  18. package/dist/index.mjs +325 -103
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/{manager-BMO1O-cW.d.ts → manager-B6NNV-E_.d.ts} +129 -18
  21. package/dist/{manager-BZwbtOyf.d.cts → manager-BwjyFjjz.d.cts} +129 -18
  22. package/dist/{detect-B8xXLwHK.d.ts → metadata-BiTMMvlY.d.ts} +5 -2
  23. package/dist/{detect-C8xpZRrL.d.cts → metadata-HCflXcsF.d.cts} +5 -2
  24. package/dist/smart-account.cjs +117 -39
  25. package/dist/smart-account.cjs.map +1 -1
  26. package/dist/smart-account.d.cts +235 -222
  27. package/dist/smart-account.d.ts +235 -222
  28. package/dist/smart-account.mjs +117 -39
  29. package/dist/smart-account.mjs.map +1 -1
  30. package/dist/wallet.cjs +113 -36
  31. package/dist/wallet.cjs.map +1 -1
  32. package/dist/wallet.d.cts +4 -7
  33. package/dist/wallet.d.ts +4 -7
  34. package/dist/wallet.mjs +113 -36
  35. package/dist/wallet.mjs.map +1 -1
  36. package/dist/widget.cjs +239 -54
  37. package/dist/widget.cjs.map +1 -1
  38. package/dist/widget.mjs +267 -81
  39. package/dist/widget.mjs.map +1 -1
  40. package/package.json +3 -2
package/dist/core.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { T as Trustware, a as TrustwareCore } from './core-BTPkApRH.cjs';
2
- import './manager-BZwbtOyf.cjs';
1
+ export { T as Trustware, a as TrustwareCore } from './core-B7Ez-5-r.cjs';
2
+ import './manager-BwjyFjjz.cjs';
3
3
  import './blockchain-BxAFzp0s.cjs';
4
4
  import './types-DX3HtFcn.cjs';
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { T as Trustware, a as TrustwareCore } from './core-2oZuxC1J.js';
2
- import './manager-BMO1O-cW.js';
1
+ export { T as Trustware, a as TrustwareCore } from './core-BPLiD1UG.js';
2
+ import './manager-B6NNV-E_.js';
3
3
  import './blockchain-BxAFzp0s.js';
4
4
  import './types-BJY9r-mz.js';
package/dist/core.mjs CHANGED
@@ -53,7 +53,7 @@ var init_constants = __esm({
53
53
  "src/constants.ts"() {
54
54
  "use strict";
55
55
  SDK_NAME = "@trustware/sdk";
56
- SDK_VERSION = "1.1.9-staging.6";
56
+ SDK_VERSION = "1.1.10-staging.0";
57
57
  API_ROOT = "https://bv-staging-api.trustware.io";
58
58
  API_PREFIX = "/api";
59
59
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -262,7 +262,9 @@ var init_chains = __esm({
262
262
  btc: "bitcoin",
263
263
  bitcoin: "bitcoin",
264
264
  sei: "cosmos",
265
- "pacific-1": "cosmos"
265
+ "pacific-1": "cosmos",
266
+ nibiru: "cosmos",
267
+ "cataclysm-1": "cosmos"
266
268
  };
267
269
  }
268
270
  });
@@ -1459,16 +1461,23 @@ function validateEvmAddress(address) {
1459
1461
  }
1460
1462
  return { isValid: true };
1461
1463
  }
1462
- function validateSeiAddress(address) {
1464
+ function resolveCosmosBech32Prefix(chain) {
1465
+ const chainDef = typeof chain === "object" && chain ? chain : void 0;
1466
+ const identifier = chainDef?.networkIdentifier ?? chainDef?.chainId ?? chainDef?.id ?? (typeof chain === "string" ? chain : void 0);
1467
+ const normalized = String(identifier ?? "").trim().toLowerCase();
1468
+ return COSMOS_BECH32_PREFIX_BY_CHAIN_ID[normalized] ?? "sei";
1469
+ }
1470
+ function validateCosmosAddress(address, chain) {
1463
1471
  const trimmed = address.trim();
1464
- if (isEvmAddress(trimmed)) {
1472
+ const prefix = resolveCosmosBech32Prefix(chain);
1473
+ if (prefix === "sei" && isEvmAddress(trimmed)) {
1465
1474
  return { isValid: true };
1466
1475
  }
1467
- const result = validateBech32LikeAddress(trimmed, "sei");
1476
+ const result = validateBech32LikeAddress(trimmed, prefix);
1468
1477
  if (result.isValid) return result;
1469
1478
  return {
1470
1479
  isValid: false,
1471
- error: "SEI addresses must be 0x-prefixed EVM or sei1 bech32 strings."
1480
+ error: prefix === "sei" ? "SEI addresses must be 0x-prefixed EVM or sei1 bech32 strings." : `Address must be a valid ${prefix}1 bech32 string.`
1472
1481
  };
1473
1482
  }
1474
1483
  function validateSolanaAddress(address) {
@@ -1518,15 +1527,12 @@ function validateAddressForChain(address, chain) {
1518
1527
  case "bitcoin":
1519
1528
  return validateBtcAddress(trimmed);
1520
1529
  case "cosmos":
1521
- if (chainDef?.networkIdentifier?.toLowerCase() === "sei") {
1522
- return validateSeiAddress(trimmed);
1523
- }
1524
- return validateBech32LikeAddress(trimmed, "sei");
1530
+ return validateCosmosAddress(trimmed, chainDef ?? chain);
1525
1531
  default:
1526
1532
  return { isValid: false, error: "Unsupported or unknown chain type." };
1527
1533
  }
1528
1534
  }
1529
- function validateAddressForRouteChain(address, chainType) {
1535
+ function validateAddressForRouteChain(address, chainType, chainRef) {
1530
1536
  switch (normalizeChainType(chainType)) {
1531
1537
  case "evm":
1532
1538
  return validateEvmAddress(address);
@@ -1535,7 +1541,7 @@ function validateAddressForRouteChain(address, chainType) {
1535
1541
  case "bitcoin":
1536
1542
  return validateBtcAddress(address);
1537
1543
  case "cosmos":
1538
- return validateSeiAddress(address);
1544
+ return validateCosmosAddress(address, chainRef ?? chainType);
1539
1545
  default:
1540
1546
  return { isValid: false, error: "Unsupported chain type." };
1541
1547
  }
@@ -1557,14 +1563,18 @@ function validateRouteAddresses(params) {
1557
1563
  const normalizedDirection = params.direction?.trim().toLowerCase();
1558
1564
  const isDepositFlow = normalizedDirection === "deposit" || (toType === "evm" || toType === "cosmos") && (fromType === "bitcoin" || fromType === "solana");
1559
1565
  if (isDepositFlow) {
1560
- const fromResult2 = validateAddressForRouteChain(fromAddress, fromType);
1566
+ const fromResult2 = validateAddressForRouteChain(
1567
+ fromAddress,
1568
+ fromType,
1569
+ params.fromChain
1570
+ );
1561
1571
  if (!fromResult2.isValid) {
1562
1572
  return {
1563
1573
  isValid: false,
1564
1574
  error: `From address: ${fromResult2.error ?? "Invalid address."}`
1565
1575
  };
1566
1576
  }
1567
- const toResult2 = toType === "cosmos" ? validateSeiAddress(toAddress) : validateEvmAddress(toAddress);
1577
+ const toResult2 = toType === "cosmos" ? validateCosmosAddress(toAddress, params.toChain) : validateEvmAddress(toAddress);
1568
1578
  if (!toResult2.isValid) {
1569
1579
  return {
1570
1580
  isValid: false,
@@ -1589,14 +1599,22 @@ function validateRouteAddresses(params) {
1589
1599
  }
1590
1600
  return { isValid: true };
1591
1601
  }
1592
- const fromResult = validateAddressForRouteChain(fromAddress, fromType);
1602
+ const fromResult = validateAddressForRouteChain(
1603
+ fromAddress,
1604
+ fromType,
1605
+ params.fromChain
1606
+ );
1593
1607
  if (!fromResult.isValid) {
1594
1608
  return {
1595
1609
  isValid: false,
1596
1610
  error: `From address: ${fromResult.error ?? "Invalid address."}`
1597
1611
  };
1598
1612
  }
1599
- const toResult = validateAddressForRouteChain(toAddress, toType);
1613
+ const toResult = validateAddressForRouteChain(
1614
+ toAddress,
1615
+ toType,
1616
+ params.toChain
1617
+ );
1600
1618
  if (!toResult.isValid) {
1601
1619
  return {
1602
1620
  isValid: false,
@@ -1605,13 +1623,19 @@ function validateRouteAddresses(params) {
1605
1623
  }
1606
1624
  return { isValid: true };
1607
1625
  }
1608
- var BECH32_CHARSET;
1626
+ var BECH32_CHARSET, COSMOS_BECH32_PREFIX_BY_CHAIN_ID;
1609
1627
  var init_address = __esm({
1610
1628
  "src/validation/address.ts"() {
1611
1629
  "use strict";
1612
1630
  init_index_node4();
1613
1631
  init_chains();
1614
1632
  BECH32_CHARSET = /^[023456789acdefghjklmnpqrstuvwxyz]+$/i;
1633
+ COSMOS_BECH32_PREFIX_BY_CHAIN_ID = {
1634
+ "pacific-1": "sei",
1635
+ sei: "sei",
1636
+ "cataclysm-1": "nibi",
1637
+ nibiru: "nibi"
1638
+ };
1615
1639
  }
1616
1640
  });
1617
1641
 
@@ -2009,6 +2033,20 @@ async function requestSDKRPC(path, init = {}) {
2009
2033
  }
2010
2034
  );
2011
2035
  }
2036
+ async function getEVMAllowance(params) {
2037
+ const search = new URLSearchParams(params);
2038
+ return requestSDKRPC(
2039
+ `/evm/allowance?${search.toString()}`,
2040
+ { method: "GET" }
2041
+ );
2042
+ }
2043
+ async function getEVMTxStatus(params) {
2044
+ const search = new URLSearchParams(params);
2045
+ return requestSDKRPC(
2046
+ `/evm/tx-status?${search.toString()}`,
2047
+ { method: "GET" }
2048
+ );
2049
+ }
2012
2050
  async function sendSolanaSerialized(body) {
2013
2051
  return requestSDKRPC(
2014
2052
  "/solana/send-serialized",
@@ -3882,6 +3920,27 @@ var init_wallets = __esm({
3882
3920
  });
3883
3921
 
3884
3922
  // src/core/routes.ts
3923
+ function assertValidPostHook(hooks) {
3924
+ const postHook = hooks?.postHook;
3925
+ if (!postHook) return;
3926
+ if (!postHook.target?.trim()) {
3927
+ throw new Error("hooks.postHook.target is required.");
3928
+ }
3929
+ if (!postHook.callData?.trim()) {
3930
+ throw new Error("hooks.postHook.callData is required.");
3931
+ }
3932
+ if (postHook.fullAmount) {
3933
+ if (postHook.amountInputPos === void 0) {
3934
+ throw new Error(
3935
+ "hooks.postHook.amountInputPos is required when fullAmount is true."
3936
+ );
3937
+ }
3938
+ } else if (!postHook.fundAmount?.trim()) {
3939
+ throw new Error(
3940
+ "hooks.postHook.fundAmount is required unless fullAmount is set."
3941
+ );
3942
+ }
3943
+ }
3885
3944
  function isEvmTxRequest(txReq) {
3886
3945
  return Boolean(txReq?.data && (txReq.to || txReq.target));
3887
3946
  }
@@ -3900,6 +3959,7 @@ async function buildRoute(body, signal) {
3900
3959
  if (!addressValidation.isValid) {
3901
3960
  throw new Error(addressValidation.error || "Invalid route addresses.");
3902
3961
  }
3962
+ assertValidPostHook(body.hooks);
3903
3963
  const cfg = TrustwareConfigStore.get();
3904
3964
  const url = `${apiBase()}/v1/routes/route`;
3905
3965
  const payload = {
@@ -3938,6 +3998,7 @@ async function buildRoute(body, signal) {
3938
3998
  return { intentId, txReq, actions, finalExchangeRate, route, sponsorship };
3939
3999
  }
3940
4000
  async function buildDepositAddress(body, signal) {
4001
+ assertValidPostHook(body.hooks);
3941
4002
  const cfg = TrustwareConfigStore.get();
3942
4003
  const url = `${apiBase()}/v1/routes/deposit-address`;
3943
4004
  const payload = {
@@ -3979,7 +4040,7 @@ async function buildDepositAddress(body, signal) {
3979
4040
  route
3980
4041
  };
3981
4042
  }
3982
- async function submitReceipt(intentId, txHash, sponsorshipRequestId) {
4043
+ async function submitReceipt(intentId, txHash, sponsorshipRequestId, eoaAddress) {
3983
4044
  const r = await rateLimitedFetch(
3984
4045
  `${apiBase()}/v1/route-intent/${intentId}/receipt`,
3985
4046
  {
@@ -3987,7 +4048,8 @@ async function submitReceipt(intentId, txHash, sponsorshipRequestId) {
3987
4048
  headers: jsonHeaders({ "Idempotency-Key": txHash }),
3988
4049
  body: JSON.stringify({
3989
4050
  txHash,
3990
- ...sponsorshipRequestId ? { sponsorshipRequestId } : {}
4051
+ ...sponsorshipRequestId ? { sponsorshipRequestId } : {},
4052
+ ...eoaAddress ? { eoaAddress } : {}
3991
4053
  })
3992
4054
  }
3993
4055
  );
@@ -4109,7 +4171,9 @@ var init_chainHelpers = __esm({
4109
4171
  btc: "bitcoin",
4110
4172
  bitcoin: "bitcoin",
4111
4173
  sei: "cosmos",
4112
- "pacific-1": "cosmos"
4174
+ "pacific-1": "cosmos",
4175
+ nibiru: "cosmos",
4176
+ "cataclysm-1": "cosmos"
4113
4177
  };
4114
4178
  SEI_EVM_CHAIN_ID = "1329";
4115
4179
  SEI_COSMOS_CHAIN_ID = "pacific-1";
@@ -4264,7 +4328,8 @@ function filterSupportedChains(chains) {
4264
4328
  }
4265
4329
  if (chainType === "cosmos") {
4266
4330
  const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
4267
- if (seiKey !== "sei" && seiKey !== "pacific-1") {
4331
+ const isNibiru = normalizeChainKey2(chain.chainId ?? chain.id) === NIBIRU_COSMOS_CHAIN_ID;
4332
+ if (seiKey !== "sei" && !isNibiru) {
4268
4333
  return false;
4269
4334
  }
4270
4335
  }
@@ -4364,7 +4429,7 @@ function useChains() {
4364
4429
  error
4365
4430
  };
4366
4431
  }
4367
- var POPULAR_CHAINS_BY_TVL, POPULAR_LIMIT;
4432
+ var POPULAR_CHAINS_BY_TVL, POPULAR_LIMIT, NIBIRU_COSMOS_CHAIN_ID;
4368
4433
  var init_useChains = __esm({
4369
4434
  "src/core/useChains.ts"() {
4370
4435
  "use strict";
@@ -4374,6 +4439,7 @@ var init_useChains = __esm({
4374
4439
  init_popularChains();
4375
4440
  POPULAR_CHAINS_BY_TVL = popularChains_default.byTvl;
4376
4441
  POPULAR_LIMIT = popularChains_default.popularLimit;
4442
+ NIBIRU_COSMOS_CHAIN_ID = "cataclysm-1";
4377
4443
  }
4378
4444
  });
4379
4445
 
@@ -6158,46 +6224,80 @@ function normalizeSlippage(v) {
6158
6224
  if (n > 5) return 5;
6159
6225
  return n;
6160
6226
  }
6227
+ function warnDeprecatedSwapModeFlag() {
6228
+ if (hasWarnedDeprecatedSwapModeFlag) return;
6229
+ hasWarnedDeprecatedSwapModeFlag = true;
6230
+ console.warn(
6231
+ '[Trustware SDK] `features.swapMode` is deprecated \u2014 use `mode: "swap"` on the top-level config instead.'
6232
+ );
6233
+ }
6234
+ function resolveMode(input) {
6235
+ if (input.mode === "swap") return "swap";
6236
+ if (input.mode === "deposit") return "deposit";
6237
+ if (input.features?.swapMode) {
6238
+ warnDeprecatedSwapModeFlag();
6239
+ return "swap";
6240
+ }
6241
+ return "deposit";
6242
+ }
6161
6243
  function resolveConfig(input) {
6162
6244
  if (!input?.apiKey) {
6163
- throw new Error("TrustwareConfig: 'apiKey' is required.");
6245
+ throw new TrustwareError({
6246
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6247
+ message: "TrustwareConfig: 'apiKey' is required.",
6248
+ userMessage: "Missing required API key configuration."
6249
+ });
6164
6250
  }
6165
- if (!input.routes?.toChain || !input.routes?.toToken) {
6166
- throw new Error(
6167
- "TrustwareConfig: 'routes.toChain' and 'routes.toToken' are required."
6168
- );
6251
+ const mode = resolveMode(input);
6252
+ if (mode === "deposit" && (!input.routes?.toChain || !input.routes?.toToken)) {
6253
+ throw new TrustwareError({
6254
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6255
+ message: "TrustwareConfig: 'routes.toChain' and 'routes.toToken' are required in deposit mode.",
6256
+ userMessage: "Missing required destination chain/token configuration."
6257
+ });
6169
6258
  }
6170
- const toChain = input.routes.toChain;
6171
- if (input.routes.toAddress) {
6259
+ const toChain = input.routes?.toChain;
6260
+ if (input.routes?.toAddress && toChain) {
6172
6261
  const result = validateAddressForChain(input.routes.toAddress, toChain);
6173
6262
  if (!result.isValid) {
6174
6263
  console.error(`[Trustware SDK] Invalid toAddress: ${result.error}`);
6175
- throw new Error(`Invalid toAddress: ${result.error}`);
6264
+ throw new TrustwareError({
6265
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6266
+ message: `Invalid toAddress: ${result.error}`,
6267
+ userMessage: "The configured destination address is invalid."
6268
+ });
6176
6269
  }
6177
6270
  }
6178
- if (input.routes.fromAddress) {
6179
- const result = validateAddressForChain(
6180
- input.routes.fromAddress,
6181
- input.routes.fromChain ?? toChain
6182
- );
6183
- if (!result.isValid) {
6184
- console.error(`[Trustware SDK] Invalid fromAddress: ${result.error}`);
6185
- throw new Error(`Invalid fromAddress: ${result.error}`);
6271
+ if (input.routes?.fromAddress) {
6272
+ const fromChain = input.routes.fromChain ?? toChain;
6273
+ if (fromChain) {
6274
+ const result = validateAddressForChain(
6275
+ input.routes.fromAddress,
6276
+ fromChain
6277
+ );
6278
+ if (!result.isValid) {
6279
+ console.error(`[Trustware SDK] Invalid fromAddress: ${result.error}`);
6280
+ throw new TrustwareError({
6281
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6282
+ message: `Invalid fromAddress: ${result.error}`,
6283
+ userMessage: "The configured source address is invalid."
6284
+ });
6285
+ }
6186
6286
  }
6187
6287
  }
6188
6288
  const autoDetectProvider = typeof input.autoDetectProvider === "boolean" ? input.autoDetectProvider : DEFAULT_AUTO_DETECT_PROVIDER;
6189
6289
  const routes = {
6190
- toChain: input.routes.toChain,
6191
- toToken: input.routes.toToken,
6192
- fromToken: input.routes.fromToken,
6193
- fromAddress: input.routes.fromAddress,
6194
- fromChain: input.routes.fromChain,
6195
- toAddress: input.routes.toAddress,
6290
+ toChain: input.routes?.toChain ?? "",
6291
+ toToken: input.routes?.toToken ?? "",
6292
+ fromToken: input.routes?.fromToken,
6293
+ fromAddress: input.routes?.fromAddress,
6294
+ fromChain: input.routes?.fromChain,
6295
+ toAddress: input.routes?.toAddress,
6196
6296
  defaultSlippage: normalizeSlippage(
6197
- input.routes.defaultSlippage ?? DEFAULT_SLIPPAGE
6297
+ input.routes?.defaultSlippage ?? DEFAULT_SLIPPAGE
6198
6298
  ),
6199
6299
  options: {
6200
- ...input.routes.options
6300
+ ...input.routes?.options
6201
6301
  }
6202
6302
  };
6203
6303
  const theme = input.theme ?? "system";
@@ -6216,13 +6316,16 @@ function resolveConfig(input) {
6216
6316
  tokensPagination: input.features?.tokensPagination ?? DEFAULT_FEATURE_FLAGS.tokensPagination,
6217
6317
  balanceStreaming: input.features?.balanceStreaming ?? DEFAULT_FEATURE_FLAGS.balanceStreaming,
6218
6318
  shouldAllowGA4: input.features?.shouldAllowGA4 ?? DEFAULT_FEATURE_FLAGS.shouldAllowGA4,
6219
- swapMode: input.features?.swapMode ?? DEFAULT_FEATURE_FLAGS.swapMode,
6319
+ // Always mirrors the canonical `mode`, however the caller set it (new `mode` field
6320
+ // or the deprecated `features.swapMode` flag).
6321
+ swapMode: mode === "swap",
6220
6322
  swapDefaultDestToken: input.features?.swapDefaultDestToken ?? DEFAULT_FEATURE_FLAGS.swapDefaultDestToken,
6221
6323
  swapLockDestToken: input.features?.swapLockDestToken ?? DEFAULT_FEATURE_FLAGS.swapLockDestToken,
6222
6324
  swapAllowedDestTokens: input.features?.swapAllowedDestTokens ?? DEFAULT_FEATURE_FLAGS.swapAllowedDestTokens
6223
6325
  };
6224
6326
  return {
6225
6327
  apiKey: input.apiKey,
6328
+ mode,
6226
6329
  routes,
6227
6330
  autoDetectProvider,
6228
6331
  theme,
@@ -6235,12 +6338,15 @@ function resolveConfig(input) {
6235
6338
  onEvent: input.onEvent
6236
6339
  };
6237
6340
  }
6341
+ var hasWarnedDeprecatedSwapModeFlag;
6238
6342
  var init_merge = __esm({
6239
6343
  "src/config/merge.ts"() {
6240
6344
  "use strict";
6241
6345
  init_defaults();
6242
6346
  init_config();
6243
6347
  init_index();
6348
+ init_TrustwareError();
6349
+ hasWarnedDeprecatedSwapModeFlag = false;
6244
6350
  }
6245
6351
  });
6246
6352
 
@@ -6325,11 +6431,92 @@ var init_store = __esm({
6325
6431
  });
6326
6432
 
6327
6433
  // src/core/tx.ts
6328
- import { keccak256 } from "viem";
6434
+ import { keccak256, encodeFunctionData, parseAbi } from "viem";
6329
6435
  function backendChainId(chain, fallback) {
6330
6436
  const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6331
6437
  return String(preferred ?? fallback ?? "");
6332
6438
  }
6439
+ function sleep2(ms) {
6440
+ return new Promise((resolve) => setTimeout(resolve, ms));
6441
+ }
6442
+ async function sendEvmTx(w, tx) {
6443
+ if (w.type === "eip1193") {
6444
+ const from = await w.getAddress();
6445
+ const params = {
6446
+ from,
6447
+ to: tx.to,
6448
+ data: tx.data,
6449
+ value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
6450
+ };
6451
+ if (tx.chainId !== void 0) {
6452
+ params.chainId = `0x${tx.chainId.toString(16)}`;
6453
+ }
6454
+ const hash = await w.request({
6455
+ method: "eth_sendTransaction",
6456
+ params: [params]
6457
+ });
6458
+ return hash;
6459
+ }
6460
+ const response = await w.sendTransaction({
6461
+ to: tx.to,
6462
+ data: tx.data,
6463
+ value: tx.value,
6464
+ chainId: tx.chainId
6465
+ });
6466
+ return response.hash;
6467
+ }
6468
+ async function waitForTxConfirmation(chainId, txHash) {
6469
+ const timeoutMs = 12e4;
6470
+ const intervalMs = 2e3;
6471
+ const started = Date.now();
6472
+ while (Date.now() - started < timeoutMs) {
6473
+ const status = await getEVMTxStatus({ chainId, txHash });
6474
+ if (status.status === "success") return;
6475
+ if (status.status === "reverted") {
6476
+ throw new Error("Approval transaction reverted");
6477
+ }
6478
+ await sleep2(intervalMs);
6479
+ }
6480
+ throw new Error("Timed out waiting for approval confirmation");
6481
+ }
6482
+ async function ensureApprovals(w, approvals, fallbackChainId) {
6483
+ if (!approvals || approvals.length === 0) return;
6484
+ const owner = await w.getAddress();
6485
+ for (const approval of approvals) {
6486
+ const spender = approval.spender;
6487
+ const tokenAddress = approval.tokenAddress;
6488
+ const amount = approval.amount;
6489
+ if (!spender || !tokenAddress || !amount) continue;
6490
+ const chainId = approval.chainId || String(fallbackChainId ?? "");
6491
+ if (!chainId) continue;
6492
+ const amountWei = BigInt(amount);
6493
+ if (amountWei === 0n) continue;
6494
+ let currentAllowance = 0n;
6495
+ try {
6496
+ const { allowance } = await getEVMAllowance({
6497
+ chainId,
6498
+ tokenAddress,
6499
+ ownerAddress: owner,
6500
+ spenderAddress: spender
6501
+ });
6502
+ currentAllowance = BigInt(allowance || "0");
6503
+ } catch {
6504
+ }
6505
+ if (currentAllowance >= amountWei) continue;
6506
+ const data = encodeFunctionData({
6507
+ abi: erc20ApproveAbi,
6508
+ functionName: "approve",
6509
+ args: [spender, amountWei]
6510
+ });
6511
+ const hash = await sendEvmTx(w, {
6512
+ to: tokenAddress,
6513
+ data,
6514
+ value: 0n,
6515
+ chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
6516
+ });
6517
+ await waitForTxConfirmation(chainId, hash);
6518
+ }
6519
+ }
6333
6520
  function isUserRejected(e2) {
6334
6521
  const code = e2?.code ?? e2?.data?.code;
6335
6522
  if (code === 4001) return true;
@@ -6363,6 +6550,13 @@ async function sendRouteTransaction(b, fallbackChainId) {
6363
6550
  }
6364
6551
  }
6365
6552
  }
6553
+ if (!validatedSponsorship) {
6554
+ await ensureApprovals(
6555
+ w,
6556
+ b.route?.execution?.approvals,
6557
+ Number.isFinite(target) ? target : void 0
6558
+ );
6559
+ }
6366
6560
  if (w.type === "eip1193") {
6367
6561
  const from = await w.getAddress();
6368
6562
  const hexValue = value ? `0x${value.toString(16)}` : "0x0";
@@ -6459,11 +6653,16 @@ async function runTopUp(params) {
6459
6653
  }
6460
6654
  }
6461
6655
  }
6656
+ var erc20ApproveAbi;
6462
6657
  var init_tx = __esm({
6463
6658
  "src/core/tx.ts"() {
6464
6659
  "use strict";
6465
6660
  init_wallets();
6466
6661
  init_routes();
6662
+ init_sdkRpc();
6663
+ erc20ApproveAbi = parseAbi([
6664
+ "function approve(address spender, uint256 amount) returns (bool)"
6665
+ ]);
6467
6666
  }
6468
6667
  });
6469
6668