@trustware/sdk-staging 1.1.12-staging.2 → 1.1.12-staging.4

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.
package/dist/index.cjs CHANGED
@@ -514,7 +514,7 @@ var init_constants = __esm({
514
514
  "src/constants.ts"() {
515
515
  "use strict";
516
516
  SDK_NAME = "@trustware/sdk";
517
- SDK_VERSION = "1.1.12-staging.2";
517
+ SDK_VERSION = "1.1.12-staging.4";
518
518
  API_ROOT = "https://bv-staging-api.trustware.io";
519
519
  GTM_ID = "GTM-TZDGNCXB";
520
520
  API_PREFIX = "/api";
@@ -2472,6 +2472,7 @@ function inferChainTypeFromValue(normalized) {
2472
2472
  if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
2473
2473
  return normalized;
2474
2474
  }
2475
+ if (normalized === SOLANA_CHAIN_ID) return "solana";
2475
2476
  if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
2476
2477
  return "evm";
2477
2478
  }
@@ -2518,12 +2519,13 @@ function isZeroAddressLike(address, chainType) {
2518
2519
  const normalized = normalizeAddress(address, chainType);
2519
2520
  return normalized === normalizeAddress(getNativeTokenAddress(chainType), chainType) || normalized === "0x0000000000000000000000000000000000000000";
2520
2521
  }
2521
- var NATIVE_EVM, NATIVE_SOLANA, CHAIN_TYPE_ALIASES;
2522
+ var NATIVE_EVM, NATIVE_SOLANA, SOLANA_CHAIN_ID, CHAIN_TYPE_ALIASES;
2522
2523
  var init_chains = __esm({
2523
2524
  "src/utils/chains.ts"() {
2524
2525
  "use strict";
2525
2526
  NATIVE_EVM = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
2526
2527
  NATIVE_SOLANA = "So11111111111111111111111111111111111111111";
2528
+ SOLANA_CHAIN_ID = "1151111081099710";
2527
2529
  CHAIN_TYPE_ALIASES = {
2528
2530
  btc: "bitcoin",
2529
2531
  bitcoin: "bitcoin",
@@ -4426,7 +4428,159 @@ var init_wallets = __esm({
4426
4428
  }
4427
4429
  });
4428
4430
 
4431
+ // src/widget/helpers/chainHelpers.ts
4432
+ function normalizeChainKey2(id) {
4433
+ if (id === void 0 || id === null) return "";
4434
+ return String(id).trim().toLowerCase();
4435
+ }
4436
+ function getNativeTokenAddress2(chainType) {
4437
+ const normalized = chainType?.toLowerCase?.();
4438
+ return normalized === "solana" ? NATIVE_SOLANA2 : NATIVE_EVM2;
4439
+ }
4440
+ function isSolanaNativeTokenAlias2(address) {
4441
+ if (!address) return false;
4442
+ const trimmed = address.trim();
4443
+ if (!trimmed) return false;
4444
+ return trimmed === NATIVE_SOLANA2 || trimmed.toLowerCase() === NATIVE_EVM2;
4445
+ }
4446
+ function parseDecimalToWei(input, decimals) {
4447
+ if (!input?.trim()) return null;
4448
+ const s = input.trim();
4449
+ if (!/^\d*\.?\d*$/.test(s)) return null;
4450
+ const [intPartRaw, fracRaw = ""] = s.split(".");
4451
+ const intPart = intPartRaw.length ? BigInt(intPartRaw) : 0n;
4452
+ const frac = (fracRaw + "0".repeat(decimals)).slice(0, decimals);
4453
+ const fracPart = frac ? BigInt(frac) : 0n;
4454
+ const base2 = 10n ** BigInt(decimals);
4455
+ return intPart * base2 + fracPart;
4456
+ }
4457
+ function inferChainTypeFromValue2(normalized) {
4458
+ if (!normalized) return void 0;
4459
+ const aliased = CHAIN_TYPE_ALIASES2[normalized];
4460
+ if (aliased) return aliased;
4461
+ if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
4462
+ return normalized;
4463
+ }
4464
+ if (normalized === SOLANA_CHAIN_ID2) return "solana";
4465
+ if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
4466
+ return "evm";
4467
+ }
4468
+ if (normalized.startsWith("solana:") || normalized.includes("solana")) {
4469
+ return "solana";
4470
+ }
4471
+ if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
4472
+ return "cosmos";
4473
+ }
4474
+ return void 0;
4475
+ }
4476
+ function normalizeChainType2(chain) {
4477
+ if (!chain) return void 0;
4478
+ const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
4479
+ if (!raw) return void 0;
4480
+ const normalized = String(raw).trim().toLowerCase();
4481
+ return inferChainTypeFromValue2(normalized) ?? normalized;
4482
+ }
4483
+ function canonicalChainKeyForLink(chain) {
4484
+ const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
4485
+ if (seiKey) return seiKey;
4486
+ return normalizeChainKey2(
4487
+ chain.networkIdentifier ?? chain.axelarChainName ?? chain.id ?? chain.chainId ?? chain.networkName
4488
+ );
4489
+ }
4490
+ function canonicalSeiChainKey(chainId) {
4491
+ const normalized = normalizeChainKey2(chainId);
4492
+ if (!normalized) return null;
4493
+ if (normalized === SEI_EVM_CHAIN_ID) return "sei-evm";
4494
+ if (normalized === SEI_COSMOS_CHAIN_ID) return "sei";
4495
+ return null;
4496
+ }
4497
+ function isZeroAddrLike(a, chainType) {
4498
+ if (!a) return true;
4499
+ if (!chainType) return false;
4500
+ const s = normalizeAddress2(a, chainType);
4501
+ return s === normalizeAddress2(getNativeTokenAddress2(chainType), chainType) || s === "0x0000000000000000000000000000000000000000";
4502
+ }
4503
+ function normalizeAddress2(address, chainType) {
4504
+ if (chainType?.toLowerCase?.() === "solana") {
4505
+ const trimmed = address.trim();
4506
+ if (isSolanaNativeTokenAlias2(trimmed)) {
4507
+ return NATIVE_SOLANA2;
4508
+ }
4509
+ return trimmed;
4510
+ }
4511
+ return address.toLowerCase();
4512
+ }
4513
+ function isNativeTokenAddress(address, chainType) {
4514
+ if (!address) return false;
4515
+ if (!chainType) return false;
4516
+ return normalizeAddress2(address, chainType) === normalizeAddress2(getNativeTokenAddress2(chainType), chainType);
4517
+ }
4518
+ function isEvmAddress2(value) {
4519
+ return !!value && EVM_ADDRESS_RE.test(value);
4520
+ }
4521
+ function needsErc20Approval(tokenAddress, chainType) {
4522
+ if (!isEvmAddress2(tokenAddress)) return false;
4523
+ const normalizedType = normalizeChainType2(chainType ?? void 0);
4524
+ if (normalizedType && NON_EVM_CHAIN_TYPES.has(normalizedType)) return false;
4525
+ return !isNativeTokenAddress(tokenAddress, chainType) && !isZeroAddrLike(tokenAddress, chainType);
4526
+ }
4527
+ function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
4528
+ const chainType = normalizeChainType2(chain);
4529
+ const rawAddress = (address ?? "").trim();
4530
+ if (chainType === "solana") return normalizeAddress2(rawAddress, "solana");
4531
+ if (chainType === "cosmos") {
4532
+ const chainIdKey = normalizeChainKey2(chain.chainId ?? chain.id ?? "");
4533
+ const nativeSymbol = chain.nativeCurrency?.symbol?.toUpperCase?.();
4534
+ const nativeFromRegistry = chainTokens.find(
4535
+ (token) => normalizeChainKey2(token.chainId) === chainIdKey && token.symbol?.toUpperCase?.() === nativeSymbol
4536
+ );
4537
+ const nativeDenom = (nativeFromRegistry?.address ?? "usei").toLowerCase();
4538
+ if (rawAddress.toLowerCase() === NATIVE_EVM2) {
4539
+ return nativeDenom;
4540
+ }
4541
+ return rawAddress.toLowerCase();
4542
+ }
4543
+ const lowerAddress = rawAddress.toLowerCase();
4544
+ if (lowerAddress === "0x0000000000000000000000000000000000000000") {
4545
+ return NATIVE_EVM2;
4546
+ }
4547
+ return lowerAddress;
4548
+ }
4549
+ var NATIVE_EVM2, NATIVE_SOLANA2, SOLANA_CHAIN_ID2, CHAIN_TYPE_ALIASES2, SEI_EVM_CHAIN_ID, SEI_COSMOS_CHAIN_ID, EVM_ADDRESS_RE, NON_EVM_CHAIN_TYPES;
4550
+ var init_chainHelpers = __esm({
4551
+ "src/widget/helpers/chainHelpers.ts"() {
4552
+ "use strict";
4553
+ NATIVE_EVM2 = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
4554
+ NATIVE_SOLANA2 = "So11111111111111111111111111111111111111111";
4555
+ SOLANA_CHAIN_ID2 = "1151111081099710";
4556
+ CHAIN_TYPE_ALIASES2 = {
4557
+ btc: "bitcoin",
4558
+ bitcoin: "bitcoin",
4559
+ sei: "cosmos",
4560
+ "pacific-1": "cosmos",
4561
+ nibiru: "cosmos",
4562
+ "cataclysm-1": "cosmos"
4563
+ };
4564
+ SEI_EVM_CHAIN_ID = "1329";
4565
+ SEI_COSMOS_CHAIN_ID = "pacific-1";
4566
+ EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
4567
+ NON_EVM_CHAIN_TYPES = /* @__PURE__ */ new Set(["solana", "bitcoin", "btc"]);
4568
+ }
4569
+ });
4570
+
4429
4571
  // src/core/routes.ts
4572
+ function canonicalRouteToken(address, chain) {
4573
+ const chainType = normalizeChainType2(
4574
+ chain === void 0 || chain === null ? void 0 : String(chain)
4575
+ );
4576
+ if (chainType !== "solana") return address ?? "";
4577
+ if (!address) return SOLANA_NATIVE_ROUTE_TOKEN;
4578
+ const trimmed = address.trim();
4579
+ if (isSolanaNativeTokenAlias2(trimmed) || trimmed === "0x0000000000000000000000000000000000000000") {
4580
+ return SOLANA_NATIVE_ROUTE_TOKEN;
4581
+ }
4582
+ return trimmed;
4583
+ }
4430
4584
  function assertValidPostHook(hooks) {
4431
4585
  const postHook = hooks?.postHook;
4432
4586
  if (!postHook) return;
@@ -4471,6 +4625,8 @@ async function buildRoute(body, signal) {
4471
4625
  const url = `${apiBase()}/v1/routes/route`;
4472
4626
  const payload = {
4473
4627
  ...body,
4628
+ fromToken: canonicalRouteToken(body.fromToken, body.fromChain),
4629
+ toToken: canonicalRouteToken(body.toToken, body.toChain),
4474
4630
  slippageBps: body.slippageBps ?? (body.slippage === void 0 ? void 0 : Math.round(body.slippage * 100)),
4475
4631
  fromAmountUSD: body.fromAmountUSD ?? body.fromAmountUsd
4476
4632
  };
@@ -4510,6 +4666,8 @@ async function buildDepositAddress(body, signal) {
4510
4666
  const url = `${apiBase()}/v1/routes/deposit-address`;
4511
4667
  const payload = {
4512
4668
  ...body,
4669
+ fromToken: canonicalRouteToken(body.fromToken, body.fromChain),
4670
+ toToken: canonicalRouteToken(body.toToken, body.toChain),
4513
4671
  slippageBps: body.slippageBps ?? (body.slippage === void 0 ? void 0 : Math.round(body.slippage * 100)),
4514
4672
  fromAmountUSD: body.fromAmountUSD ?? body.fromAmountUsd
4515
4673
  };
@@ -4608,13 +4766,15 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
4608
4766
  await new Promise((r) => setTimeout(r, intervalMs));
4609
4767
  }
4610
4768
  }
4611
- var STATUS_WIRE_TO_CAMEL;
4769
+ var SOLANA_NATIVE_ROUTE_TOKEN, STATUS_WIRE_TO_CAMEL;
4612
4770
  var init_routes = __esm({
4613
4771
  "src/core/routes.ts"() {
4614
4772
  "use strict";
4615
4773
  init_http();
4616
4774
  init_store();
4617
4775
  init_address();
4776
+ init_chainHelpers();
4777
+ SOLANA_NATIVE_ROUTE_TOKEN = "So11111111111111111111111111111111111111112";
4618
4778
  STATUS_WIRE_TO_CAMEL = {
4619
4779
  intent_id: "intentId",
4620
4780
  from_address: "fromAddress",
@@ -5593,133 +5753,6 @@ var init_tx = __esm({
5593
5753
  }
5594
5754
  });
5595
5755
 
5596
- // src/widget/helpers/chainHelpers.ts
5597
- function normalizeChainKey2(id) {
5598
- if (id === void 0 || id === null) return "";
5599
- return String(id).trim().toLowerCase();
5600
- }
5601
- function getNativeTokenAddress2(chainType) {
5602
- const normalized = chainType?.toLowerCase?.();
5603
- return normalized === "solana" ? NATIVE_SOLANA2 : NATIVE_EVM2;
5604
- }
5605
- function isSolanaNativeTokenAlias2(address) {
5606
- if (!address) return false;
5607
- const trimmed = address.trim();
5608
- if (!trimmed) return false;
5609
- return trimmed === NATIVE_SOLANA2 || trimmed.toLowerCase() === NATIVE_EVM2;
5610
- }
5611
- function parseDecimalToWei(input, decimals) {
5612
- if (!input?.trim()) return null;
5613
- const s = input.trim();
5614
- if (!/^\d*\.?\d*$/.test(s)) return null;
5615
- const [intPartRaw, fracRaw = ""] = s.split(".");
5616
- const intPart = intPartRaw.length ? BigInt(intPartRaw) : 0n;
5617
- const frac = (fracRaw + "0".repeat(decimals)).slice(0, decimals);
5618
- const fracPart = frac ? BigInt(frac) : 0n;
5619
- const base2 = 10n ** BigInt(decimals);
5620
- return intPart * base2 + fracPart;
5621
- }
5622
- function inferChainTypeFromValue2(normalized) {
5623
- if (!normalized) return void 0;
5624
- const aliased = CHAIN_TYPE_ALIASES2[normalized];
5625
- if (aliased) return aliased;
5626
- if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
5627
- return normalized;
5628
- }
5629
- if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
5630
- return "evm";
5631
- }
5632
- if (normalized.startsWith("solana:") || normalized.includes("solana")) {
5633
- return "solana";
5634
- }
5635
- if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
5636
- return "cosmos";
5637
- }
5638
- return void 0;
5639
- }
5640
- function normalizeChainType2(chain) {
5641
- if (!chain) return void 0;
5642
- const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
5643
- if (!raw) return void 0;
5644
- const normalized = String(raw).trim().toLowerCase();
5645
- return inferChainTypeFromValue2(normalized) ?? normalized;
5646
- }
5647
- function canonicalChainKeyForLink(chain) {
5648
- const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
5649
- if (seiKey) return seiKey;
5650
- return normalizeChainKey2(
5651
- chain.networkIdentifier ?? chain.axelarChainName ?? chain.id ?? chain.chainId ?? chain.networkName
5652
- );
5653
- }
5654
- function canonicalSeiChainKey(chainId) {
5655
- const normalized = normalizeChainKey2(chainId);
5656
- if (!normalized) return null;
5657
- if (normalized === SEI_EVM_CHAIN_ID) return "sei-evm";
5658
- if (normalized === SEI_COSMOS_CHAIN_ID) return "sei";
5659
- return null;
5660
- }
5661
- function isZeroAddrLike(a, chainType) {
5662
- if (!a) return true;
5663
- if (!chainType) return false;
5664
- const s = normalizeAddress2(a, chainType);
5665
- return s === normalizeAddress2(getNativeTokenAddress2(chainType), chainType) || s === "0x0000000000000000000000000000000000000000";
5666
- }
5667
- function normalizeAddress2(address, chainType) {
5668
- if (chainType?.toLowerCase?.() === "solana") {
5669
- const trimmed = address.trim();
5670
- if (isSolanaNativeTokenAlias2(trimmed)) {
5671
- return NATIVE_SOLANA2;
5672
- }
5673
- return trimmed;
5674
- }
5675
- return address.toLowerCase();
5676
- }
5677
- function isNativeTokenAddress(address, chainType) {
5678
- if (!address) return false;
5679
- if (!chainType) return false;
5680
- return normalizeAddress2(address, chainType) === normalizeAddress2(getNativeTokenAddress2(chainType), chainType);
5681
- }
5682
- function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
5683
- const chainType = normalizeChainType2(chain);
5684
- const rawAddress = (address ?? "").trim();
5685
- if (chainType === "solana") return normalizeAddress2(rawAddress, "solana");
5686
- if (chainType === "cosmos") {
5687
- const chainIdKey = normalizeChainKey2(chain.chainId ?? chain.id ?? "");
5688
- const nativeSymbol = chain.nativeCurrency?.symbol?.toUpperCase?.();
5689
- const nativeFromRegistry = chainTokens.find(
5690
- (token) => normalizeChainKey2(token.chainId) === chainIdKey && token.symbol?.toUpperCase?.() === nativeSymbol
5691
- );
5692
- const nativeDenom = (nativeFromRegistry?.address ?? "usei").toLowerCase();
5693
- if (rawAddress.toLowerCase() === NATIVE_EVM2) {
5694
- return nativeDenom;
5695
- }
5696
- return rawAddress.toLowerCase();
5697
- }
5698
- const lowerAddress = rawAddress.toLowerCase();
5699
- if (lowerAddress === "0x0000000000000000000000000000000000000000") {
5700
- return NATIVE_EVM2;
5701
- }
5702
- return lowerAddress;
5703
- }
5704
- var NATIVE_EVM2, NATIVE_SOLANA2, CHAIN_TYPE_ALIASES2, SEI_EVM_CHAIN_ID, SEI_COSMOS_CHAIN_ID;
5705
- var init_chainHelpers = __esm({
5706
- "src/widget/helpers/chainHelpers.ts"() {
5707
- "use strict";
5708
- NATIVE_EVM2 = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
5709
- NATIVE_SOLANA2 = "So11111111111111111111111111111111111111111";
5710
- CHAIN_TYPE_ALIASES2 = {
5711
- btc: "bitcoin",
5712
- bitcoin: "bitcoin",
5713
- sei: "cosmos",
5714
- "pacific-1": "cosmos",
5715
- nibiru: "cosmos",
5716
- "cataclysm-1": "cosmos"
5717
- };
5718
- SEI_EVM_CHAIN_ID = "1329";
5719
- SEI_COSMOS_CHAIN_ID = "pacific-1";
5720
- }
5721
- });
5722
-
5723
5756
  // src/widget/helpers/tokenAmount.ts
5724
5757
  function rawToDecimal(rawAmount, decimals) {
5725
5758
  if (!rawAmount) return "0";
@@ -8873,9 +8906,9 @@ var init_useRouteBuilder = __esm({
8873
8906
  // src/widget/hooks/useAmountConstraints.ts
8874
8907
  function parsePositiveNumber(value) {
8875
8908
  if (value === null || value === void 0) return void 0;
8876
- const str = String(value).trim();
8877
- if (!str) return void 0;
8878
- const n = Number(str);
8909
+ const str2 = String(value).trim();
8910
+ if (!str2) return void 0;
8911
+ const n = Number(str2);
8879
8912
  return Number.isFinite(n) && n >= 0 ? n : void 0;
8880
8913
  }
8881
8914
  function useAmountConstraints() {
@@ -8884,10 +8917,10 @@ function useAmountConstraints() {
8884
8917
  const fixedFromAmountString = (0, import_react13.useMemo)(() => {
8885
8918
  const raw = routeOptions.fixedFromAmount;
8886
8919
  if (raw === null || raw === void 0) return void 0;
8887
- const str = String(raw).trim();
8888
- if (!str) return void 0;
8889
- const n = Number(str);
8890
- return Number.isFinite(n) && n > 0 ? str : void 0;
8920
+ const str2 = String(raw).trim();
8921
+ if (!str2) return void 0;
8922
+ const n = Number(str2);
8923
+ return Number.isFinite(n) && n > 0 ? str2 : void 0;
8891
8924
  }, [routeOptions.fixedFromAmount]);
8892
8925
  const fixedFromAmountValue = (0, import_react13.useMemo)(() => {
8893
8926
  if (!fixedFromAmountString) return void 0;
@@ -9082,6 +9115,52 @@ var init_useTransactionSubmit = __esm({
9082
9115
  }
9083
9116
  });
9084
9117
 
9118
+ // src/core/failure.ts
9119
+ function asRecord(value) {
9120
+ return typeof value === "object" && value !== null ? value : null;
9121
+ }
9122
+ function str(value) {
9123
+ return typeof value === "string" ? value.trim() : "";
9124
+ }
9125
+ function tidy(detail) {
9126
+ const collapsed = detail.replace(/\s+/g, " ").trim();
9127
+ return collapsed.length > MAX_DETAIL ? `${collapsed.slice(0, MAX_DETAIL - 1).trimEnd()}\u2026` : collapsed;
9128
+ }
9129
+ function describeTransactionFailure(tx) {
9130
+ const raw = asRecord(tx?.statusRaw);
9131
+ const substatus = str(raw?.substatus);
9132
+ const detail = str(raw?.substatusMessage) || str(raw?.reason) || str(raw?.error) || str(raw?.message);
9133
+ const haystack = `${substatus} ${detail}`.toLowerCase();
9134
+ if (/slippage|price impact|price movement/.test(haystack)) {
9135
+ return "Transaction failed due to price movement. Please try again with a higher slippage.";
9136
+ }
9137
+ if (/liquidity/.test(haystack)) {
9138
+ return "Transaction failed due to insufficient liquidity. Try a smaller amount.";
9139
+ }
9140
+ if (/timeout|timed out|expired/.test(haystack)) {
9141
+ return "Transaction expired. Please start a new transaction.";
9142
+ }
9143
+ if (/out.?of.?gas|insufficient (gas|fee)/.test(haystack)) {
9144
+ return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9145
+ }
9146
+ if (/insufficient (balance|funds)/.test(haystack)) {
9147
+ return "Transaction failed due to insufficient balance.";
9148
+ }
9149
+ if (tx?.gasStatus === "insufficient") {
9150
+ return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9151
+ }
9152
+ if (detail) return `Transaction failed on-chain: ${tidy(detail)}`;
9153
+ return GENERIC;
9154
+ }
9155
+ var MAX_DETAIL, GENERIC;
9156
+ var init_failure = __esm({
9157
+ "src/core/failure.ts"() {
9158
+ "use strict";
9159
+ MAX_DETAIL = 160;
9160
+ GENERIC = "Transaction failed on-chain. Please try again.";
9161
+ }
9162
+ });
9163
+
9085
9164
  // src/hooks/useGTM.ts
9086
9165
  function isGA4Allowed() {
9087
9166
  try {
@@ -9325,7 +9404,7 @@ function useTransactionPolling() {
9325
9404
  return;
9326
9405
  }
9327
9406
  if (tx.status === "failed") {
9328
- const failError = mapFailedTransactionError(tx);
9407
+ const failError = describeTransactionFailure(tx);
9329
9408
  clearPolling();
9330
9409
  setState((prev) => ({
9331
9410
  ...prev,
@@ -9464,29 +9543,6 @@ function mapReceiptError(err) {
9464
9543
  }
9465
9544
  return cleanedMsg || "Failed to submit transaction. Please try again.";
9466
9545
  }
9467
- function mapFailedTransactionError(tx) {
9468
- const statusRaw = tx.statusRaw;
9469
- if (typeof statusRaw === "object" && statusRaw !== null) {
9470
- const statusObj = statusRaw;
9471
- const reason = statusObj.reason || statusObj.error || statusObj.message;
9472
- if (reason) {
9473
- const reasonLower = String(reason).toLowerCase();
9474
- if (reasonLower.includes("slippage") || reasonLower.includes("price")) {
9475
- return "Transaction failed due to price movement. Please try again with a higher slippage.";
9476
- }
9477
- if (reasonLower.includes("liquidity")) {
9478
- return "Transaction failed due to insufficient liquidity. Try a smaller amount.";
9479
- }
9480
- if (reasonLower.includes("timeout") || reasonLower.includes("expired")) {
9481
- return "Transaction expired. Please start a new deposit.";
9482
- }
9483
- }
9484
- }
9485
- if (tx.gasStatus === "insufficient") {
9486
- return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9487
- }
9488
- return "Transaction failed. Please try again or contact support if the issue persists.";
9489
- }
9490
9546
  var import_react16, FAST_POLL_INTERVAL_MS, NORMAL_POLL_INTERVAL_MS, POLL_TIMEOUT_MS;
9491
9547
  var init_useTransactionPolling = __esm({
9492
9548
  "src/widget/hooks/useTransactionPolling.ts"() {
@@ -9495,6 +9551,7 @@ var init_useTransactionPolling = __esm({
9495
9551
  import_react16 = require("react");
9496
9552
  init_routes();
9497
9553
  init_http();
9554
+ init_failure();
9498
9555
  init_DepositContext();
9499
9556
  init_provider();
9500
9557
  init_core2();
@@ -33511,10 +33568,12 @@ function mapError(raw) {
33511
33568
  };
33512
33569
  }
33513
33570
  if (lower.includes("transaction failed") || lower.includes("reverted")) {
33571
+ const specific = msg.trim();
33572
+ const isBare = /^transaction (failed|reverted)[.!]?$/i.test(specific) || specific.length > 200 || specific.includes("\n");
33514
33573
  return {
33515
33574
  category: "transaction_failed",
33516
33575
  title: "Transaction Failed",
33517
- message: "The transaction could not be completed. Please try again."
33576
+ message: isBare ? "The transaction could not be completed. Please try again." : specific
33518
33577
  };
33519
33578
  }
33520
33579
  if (lower.includes("wrong network") || lower.includes("wrong chain") || lower.includes("chain mismatch")) {
@@ -33806,7 +33865,7 @@ function useSwapExecution(fromChain) {
33806
33865
  }
33807
33866
  if (tx.status === "failed") {
33808
33867
  clearPolling();
33809
- const msg = "Transaction failed on-chain. Please try again.";
33868
+ const msg = describeTransactionFailure(tx);
33810
33869
  setState((p) => ({ ...p, txStatus: "error", errorMessage: msg }));
33811
33870
  onError(msg);
33812
33871
  return;
@@ -33841,8 +33900,7 @@ function useSwapExecution(fromChain) {
33841
33900
  return;
33842
33901
  }
33843
33902
  const chainType = normalizeChainType2(fromChain);
33844
- const isNative = !fromTokenAddress || isNativeTokenAddress(fromTokenAddress, chainType) || isZeroAddrLike(fromTokenAddress, chainType);
33845
- if (isNative) {
33903
+ if (!needsErc20Approval(fromTokenAddress, chainType)) {
33846
33904
  setState((p) => ({ ...p, allowanceStatus: "sufficient" }));
33847
33905
  return;
33848
33906
  }
@@ -33856,7 +33914,7 @@ function useSwapExecution(fromChain) {
33856
33914
  BigInt(a.amount || "0"),
33857
33915
  amountWei
33858
33916
  );
33859
- if (!token || !a.spender) return [];
33917
+ if (!isEvmAddress2(token) || !isEvmAddress2(a.spender)) return [];
33860
33918
  return [
33861
33919
  {
33862
33920
  chainId: a.chainId || chainIdStr,
@@ -34004,7 +34062,8 @@ function useSwapExecution(fromChain) {
34004
34062
  const requiredApprovals = plannedApprovals.length ? plannedApprovals.flatMap((a, index) => {
34005
34063
  const token = a.tokenAddress ?? fromTokenAddress;
34006
34064
  const approvalSpender = a.spender;
34007
- if (!token || !approvalSpender) return [];
34065
+ if (!isEvmAddress2(token) || !isEvmAddress2(approvalSpender))
34066
+ return [];
34008
34067
  const amountWei = requiredApprovalAmount(
34009
34068
  BigInt(a.amount || "0"),
34010
34069
  fromAmountWei
@@ -34027,7 +34086,8 @@ function useSwapExecution(fromChain) {
34027
34086
  chainId: chainIdStr
34028
34087
  }
34029
34088
  ] : [];
34030
- const ownsApprovals = !isNative && !!walletAddress && !!chainIdStr;
34089
+ const coversEveryPlannedApproval = plannedApprovals.length === 0 || requiredApprovals.length === plannedApprovals.length;
34090
+ const ownsApprovals = coversEveryPlannedApproval && needsErc20Approval(fromTokenAddress, chainType) && !!walletAddress && !!chainIdStr;
34031
34091
  const activeAddress = ownsApprovals ? await requireActiveAddress(wallet, walletAddress) : void 0;
34032
34092
  for (const required of requiredApprovals) {
34033
34093
  if (!ownsApprovals) break;
@@ -34184,6 +34244,7 @@ var init_useSwapExecution = __esm({
34184
34244
  init_core2();
34185
34245
  init_routes();
34186
34246
  init_http();
34247
+ init_failure();
34187
34248
  init_tx();
34188
34249
  init_sdkRpc();
34189
34250
  init_chainHelpers();
@@ -35908,8 +35969,8 @@ function truncateDecimal(n, dp) {
35908
35969
  const s = truncated.toFixed(dp);
35909
35970
  return s.includes(".") ? s.replace(/\.?0+$/, "") || "0" : s;
35910
35971
  }
35911
- function scaleFontSize(str) {
35912
- const len = str.replace(/[^0-9.]/g, "").length;
35972
+ function scaleFontSize(str2) {
35973
+ const len = str2.replace(/[^0-9.]/g, "").length;
35913
35974
  if (len <= 6) return "2.5rem";
35914
35975
  if (len <= 9) return "2rem";
35915
35976
  if (len <= 12) return "1.5rem";
@@ -36208,6 +36269,10 @@ function SwapMode({
36208
36269
  }, [lockDestToken, fromToken, fromChain, toToken, toChain, route, emitEvent]);
36209
36270
  const fromChainType = normalizeChainType2(fromChain);
36210
36271
  const toChainType = normalizeChainType2(toChain);
36272
+ const canSetMaxApproval = needsErc20Approval(
36273
+ fromToken?.address,
36274
+ fromChainType
36275
+ );
36211
36276
  const needsDestAddress = !!fromChainType && !!toChainType && fromChainType !== toChainType;
36212
36277
  const isValidDestAddress = !needsDestAddress || validateDestAddress(destAddress, toChainType ?? "");
36213
36278
  const handleReview = (0, import_react50.useCallback)(async () => {
@@ -38428,7 +38493,7 @@ function SwapMode({
38428
38493
  }
38429
38494
  )
38430
38495
  ] }),
38431
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { style: { marginBottom: spacing[4] }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
38496
+ canSetMaxApproval && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { style: { marginBottom: spacing[4] }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
38432
38497
  "div",
38433
38498
  {
38434
38499
  style: {