@trustware/sdk-staging 1.1.12-staging.1 → 1.1.12-staging.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.1";
495
+ SDK_VERSION = "1.1.12-staging.3";
496
496
  API_ROOT = "https://bv-staging-api.trustware.io";
497
497
  GTM_ID = "GTM-TZDGNCXB";
498
498
  API_PREFIX = "/api";
@@ -5657,6 +5657,15 @@ function isNativeTokenAddress(address, chainType) {
5657
5657
  if (!chainType) return false;
5658
5658
  return normalizeAddress2(address, chainType) === normalizeAddress2(getNativeTokenAddress2(chainType), chainType);
5659
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
+ }
5660
5669
  function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
5661
5670
  const chainType = normalizeChainType2(chain);
5662
5671
  const rawAddress = (address ?? "").trim();
@@ -5679,7 +5688,7 @@ function canonicalTokenAddressForChain(chain, address, chainTokens = []) {
5679
5688
  }
5680
5689
  return lowerAddress;
5681
5690
  }
5682
- var NATIVE_EVM2, NATIVE_SOLANA2, CHAIN_TYPE_ALIASES2, SEI_EVM_CHAIN_ID, SEI_COSMOS_CHAIN_ID;
5691
+ var NATIVE_EVM2, NATIVE_SOLANA2, CHAIN_TYPE_ALIASES2, SEI_EVM_CHAIN_ID, SEI_COSMOS_CHAIN_ID, EVM_ADDRESS_RE, NON_EVM_CHAIN_TYPES;
5683
5692
  var init_chainHelpers = __esm({
5684
5693
  "src/widget/helpers/chainHelpers.ts"() {
5685
5694
  "use strict";
@@ -5695,6 +5704,8 @@ var init_chainHelpers = __esm({
5695
5704
  };
5696
5705
  SEI_EVM_CHAIN_ID = "1329";
5697
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"]);
5698
5709
  }
5699
5710
  });
5700
5711
 
@@ -31827,7 +31838,18 @@ async function sendRouteAsUserOperation(params) {
31827
31838
  );
31828
31839
  }
31829
31840
  console.debug("[send] UserOp included", { userOpHash, txHash });
31830
- await submitReceipt(intentId, txHash, getSponsorshipRequestId(), eoaAddress);
31841
+ try {
31842
+ void submitReceipt(
31843
+ intentId,
31844
+ txHash,
31845
+ getSponsorshipRequestId(),
31846
+ eoaAddress
31847
+ ).catch((err) => {
31848
+ console.debug("[send] receipt submission failed (non-fatal)", err);
31849
+ });
31850
+ } catch (err) {
31851
+ console.debug("[send] receipt submission failed (non-fatal)", err);
31852
+ }
31831
31853
  return { userOpHash, txHash, intentId };
31832
31854
  }
31833
31855
  var NATIVE_ADDRS;
@@ -33773,8 +33795,7 @@ function useSwapExecution(fromChain) {
33773
33795
  return;
33774
33796
  }
33775
33797
  const chainType = normalizeChainType2(fromChain);
33776
- const isNative = !fromTokenAddress || isNativeTokenAddress(fromTokenAddress, chainType) || isZeroAddrLike(fromTokenAddress, chainType);
33777
- if (isNative) {
33798
+ if (!needsErc20Approval(fromTokenAddress, chainType)) {
33778
33799
  setState((p) => ({ ...p, allowanceStatus: "sufficient" }));
33779
33800
  return;
33780
33801
  }
@@ -33788,7 +33809,7 @@ function useSwapExecution(fromChain) {
33788
33809
  BigInt(a.amount || "0"),
33789
33810
  amountWei
33790
33811
  );
33791
- if (!token || !a.spender) return [];
33812
+ if (!isEvmAddress2(token) || !isEvmAddress2(a.spender)) return [];
33792
33813
  return [
33793
33814
  {
33794
33815
  chainId: a.chainId || chainIdStr,
@@ -33936,7 +33957,8 @@ function useSwapExecution(fromChain) {
33936
33957
  const requiredApprovals = plannedApprovals.length ? plannedApprovals.flatMap((a, index) => {
33937
33958
  const token = a.tokenAddress ?? fromTokenAddress;
33938
33959
  const approvalSpender = a.spender;
33939
- if (!token || !approvalSpender) return [];
33960
+ if (!isEvmAddress2(token) || !isEvmAddress2(approvalSpender))
33961
+ return [];
33940
33962
  const amountWei = requiredApprovalAmount(
33941
33963
  BigInt(a.amount || "0"),
33942
33964
  fromAmountWei
@@ -33959,7 +33981,8 @@ function useSwapExecution(fromChain) {
33959
33981
  chainId: chainIdStr
33960
33982
  }
33961
33983
  ] : [];
33962
- const ownsApprovals = !isNative && !!walletAddress && !!chainIdStr;
33984
+ const coversEveryPlannedApproval = plannedApprovals.length === 0 || requiredApprovals.length === plannedApprovals.length;
33985
+ const ownsApprovals = coversEveryPlannedApproval && needsErc20Approval(fromTokenAddress, chainType) && !!walletAddress && !!chainIdStr;
33963
33986
  const activeAddress = ownsApprovals ? await requireActiveAddress(wallet, walletAddress) : void 0;
33964
33987
  for (const required of requiredApprovals) {
33965
33988
  if (!ownsApprovals) break;
@@ -34049,10 +34072,6 @@ function useSwapExecution(fromChain) {
34049
34072
  numericChainId,
34050
34073
  { approvalsEnsured: ownsApprovals }
34051
34074
  );
34052
- try {
34053
- await submitReceipt(routeResult.intentId, hash);
34054
- } catch {
34055
- }
34056
34075
  setState((p) => ({
34057
34076
  ...p,
34058
34077
  isSubmitting: false,
@@ -34061,6 +34080,8 @@ function useSwapExecution(fromChain) {
34061
34080
  txStatus: "processing"
34062
34081
  }));
34063
34082
  startPolling(routeResult.intentId, onSuccess, onError);
34083
+ void submitReceipt(routeResult.intentId, hash).catch(() => {
34084
+ });
34064
34085
  } catch (err) {
34065
34086
  const msg = mapTxError(err);
34066
34087
  setState((p) => ({
@@ -36149,6 +36170,10 @@ function SwapMode({
36149
36170
  }, [lockDestToken, fromToken, fromChain, toToken, toChain, route, emitEvent]);
36150
36171
  const fromChainType = normalizeChainType2(fromChain);
36151
36172
  const toChainType = normalizeChainType2(toChain);
36173
+ const canSetMaxApproval = needsErc20Approval(
36174
+ fromToken?.address,
36175
+ fromChainType
36176
+ );
36152
36177
  const needsDestAddress = !!fromChainType && !!toChainType && fromChainType !== toChainType;
36153
36178
  const isValidDestAddress = !needsDestAddress || validateDestAddress(destAddress, toChainType ?? "");
36154
36179
  const handleReview = useCallback22(async () => {
@@ -36503,6 +36528,7 @@ function SwapMode({
36503
36528
  }, [route.loading]);
36504
36529
  useEffect34(() => {
36505
36530
  if (!route.data) return;
36531
+ if (stage !== "home" && stage !== "review") return;
36506
36532
  const id = setInterval(() => {
36507
36533
  const ts = quoteTimestampRef.current;
36508
36534
  if (ts === null) return;
@@ -36514,7 +36540,11 @@ function SwapMode({
36514
36540
  }
36515
36541
  }, 1e3);
36516
36542
  return () => clearInterval(id);
36517
- }, [route.data]);
36543
+ }, [route.data, stage]);
36544
+ const handleRetryQuote = useCallback22(() => {
36545
+ if (!latestFetchParamsRef.current) return;
36546
+ void fetchRef.current(latestFetchParamsRef.current);
36547
+ }, []);
36518
36548
  useEffect34(() => {
36519
36549
  if (stage !== "review") return;
36520
36550
  if (!route.data || !walletAddress) return;
@@ -38043,6 +38073,10 @@ function SwapMode({
38043
38073
  txStatus: execution.txStatus,
38044
38074
  isSubmitting: execution.isSubmitting,
38045
38075
  isGasSponsored,
38076
+ hasQuote: !!route.data,
38077
+ isQuoteRefreshing: route.loading,
38078
+ quoteError: route.error,
38079
+ onRetryQuote: handleRetryQuote,
38046
38080
  onExecute: () => void handleExecute()
38047
38081
  }
38048
38082
  )
@@ -38360,7 +38394,7 @@ function SwapMode({
38360
38394
  }
38361
38395
  )
38362
38396
  ] }),
38363
- /* @__PURE__ */ jsx59("div", { style: { marginBottom: spacing[4] }, children: /* @__PURE__ */ jsxs47(
38397
+ canSetMaxApproval && /* @__PURE__ */ jsx59("div", { style: { marginBottom: spacing[4] }, children: /* @__PURE__ */ jsxs47(
38364
38398
  "div",
38365
38399
  {
38366
38400
  style: {
@@ -39379,10 +39413,15 @@ function SwapActionArea({
39379
39413
  txStatus,
39380
39414
  isSubmitting,
39381
39415
  isGasSponsored,
39416
+ hasQuote,
39417
+ isQuoteRefreshing,
39418
+ quoteError,
39419
+ onRetryQuote,
39382
39420
  onExecute
39383
39421
  }) {
39384
39422
  const needsApproval = allowanceStatus === "needed" && !isGasSponsored;
39385
39423
  const isChecking = allowanceStatus === "checking";
39424
+ const quoteUnavailable = !hasQuote && !isQuoteRefreshing && !isSubmitting && txStatus === "idle";
39386
39425
  let label;
39387
39426
  if (isChecking) {
39388
39427
  label = "Checking approval...";
@@ -39390,12 +39429,14 @@ function SwapActionArea({
39390
39429
  label = `Approving ${fromTokenSymbol}...`;
39391
39430
  } else if (isSubmitting) {
39392
39431
  label = "Confirm in wallet...";
39432
+ } else if (isQuoteRefreshing) {
39433
+ label = "Refreshing quote...";
39393
39434
  } else if (needsApproval) {
39394
39435
  label = `Approve ${fromTokenSymbol}`;
39395
39436
  } else {
39396
39437
  label = "Swap";
39397
39438
  }
39398
- const isDisabled = isSubmitting || isChecking;
39439
+ const isDisabled = isSubmitting || isChecking || isQuoteRefreshing || !hasQuote;
39399
39440
  return /* @__PURE__ */ jsxs47("div", { style: { marginTop: spacing[6] }, children: [
39400
39441
  isGasSponsored && !isSubmitting && /* @__PURE__ */ jsxs47(
39401
39442
  "div",
@@ -39435,7 +39476,38 @@ function SwapActionArea({
39435
39476
  ]
39436
39477
  }
39437
39478
  ),
39438
- /* @__PURE__ */ jsx59(
39479
+ quoteUnavailable ? /* @__PURE__ */ jsxs47(Fragment13, { children: [
39480
+ /* @__PURE__ */ jsx59(
39481
+ "p",
39482
+ {
39483
+ style: {
39484
+ fontSize: fontSize.xs,
39485
+ color: colors.destructive,
39486
+ textAlign: "center",
39487
+ marginBottom: spacing[3]
39488
+ },
39489
+ children: quoteError ?? "This quote expired."
39490
+ }
39491
+ ),
39492
+ /* @__PURE__ */ jsx59(
39493
+ "button",
39494
+ {
39495
+ onClick: onRetryQuote,
39496
+ style: {
39497
+ width: "100%",
39498
+ height: "3.5rem",
39499
+ borderRadius: "1.5rem",
39500
+ backgroundColor: colors.primary,
39501
+ color: colors.primaryForeground,
39502
+ fontSize: fontSize.base,
39503
+ fontWeight: fontWeight.semibold,
39504
+ border: 0,
39505
+ cursor: "pointer"
39506
+ },
39507
+ children: "Get a new quote"
39508
+ }
39509
+ )
39510
+ ] }) : /* @__PURE__ */ jsx59(
39439
39511
  "button",
39440
39512
  {
39441
39513
  onClick: onExecute,