@trustware/sdk-staging 1.1.12-staging.3 → 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.mjs CHANGED
@@ -492,7 +492,7 @@ var init_constants = __esm({
492
492
  "src/constants.ts"() {
493
493
  "use strict";
494
494
  SDK_NAME = "@trustware/sdk";
495
- SDK_VERSION = "1.1.12-staging.3";
495
+ SDK_VERSION = "1.1.12-staging.4";
496
496
  API_ROOT = "https://bv-staging-api.trustware.io";
497
497
  GTM_ID = "GTM-TZDGNCXB";
498
498
  API_PREFIX = "/api";
@@ -2450,6 +2450,7 @@ function inferChainTypeFromValue(normalized) {
2450
2450
  if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
2451
2451
  return normalized;
2452
2452
  }
2453
+ if (normalized === SOLANA_CHAIN_ID) return "solana";
2453
2454
  if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
2454
2455
  return "evm";
2455
2456
  }
@@ -2496,12 +2497,13 @@ function isZeroAddressLike(address, chainType) {
2496
2497
  const normalized = normalizeAddress(address, chainType);
2497
2498
  return normalized === normalizeAddress(getNativeTokenAddress(chainType), chainType) || normalized === "0x0000000000000000000000000000000000000000";
2498
2499
  }
2499
- var NATIVE_EVM, NATIVE_SOLANA, CHAIN_TYPE_ALIASES;
2500
+ var NATIVE_EVM, NATIVE_SOLANA, SOLANA_CHAIN_ID, CHAIN_TYPE_ALIASES;
2500
2501
  var init_chains = __esm({
2501
2502
  "src/utils/chains.ts"() {
2502
2503
  "use strict";
2503
2504
  NATIVE_EVM = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
2504
2505
  NATIVE_SOLANA = "So11111111111111111111111111111111111111111";
2506
+ SOLANA_CHAIN_ID = "1151111081099710";
2505
2507
  CHAIN_TYPE_ALIASES = {
2506
2508
  btc: "bitcoin",
2507
2509
  bitcoin: "bitcoin",
@@ -4404,7 +4406,159 @@ var init_wallets = __esm({
4404
4406
  }
4405
4407
  });
4406
4408
 
4409
+ // src/widget/helpers/chainHelpers.ts
4410
+ function normalizeChainKey2(id) {
4411
+ if (id === void 0 || id === null) return "";
4412
+ return String(id).trim().toLowerCase();
4413
+ }
4414
+ function getNativeTokenAddress2(chainType) {
4415
+ const normalized = chainType?.toLowerCase?.();
4416
+ return normalized === "solana" ? NATIVE_SOLANA2 : NATIVE_EVM2;
4417
+ }
4418
+ function isSolanaNativeTokenAlias2(address) {
4419
+ if (!address) return false;
4420
+ const trimmed = address.trim();
4421
+ if (!trimmed) return false;
4422
+ return trimmed === NATIVE_SOLANA2 || trimmed.toLowerCase() === NATIVE_EVM2;
4423
+ }
4424
+ function parseDecimalToWei(input, decimals) {
4425
+ if (!input?.trim()) return null;
4426
+ const s = input.trim();
4427
+ if (!/^\d*\.?\d*$/.test(s)) return null;
4428
+ const [intPartRaw, fracRaw = ""] = s.split(".");
4429
+ const intPart = intPartRaw.length ? BigInt(intPartRaw) : 0n;
4430
+ const frac = (fracRaw + "0".repeat(decimals)).slice(0, decimals);
4431
+ const fracPart = frac ? BigInt(frac) : 0n;
4432
+ const base2 = 10n ** BigInt(decimals);
4433
+ return intPart * base2 + fracPart;
4434
+ }
4435
+ function inferChainTypeFromValue2(normalized) {
4436
+ if (!normalized) return void 0;
4437
+ const aliased = CHAIN_TYPE_ALIASES2[normalized];
4438
+ if (aliased) return aliased;
4439
+ if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
4440
+ return normalized;
4441
+ }
4442
+ if (normalized === SOLANA_CHAIN_ID2) return "solana";
4443
+ if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
4444
+ return "evm";
4445
+ }
4446
+ if (normalized.startsWith("solana:") || normalized.includes("solana")) {
4447
+ return "solana";
4448
+ }
4449
+ if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
4450
+ return "cosmos";
4451
+ }
4452
+ return void 0;
4453
+ }
4454
+ function normalizeChainType2(chain) {
4455
+ if (!chain) return void 0;
4456
+ const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
4457
+ if (!raw) return void 0;
4458
+ const normalized = String(raw).trim().toLowerCase();
4459
+ return inferChainTypeFromValue2(normalized) ?? normalized;
4460
+ }
4461
+ function canonicalChainKeyForLink(chain) {
4462
+ const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
4463
+ if (seiKey) return seiKey;
4464
+ return normalizeChainKey2(
4465
+ chain.networkIdentifier ?? chain.axelarChainName ?? chain.id ?? chain.chainId ?? chain.networkName
4466
+ );
4467
+ }
4468
+ function canonicalSeiChainKey(chainId) {
4469
+ const normalized = normalizeChainKey2(chainId);
4470
+ if (!normalized) return null;
4471
+ if (normalized === SEI_EVM_CHAIN_ID) return "sei-evm";
4472
+ if (normalized === SEI_COSMOS_CHAIN_ID) return "sei";
4473
+ return null;
4474
+ }
4475
+ function isZeroAddrLike(a, chainType) {
4476
+ if (!a) return true;
4477
+ if (!chainType) return false;
4478
+ const s = normalizeAddress2(a, chainType);
4479
+ return s === normalizeAddress2(getNativeTokenAddress2(chainType), chainType) || s === "0x0000000000000000000000000000000000000000";
4480
+ }
4481
+ function normalizeAddress2(address, chainType) {
4482
+ if (chainType?.toLowerCase?.() === "solana") {
4483
+ const trimmed = address.trim();
4484
+ if (isSolanaNativeTokenAlias2(trimmed)) {
4485
+ return NATIVE_SOLANA2;
4486
+ }
4487
+ return trimmed;
4488
+ }
4489
+ return address.toLowerCase();
4490
+ }
4491
+ function isNativeTokenAddress(address, chainType) {
4492
+ if (!address) return false;
4493
+ if (!chainType) return false;
4494
+ return normalizeAddress2(address, chainType) === normalizeAddress2(getNativeTokenAddress2(chainType), chainType);
4495
+ }
4496
+ function isEvmAddress2(value) {
4497
+ return !!value && EVM_ADDRESS_RE.test(value);
4498
+ }
4499
+ function needsErc20Approval(tokenAddress, chainType) {
4500
+ if (!isEvmAddress2(tokenAddress)) return false;
4501
+ const normalizedType = normalizeChainType2(chainType ?? void 0);
4502
+ if (normalizedType && NON_EVM_CHAIN_TYPES.has(normalizedType)) return false;
4503
+ return !isNativeTokenAddress(tokenAddress, chainType) && !isZeroAddrLike(tokenAddress, chainType);
4504
+ }
4505
+ function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
4506
+ const chainType = normalizeChainType2(chain);
4507
+ const rawAddress = (address ?? "").trim();
4508
+ if (chainType === "solana") return normalizeAddress2(rawAddress, "solana");
4509
+ if (chainType === "cosmos") {
4510
+ const chainIdKey = normalizeChainKey2(chain.chainId ?? chain.id ?? "");
4511
+ const nativeSymbol = chain.nativeCurrency?.symbol?.toUpperCase?.();
4512
+ const nativeFromRegistry = chainTokens.find(
4513
+ (token) => normalizeChainKey2(token.chainId) === chainIdKey && token.symbol?.toUpperCase?.() === nativeSymbol
4514
+ );
4515
+ const nativeDenom = (nativeFromRegistry?.address ?? "usei").toLowerCase();
4516
+ if (rawAddress.toLowerCase() === NATIVE_EVM2) {
4517
+ return nativeDenom;
4518
+ }
4519
+ return rawAddress.toLowerCase();
4520
+ }
4521
+ const lowerAddress = rawAddress.toLowerCase();
4522
+ if (lowerAddress === "0x0000000000000000000000000000000000000000") {
4523
+ return NATIVE_EVM2;
4524
+ }
4525
+ return lowerAddress;
4526
+ }
4527
+ 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;
4528
+ var init_chainHelpers = __esm({
4529
+ "src/widget/helpers/chainHelpers.ts"() {
4530
+ "use strict";
4531
+ NATIVE_EVM2 = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
4532
+ NATIVE_SOLANA2 = "So11111111111111111111111111111111111111111";
4533
+ SOLANA_CHAIN_ID2 = "1151111081099710";
4534
+ CHAIN_TYPE_ALIASES2 = {
4535
+ btc: "bitcoin",
4536
+ bitcoin: "bitcoin",
4537
+ sei: "cosmos",
4538
+ "pacific-1": "cosmos",
4539
+ nibiru: "cosmos",
4540
+ "cataclysm-1": "cosmos"
4541
+ };
4542
+ SEI_EVM_CHAIN_ID = "1329";
4543
+ SEI_COSMOS_CHAIN_ID = "pacific-1";
4544
+ EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
4545
+ NON_EVM_CHAIN_TYPES = /* @__PURE__ */ new Set(["solana", "bitcoin", "btc"]);
4546
+ }
4547
+ });
4548
+
4407
4549
  // src/core/routes.ts
4550
+ function canonicalRouteToken(address, chain) {
4551
+ const chainType = normalizeChainType2(
4552
+ chain === void 0 || chain === null ? void 0 : String(chain)
4553
+ );
4554
+ if (chainType !== "solana") return address ?? "";
4555
+ if (!address) return SOLANA_NATIVE_ROUTE_TOKEN;
4556
+ const trimmed = address.trim();
4557
+ if (isSolanaNativeTokenAlias2(trimmed) || trimmed === "0x0000000000000000000000000000000000000000") {
4558
+ return SOLANA_NATIVE_ROUTE_TOKEN;
4559
+ }
4560
+ return trimmed;
4561
+ }
4408
4562
  function assertValidPostHook(hooks) {
4409
4563
  const postHook = hooks?.postHook;
4410
4564
  if (!postHook) return;
@@ -4449,6 +4603,8 @@ async function buildRoute(body, signal) {
4449
4603
  const url = `${apiBase()}/v1/routes/route`;
4450
4604
  const payload = {
4451
4605
  ...body,
4606
+ fromToken: canonicalRouteToken(body.fromToken, body.fromChain),
4607
+ toToken: canonicalRouteToken(body.toToken, body.toChain),
4452
4608
  slippageBps: body.slippageBps ?? (body.slippage === void 0 ? void 0 : Math.round(body.slippage * 100)),
4453
4609
  fromAmountUSD: body.fromAmountUSD ?? body.fromAmountUsd
4454
4610
  };
@@ -4488,6 +4644,8 @@ async function buildDepositAddress(body, signal) {
4488
4644
  const url = `${apiBase()}/v1/routes/deposit-address`;
4489
4645
  const payload = {
4490
4646
  ...body,
4647
+ fromToken: canonicalRouteToken(body.fromToken, body.fromChain),
4648
+ toToken: canonicalRouteToken(body.toToken, body.toChain),
4491
4649
  slippageBps: body.slippageBps ?? (body.slippage === void 0 ? void 0 : Math.round(body.slippage * 100)),
4492
4650
  fromAmountUSD: body.fromAmountUSD ?? body.fromAmountUsd
4493
4651
  };
@@ -4586,13 +4744,15 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
4586
4744
  await new Promise((r) => setTimeout(r, intervalMs));
4587
4745
  }
4588
4746
  }
4589
- var STATUS_WIRE_TO_CAMEL;
4747
+ var SOLANA_NATIVE_ROUTE_TOKEN, STATUS_WIRE_TO_CAMEL;
4590
4748
  var init_routes = __esm({
4591
4749
  "src/core/routes.ts"() {
4592
4750
  "use strict";
4593
4751
  init_http();
4594
4752
  init_store();
4595
4753
  init_address();
4754
+ init_chainHelpers();
4755
+ SOLANA_NATIVE_ROUTE_TOKEN = "So11111111111111111111111111111111111111112";
4596
4756
  STATUS_WIRE_TO_CAMEL = {
4597
4757
  intent_id: "intentId",
4598
4758
  from_address: "fromAddress",
@@ -5571,144 +5731,6 @@ var init_tx = __esm({
5571
5731
  }
5572
5732
  });
5573
5733
 
5574
- // src/widget/helpers/chainHelpers.ts
5575
- function normalizeChainKey2(id) {
5576
- if (id === void 0 || id === null) return "";
5577
- return String(id).trim().toLowerCase();
5578
- }
5579
- function getNativeTokenAddress2(chainType) {
5580
- const normalized = chainType?.toLowerCase?.();
5581
- return normalized === "solana" ? NATIVE_SOLANA2 : NATIVE_EVM2;
5582
- }
5583
- function isSolanaNativeTokenAlias2(address) {
5584
- if (!address) return false;
5585
- const trimmed = address.trim();
5586
- if (!trimmed) return false;
5587
- return trimmed === NATIVE_SOLANA2 || trimmed.toLowerCase() === NATIVE_EVM2;
5588
- }
5589
- function parseDecimalToWei(input, decimals) {
5590
- if (!input?.trim()) return null;
5591
- const s = input.trim();
5592
- if (!/^\d*\.?\d*$/.test(s)) return null;
5593
- const [intPartRaw, fracRaw = ""] = s.split(".");
5594
- const intPart = intPartRaw.length ? BigInt(intPartRaw) : 0n;
5595
- const frac = (fracRaw + "0".repeat(decimals)).slice(0, decimals);
5596
- const fracPart = frac ? BigInt(frac) : 0n;
5597
- const base2 = 10n ** BigInt(decimals);
5598
- return intPart * base2 + fracPart;
5599
- }
5600
- function inferChainTypeFromValue2(normalized) {
5601
- if (!normalized) return void 0;
5602
- const aliased = CHAIN_TYPE_ALIASES2[normalized];
5603
- if (aliased) return aliased;
5604
- if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
5605
- return normalized;
5606
- }
5607
- if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
5608
- return "evm";
5609
- }
5610
- if (normalized.startsWith("solana:") || normalized.includes("solana")) {
5611
- return "solana";
5612
- }
5613
- if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
5614
- return "cosmos";
5615
- }
5616
- return void 0;
5617
- }
5618
- function normalizeChainType2(chain) {
5619
- if (!chain) return void 0;
5620
- const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
5621
- if (!raw) return void 0;
5622
- const normalized = String(raw).trim().toLowerCase();
5623
- return inferChainTypeFromValue2(normalized) ?? normalized;
5624
- }
5625
- function canonicalChainKeyForLink(chain) {
5626
- const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
5627
- if (seiKey) return seiKey;
5628
- return normalizeChainKey2(
5629
- chain.networkIdentifier ?? chain.axelarChainName ?? chain.id ?? chain.chainId ?? chain.networkName
5630
- );
5631
- }
5632
- function canonicalSeiChainKey(chainId) {
5633
- const normalized = normalizeChainKey2(chainId);
5634
- if (!normalized) return null;
5635
- if (normalized === SEI_EVM_CHAIN_ID) return "sei-evm";
5636
- if (normalized === SEI_COSMOS_CHAIN_ID) return "sei";
5637
- return null;
5638
- }
5639
- function isZeroAddrLike(a, chainType) {
5640
- if (!a) return true;
5641
- if (!chainType) return false;
5642
- const s = normalizeAddress2(a, chainType);
5643
- return s === normalizeAddress2(getNativeTokenAddress2(chainType), chainType) || s === "0x0000000000000000000000000000000000000000";
5644
- }
5645
- function normalizeAddress2(address, chainType) {
5646
- if (chainType?.toLowerCase?.() === "solana") {
5647
- const trimmed = address.trim();
5648
- if (isSolanaNativeTokenAlias2(trimmed)) {
5649
- return NATIVE_SOLANA2;
5650
- }
5651
- return trimmed;
5652
- }
5653
- return address.toLowerCase();
5654
- }
5655
- function isNativeTokenAddress(address, chainType) {
5656
- if (!address) return false;
5657
- if (!chainType) return false;
5658
- return normalizeAddress2(address, chainType) === normalizeAddress2(getNativeTokenAddress2(chainType), chainType);
5659
- }
5660
- function isEvmAddress2(value) {
5661
- return !!value && EVM_ADDRESS_RE.test(value);
5662
- }
5663
- function needsErc20Approval(tokenAddress, chainType) {
5664
- if (!isEvmAddress2(tokenAddress)) return false;
5665
- const normalizedType = normalizeChainType2(chainType ?? void 0);
5666
- if (normalizedType && NON_EVM_CHAIN_TYPES.has(normalizedType)) return false;
5667
- return !isNativeTokenAddress(tokenAddress, chainType) && !isZeroAddrLike(tokenAddress, chainType);
5668
- }
5669
- function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
5670
- const chainType = normalizeChainType2(chain);
5671
- const rawAddress = (address ?? "").trim();
5672
- if (chainType === "solana") return normalizeAddress2(rawAddress, "solana");
5673
- if (chainType === "cosmos") {
5674
- const chainIdKey = normalizeChainKey2(chain.chainId ?? chain.id ?? "");
5675
- const nativeSymbol = chain.nativeCurrency?.symbol?.toUpperCase?.();
5676
- const nativeFromRegistry = chainTokens.find(
5677
- (token) => normalizeChainKey2(token.chainId) === chainIdKey && token.symbol?.toUpperCase?.() === nativeSymbol
5678
- );
5679
- const nativeDenom = (nativeFromRegistry?.address ?? "usei").toLowerCase();
5680
- if (rawAddress.toLowerCase() === NATIVE_EVM2) {
5681
- return nativeDenom;
5682
- }
5683
- return rawAddress.toLowerCase();
5684
- }
5685
- const lowerAddress = rawAddress.toLowerCase();
5686
- if (lowerAddress === "0x0000000000000000000000000000000000000000") {
5687
- return NATIVE_EVM2;
5688
- }
5689
- return lowerAddress;
5690
- }
5691
- var NATIVE_EVM2, NATIVE_SOLANA2, CHAIN_TYPE_ALIASES2, SEI_EVM_CHAIN_ID, SEI_COSMOS_CHAIN_ID, EVM_ADDRESS_RE, NON_EVM_CHAIN_TYPES;
5692
- var init_chainHelpers = __esm({
5693
- "src/widget/helpers/chainHelpers.ts"() {
5694
- "use strict";
5695
- NATIVE_EVM2 = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
5696
- NATIVE_SOLANA2 = "So11111111111111111111111111111111111111111";
5697
- CHAIN_TYPE_ALIASES2 = {
5698
- btc: "bitcoin",
5699
- bitcoin: "bitcoin",
5700
- sei: "cosmos",
5701
- "pacific-1": "cosmos",
5702
- nibiru: "cosmos",
5703
- "cataclysm-1": "cosmos"
5704
- };
5705
- SEI_EVM_CHAIN_ID = "1329";
5706
- SEI_COSMOS_CHAIN_ID = "pacific-1";
5707
- EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
5708
- NON_EVM_CHAIN_TYPES = /* @__PURE__ */ new Set(["solana", "bitcoin", "btc"]);
5709
- }
5710
- });
5711
-
5712
5734
  // src/widget/helpers/tokenAmount.ts
5713
5735
  function rawToDecimal(rawAmount, decimals) {
5714
5736
  if (!rawAmount) return "0";
@@ -8866,9 +8888,9 @@ var init_useRouteBuilder = __esm({
8866
8888
  import { useMemo as useMemo7 } from "react";
8867
8889
  function parsePositiveNumber(value) {
8868
8890
  if (value === null || value === void 0) return void 0;
8869
- const str = String(value).trim();
8870
- if (!str) return void 0;
8871
- const n = Number(str);
8891
+ const str2 = String(value).trim();
8892
+ if (!str2) return void 0;
8893
+ const n = Number(str2);
8872
8894
  return Number.isFinite(n) && n >= 0 ? n : void 0;
8873
8895
  }
8874
8896
  function useAmountConstraints() {
@@ -8877,10 +8899,10 @@ function useAmountConstraints() {
8877
8899
  const fixedFromAmountString = useMemo7(() => {
8878
8900
  const raw = routeOptions.fixedFromAmount;
8879
8901
  if (raw === null || raw === void 0) return void 0;
8880
- const str = String(raw).trim();
8881
- if (!str) return void 0;
8882
- const n = Number(str);
8883
- return Number.isFinite(n) && n > 0 ? str : void 0;
8902
+ const str2 = String(raw).trim();
8903
+ if (!str2) return void 0;
8904
+ const n = Number(str2);
8905
+ return Number.isFinite(n) && n > 0 ? str2 : void 0;
8884
8906
  }, [routeOptions.fixedFromAmount]);
8885
8907
  const fixedFromAmountValue = useMemo7(() => {
8886
8908
  if (!fixedFromAmountString) return void 0;
@@ -9072,6 +9094,52 @@ var init_useTransactionSubmit = __esm({
9072
9094
  }
9073
9095
  });
9074
9096
 
9097
+ // src/core/failure.ts
9098
+ function asRecord(value) {
9099
+ return typeof value === "object" && value !== null ? value : null;
9100
+ }
9101
+ function str(value) {
9102
+ return typeof value === "string" ? value.trim() : "";
9103
+ }
9104
+ function tidy(detail) {
9105
+ const collapsed = detail.replace(/\s+/g, " ").trim();
9106
+ return collapsed.length > MAX_DETAIL ? `${collapsed.slice(0, MAX_DETAIL - 1).trimEnd()}\u2026` : collapsed;
9107
+ }
9108
+ function describeTransactionFailure(tx) {
9109
+ const raw = asRecord(tx?.statusRaw);
9110
+ const substatus = str(raw?.substatus);
9111
+ const detail = str(raw?.substatusMessage) || str(raw?.reason) || str(raw?.error) || str(raw?.message);
9112
+ const haystack = `${substatus} ${detail}`.toLowerCase();
9113
+ if (/slippage|price impact|price movement/.test(haystack)) {
9114
+ return "Transaction failed due to price movement. Please try again with a higher slippage.";
9115
+ }
9116
+ if (/liquidity/.test(haystack)) {
9117
+ return "Transaction failed due to insufficient liquidity. Try a smaller amount.";
9118
+ }
9119
+ if (/timeout|timed out|expired/.test(haystack)) {
9120
+ return "Transaction expired. Please start a new transaction.";
9121
+ }
9122
+ if (/out.?of.?gas|insufficient (gas|fee)/.test(haystack)) {
9123
+ return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9124
+ }
9125
+ if (/insufficient (balance|funds)/.test(haystack)) {
9126
+ return "Transaction failed due to insufficient balance.";
9127
+ }
9128
+ if (tx?.gasStatus === "insufficient") {
9129
+ return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9130
+ }
9131
+ if (detail) return `Transaction failed on-chain: ${tidy(detail)}`;
9132
+ return GENERIC;
9133
+ }
9134
+ var MAX_DETAIL, GENERIC;
9135
+ var init_failure = __esm({
9136
+ "src/core/failure.ts"() {
9137
+ "use strict";
9138
+ MAX_DETAIL = 160;
9139
+ GENERIC = "Transaction failed on-chain. Please try again.";
9140
+ }
9141
+ });
9142
+
9075
9143
  // src/hooks/useGTM.ts
9076
9144
  import { useEffect as useEffect11, useRef as useRef3, useCallback as useCallback8 } from "react";
9077
9145
  function isGA4Allowed() {
@@ -9316,7 +9384,7 @@ function useTransactionPolling() {
9316
9384
  return;
9317
9385
  }
9318
9386
  if (tx.status === "failed") {
9319
- const failError = mapFailedTransactionError(tx);
9387
+ const failError = describeTransactionFailure(tx);
9320
9388
  clearPolling();
9321
9389
  setState((prev) => ({
9322
9390
  ...prev,
@@ -9455,29 +9523,6 @@ function mapReceiptError(err) {
9455
9523
  }
9456
9524
  return cleanedMsg || "Failed to submit transaction. Please try again.";
9457
9525
  }
9458
- function mapFailedTransactionError(tx) {
9459
- const statusRaw = tx.statusRaw;
9460
- if (typeof statusRaw === "object" && statusRaw !== null) {
9461
- const statusObj = statusRaw;
9462
- const reason = statusObj.reason || statusObj.error || statusObj.message;
9463
- if (reason) {
9464
- const reasonLower = String(reason).toLowerCase();
9465
- if (reasonLower.includes("slippage") || reasonLower.includes("price")) {
9466
- return "Transaction failed due to price movement. Please try again with a higher slippage.";
9467
- }
9468
- if (reasonLower.includes("liquidity")) {
9469
- return "Transaction failed due to insufficient liquidity. Try a smaller amount.";
9470
- }
9471
- if (reasonLower.includes("timeout") || reasonLower.includes("expired")) {
9472
- return "Transaction expired. Please start a new deposit.";
9473
- }
9474
- }
9475
- }
9476
- if (tx.gasStatus === "insufficient") {
9477
- return "Transaction failed due to insufficient gas. Please ensure you have enough native tokens for gas.";
9478
- }
9479
- return "Transaction failed. Please try again or contact support if the issue persists.";
9480
- }
9481
9526
  var FAST_POLL_INTERVAL_MS, NORMAL_POLL_INTERVAL_MS, POLL_TIMEOUT_MS;
9482
9527
  var init_useTransactionPolling = __esm({
9483
9528
  "src/widget/hooks/useTransactionPolling.ts"() {
@@ -9485,6 +9530,7 @@ var init_useTransactionPolling = __esm({
9485
9530
  "use client";
9486
9531
  init_routes();
9487
9532
  init_http();
9533
+ init_failure();
9488
9534
  init_DepositContext();
9489
9535
  init_provider();
9490
9536
  init_core2();
@@ -33465,10 +33511,12 @@ function mapError(raw) {
33465
33511
  };
33466
33512
  }
33467
33513
  if (lower.includes("transaction failed") || lower.includes("reverted")) {
33514
+ const specific = msg.trim();
33515
+ const isBare = /^transaction (failed|reverted)[.!]?$/i.test(specific) || specific.length > 200 || specific.includes("\n");
33468
33516
  return {
33469
33517
  category: "transaction_failed",
33470
33518
  title: "Transaction Failed",
33471
- message: "The transaction could not be completed. Please try again."
33519
+ message: isBare ? "The transaction could not be completed. Please try again." : specific
33472
33520
  };
33473
33521
  }
33474
33522
  if (lower.includes("wrong network") || lower.includes("wrong chain") || lower.includes("chain mismatch")) {
@@ -33760,7 +33808,7 @@ function useSwapExecution(fromChain) {
33760
33808
  }
33761
33809
  if (tx.status === "failed") {
33762
33810
  clearPolling();
33763
- const msg = "Transaction failed on-chain. Please try again.";
33811
+ const msg = describeTransactionFailure(tx);
33764
33812
  setState((p) => ({ ...p, txStatus: "error", errorMessage: msg }));
33765
33813
  onError(msg);
33766
33814
  return;
@@ -34137,6 +34185,7 @@ var init_useSwapExecution = __esm({
34137
34185
  init_core2();
34138
34186
  init_routes();
34139
34187
  init_http();
34188
+ init_failure();
34140
34189
  init_tx();
34141
34190
  init_sdkRpc();
34142
34191
  init_chainHelpers();
@@ -35870,8 +35919,8 @@ function truncateDecimal(n, dp) {
35870
35919
  const s = truncated.toFixed(dp);
35871
35920
  return s.includes(".") ? s.replace(/\.?0+$/, "") || "0" : s;
35872
35921
  }
35873
- function scaleFontSize(str) {
35874
- const len = str.replace(/[^0-9.]/g, "").length;
35922
+ function scaleFontSize(str2) {
35923
+ const len = str2.replace(/[^0-9.]/g, "").length;
35875
35924
  if (len <= 6) return "2.5rem";
35876
35925
  if (len <= 9) return "2rem";
35877
35926
  if (len <= 12) return "1.5rem";