@trustware/sdk-staging 1.1.11-staging.1 → 1.1.11-staging.2

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 (38) hide show
  1. package/README.md +54 -21
  2. package/dist/constants.cjs +1 -1
  3. package/dist/constants.mjs +1 -1
  4. package/dist/{core-BgYLe9Q7.d.ts → core-B1WCJfDI.d.ts} +1 -1
  5. package/dist/{core-fLSt4qD2.d.cts → core-CeNTuqPz.d.cts} +1 -1
  6. package/dist/core.cjs +85 -43
  7. package/dist/core.cjs.map +1 -1
  8. package/dist/core.d.cts +2 -2
  9. package/dist/core.d.ts +2 -2
  10. package/dist/core.mjs +83 -42
  11. package/dist/core.mjs.map +1 -1
  12. package/dist/index.cjs +107 -55
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +11 -5
  15. package/dist/index.d.ts +11 -5
  16. package/dist/index.mjs +105 -55
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/{manager-BY3NHAks.d.ts → manager-Bw8b1wSD.d.ts} +89 -22
  19. package/dist/{manager-DT8enQbE.d.cts → manager-DNGk1YkR.d.cts} +89 -22
  20. package/dist/{metadata-BPvFYMlc.d.ts → metadata-C__KMeuz.d.ts} +1 -1
  21. package/dist/{metadata-DyxUcKHk.d.cts → metadata-Dk4R8_-T.d.cts} +1 -1
  22. package/dist/smart-account.cjs +49 -44
  23. package/dist/smart-account.cjs.map +1 -1
  24. package/dist/smart-account.d.cts +5 -0
  25. package/dist/smart-account.d.ts +5 -0
  26. package/dist/smart-account.mjs +49 -44
  27. package/dist/smart-account.mjs.map +1 -1
  28. package/dist/wallet.cjs +40 -39
  29. package/dist/wallet.cjs.map +1 -1
  30. package/dist/wallet.d.cts +3 -3
  31. package/dist/wallet.d.ts +3 -3
  32. package/dist/wallet.mjs +40 -39
  33. package/dist/wallet.mjs.map +1 -1
  34. package/dist/widget.cjs +101 -55
  35. package/dist/widget.cjs.map +1 -1
  36. package/dist/widget.mjs +101 -55
  37. package/dist/widget.mjs.map +1 -1
  38. package/package.json +73 -5
package/dist/widget.mjs CHANGED
@@ -535,16 +535,14 @@ var init_defaults = __esm({
535
535
  });
536
536
 
537
537
  // src/types/config.ts
538
- var DEFAULT_RETRY_CONFIG, DEFAULT_FEATURE_FLAGS;
538
+ var DEFAULT_RETRY_CONFIG, RATE_LIMIT_WAIT_BUDGET_MS, DEFAULT_FEATURE_FLAGS;
539
539
  var init_config = __esm({
540
540
  "src/types/config.ts"() {
541
541
  "use strict";
542
542
  DEFAULT_RETRY_CONFIG = {
543
- autoRetry: true,
544
- maxRetries: 3,
545
- baseDelayMs: 1e3,
546
543
  approachingThreshold: 5
547
544
  };
545
+ RATE_LIMIT_WAIT_BUDGET_MS = 1e4;
548
546
  DEFAULT_FEATURE_FLAGS = {
549
547
  tokensPagination: true,
550
548
  balanceStreaming: false,
@@ -563,7 +561,7 @@ var init_constants = __esm({
563
561
  "src/constants.ts"() {
564
562
  "use strict";
565
563
  SDK_NAME = "@trustware/sdk";
566
- SDK_VERSION = "1.1.11-staging.1";
564
+ SDK_VERSION = "1.1.11-staging.2";
567
565
  API_ROOT = "https://bv-staging-api.trustware.io";
568
566
  GTM_ID = "GTM-TZDGNCXB";
569
567
  API_PREFIX = "/api";
@@ -650,50 +648,54 @@ function notifyRateLimitCallbacks(info, isRateLimited, retryCount) {
650
648
  retry.onRateLimitApproaching(info, retry.approachingThreshold);
651
649
  }
652
650
  }
653
- function calculateBackoffDelay(baseDelayMs, retryCount, retryAfter) {
654
- if (retryAfter && retryAfter > 0) {
655
- return retryAfter * 1e3;
651
+ function serverDirectedWaitMs(info) {
652
+ if (!info) return null;
653
+ if (typeof info.retryAfter === "number" && info.retryAfter > 0) {
654
+ return info.retryAfter * 1e3;
656
655
  }
657
- return baseDelayMs * Math.pow(2, retryCount);
656
+ if (typeof info.reset === "number" && info.reset > 0) {
657
+ const untilReset = info.reset * 1e3 - Date.now();
658
+ if (untilReset > 0) return untilReset;
659
+ }
660
+ return null;
658
661
  }
659
662
  function sleep(ms) {
660
663
  return new Promise((resolve) => setTimeout(resolve, ms));
661
664
  }
662
- async function rateLimitedFetch(url, options = {}) {
663
- const { skipRateLimit, ...fetchOptions } = options;
664
- const cfg = TrustwareConfigStore.get();
665
- if (!cfg.retry.autoRetry || skipRateLimit) {
666
- return fetch(url, fetchOptions);
667
- }
668
- const { maxRetries, baseDelayMs } = cfg.retry;
665
+ async function withRateLimitRetry(attempt) {
666
+ let waitedMs = 0;
669
667
  let retryCount = 0;
670
668
  while (true) {
671
- const response = await fetch(url, fetchOptions);
669
+ const response = await attempt();
672
670
  const rateLimitInfo = parseRateLimitHeaders(response);
673
- if (response.status === 429) {
671
+ if (response.status !== 429) {
674
672
  if (rateLimitInfo) {
675
- notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
673
+ notifyRateLimitCallbacks(rateLimitInfo, false, 0);
676
674
  }
677
- if (retryCount >= maxRetries) {
678
- throw new RateLimitError(
679
- rateLimitInfo || { limit: 0, remaining: 0, reset: 0 },
680
- true
681
- );
682
- }
683
- const delay = calculateBackoffDelay(
684
- baseDelayMs,
685
- retryCount,
686
- rateLimitInfo?.retryAfter
687
- );
688
- await sleep(delay);
689
- retryCount++;
690
- continue;
675
+ return response;
691
676
  }
692
677
  if (rateLimitInfo) {
693
- notifyRateLimitCallbacks(rateLimitInfo, false, 0);
678
+ notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
679
+ }
680
+ const waitMs = serverDirectedWaitMs(rateLimitInfo);
681
+ const info = rateLimitInfo || { limit: 0, remaining: 0, reset: 0 };
682
+ if (waitMs === null) {
683
+ throw new RateLimitError(info, true);
684
+ }
685
+ if (waitedMs + waitMs > RATE_LIMIT_WAIT_BUDGET_MS) {
686
+ throw new RateLimitError(info, false);
694
687
  }
695
- return response;
688
+ await sleep(waitMs);
689
+ waitedMs += waitMs;
690
+ retryCount++;
691
+ }
692
+ }
693
+ async function rateLimitedFetch(url, options = {}) {
694
+ const { skipRateLimit, ...fetchOptions } = options;
695
+ if (skipRateLimit) {
696
+ return fetch(url, fetchOptions);
696
697
  }
698
+ return withRateLimitRetry(() => fetch(url, fetchOptions));
697
699
  }
698
700
  var RateLimitError;
699
701
  var init_http = __esm({
@@ -701,9 +703,11 @@ var init_http = __esm({
701
703
  "use strict";
702
704
  init_constants();
703
705
  init_config2();
706
+ init_config();
704
707
  RateLimitError = class extends Error {
705
708
  constructor(info, retriesExhausted) {
706
- const message = retriesExhausted ? `Rate limit exceeded after max retries. Try again in ${info.retryAfter ?? Math.ceil((info.reset * 1e3 - Date.now()) / 1e3)} seconds.` : `Rate limit exceeded. Try again in ${info.retryAfter} seconds.`;
709
+ const seconds = info.retryAfter ?? (info.reset > 0 ? Math.max(0, Math.ceil((info.reset * 1e3 - Date.now()) / 1e3)) : null);
710
+ const message = seconds === null ? "Rate limit exceeded. The server did not say when to retry." : `Rate limit exceeded. Try again in ${seconds} seconds.`;
707
711
  super(message);
708
712
  this.name = "RateLimitError";
709
713
  this.rateLimitInfo = info;
@@ -2360,7 +2364,7 @@ async function getBalances(chainRef, address, opts) {
2360
2364
  if (cached) return cached;
2361
2365
  }
2362
2366
  const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
2363
- const response = await fetch(url, {
2367
+ const response = await rateLimitedFetch(url, {
2364
2368
  method: "GET",
2365
2369
  credentials: "omit",
2366
2370
  headers: jsonHeaders()
@@ -2604,7 +2608,18 @@ async function getStatus(intentId) {
2604
2608
  );
2605
2609
  await assertOK(r);
2606
2610
  const j = await r.json();
2607
- return j.data;
2611
+ return normalizeStatusPayload(j.data);
2612
+ }
2613
+ function normalizeStatusPayload(raw) {
2614
+ if (!raw || typeof raw !== "object") return raw;
2615
+ const wire = raw;
2616
+ const out = { ...wire };
2617
+ for (const [snake, camel] of Object.entries(STATUS_WIRE_TO_CAMEL)) {
2618
+ if (out[camel] !== void 0) continue;
2619
+ if (!(snake in wire)) continue;
2620
+ out[camel] = wire[snake];
2621
+ }
2622
+ return out;
2608
2623
  }
2609
2624
  async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } = {}) {
2610
2625
  const t0 = Date.now();
@@ -2615,12 +2630,39 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
2615
2630
  await new Promise((r) => setTimeout(r, intervalMs));
2616
2631
  }
2617
2632
  }
2633
+ var STATUS_WIRE_TO_CAMEL;
2618
2634
  var init_routes = __esm({
2619
2635
  "src/core/routes.ts"() {
2620
2636
  "use strict";
2621
2637
  init_http();
2622
2638
  init_store();
2623
2639
  init_address();
2640
+ STATUS_WIRE_TO_CAMEL = {
2641
+ intent_id: "intentId",
2642
+ from_address: "fromAddress",
2643
+ to_address: "toAddress",
2644
+ from_chain_id: "fromChainId",
2645
+ to_chain_id: "toChainId",
2646
+ source_tx_hash: "sourceTxHash",
2647
+ dest_tx_hash: "destTxHash",
2648
+ request_id: "requestId",
2649
+ provider_request_id: "providerRequestId",
2650
+ transaction_request: "transactionRequest",
2651
+ status_raw: "statusRaw",
2652
+ route_path: "routePath",
2653
+ route_status: "routeStatus",
2654
+ to_amount_wei: "toAmountWei",
2655
+ from_chain_block: "fromChainBlock",
2656
+ to_chain_block: "toChainBlock",
2657
+ from_chain_tx_url: "fromChainTxUrl",
2658
+ to_chain_tx_url: "toChainTxUrl",
2659
+ gas_status: "gasStatus",
2660
+ is_gmp_transaction: "isGMPTransaction",
2661
+ axelar_transaction_url: "axelarTransactionUrl",
2662
+ create_date: "createdDate",
2663
+ update_date: "updatedDate",
2664
+ time_spent_ms: "timeSpentMs"
2665
+ };
2624
2666
  }
2625
2667
  });
2626
2668
 
@@ -2911,12 +2953,9 @@ function useTrustwareConfig() {
2911
2953
  title: "Trustware SDK",
2912
2954
  description: "Seamlessly bridge assets across chains with Trustware."
2913
2955
  },
2914
- retry: {
2915
- autoRetry: true,
2916
- maxRetries: 3,
2917
- baseDelayMs: 1e3,
2918
- approachingThreshold: 5
2919
- },
2956
+ // Shared with the resolver rather than restated, so this placeholder
2957
+ // can't drift from the real defaults.
2958
+ retry: { ...DEFAULT_RETRY_CONFIG },
2920
2959
  features: {
2921
2960
  tokensPagination: true,
2922
2961
  balanceStreaming: false,
@@ -2941,6 +2980,7 @@ var init_useTrustwareConfig = __esm({
2941
2980
  "src/hooks/useTrustwareConfig.ts"() {
2942
2981
  "use strict";
2943
2982
  "use client";
2983
+ init_config();
2944
2984
  init_store();
2945
2985
  }
2946
2986
  });
@@ -8929,9 +8969,6 @@ function resolveConfig(input) {
8929
8969
  const theme = input.theme ?? "system";
8930
8970
  const messages = deepMerge(DEFAULT_MESSAGES, input.messages);
8931
8971
  const retry = {
8932
- autoRetry: input.retry?.autoRetry ?? DEFAULT_RETRY_CONFIG.autoRetry,
8933
- maxRetries: input.retry?.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
8934
- baseDelayMs: input.retry?.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
8935
8972
  approachingThreshold: input.retry?.approachingThreshold ?? DEFAULT_RETRY_CONFIG.approachingThreshold,
8936
8973
  onRateLimitInfo: input.retry?.onRateLimitInfo,
8937
8974
  onRateLimited: input.retry?.onRateLimited,
@@ -30607,7 +30644,7 @@ import {
30607
30644
  keccak256 as keccak2566,
30608
30645
  stringToHex
30609
30646
  } from "viem";
30610
- async function fetchWithTimeout(url, init) {
30647
+ async function fetchOnceWithTimeout(url, init) {
30611
30648
  const controller = new AbortController();
30612
30649
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
30613
30650
  try {
@@ -30628,6 +30665,9 @@ async function fetchWithTimeout(url, init) {
30628
30665
  clearTimeout(timer);
30629
30666
  }
30630
30667
  }
30668
+ async function fetchWithTimeout(url, init) {
30669
+ return withRateLimitRetry(() => fetchOnceWithTimeout(url, init));
30670
+ }
30631
30671
  function extractRevertHex(err) {
30632
30672
  if (typeof err.data === "string" && err.data.startsWith("0x"))
30633
30673
  return err.data;
@@ -31127,7 +31167,7 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
31127
31167
  tokenUnitsPerDollar = Number(fromAmountWei) / fromUSD;
31128
31168
  } else if (fromToken && fromDecimals !== void 0) {
31129
31169
  try {
31130
- const resp = await fetch(
31170
+ const resp = await rateLimitedFetch(
31131
31171
  `${apiBase()}/v1/price/token?chainId=${cid}&address=${fromToken}`,
31132
31172
  { headers: jsonHeaders() }
31133
31173
  );
@@ -31143,9 +31183,10 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
31143
31183
  return 0n;
31144
31184
  }
31145
31185
  try {
31146
- const resp = await fetch(`${apiBase()}/v1/price/native?chainId=${cid}`, {
31147
- headers: jsonHeaders()
31148
- });
31186
+ const resp = await rateLimitedFetch(
31187
+ `${apiBase()}/v1/price/native?chainId=${cid}`,
31188
+ { headers: jsonHeaders() }
31189
+ );
31149
31190
  if (!resp.ok) throw new Error(`native price HTTP ${resp.status}`);
31150
31191
  const json = await resp.json();
31151
31192
  const ethPriceUSD = parseFloat(json.data?.priceUSD ?? "0");
@@ -33885,9 +33926,14 @@ var init_useSwapExecution = __esm({
33885
33926
 
33886
33927
  // src/core/forex.ts
33887
33928
  async function fetchForexRates(base2 = "USD") {
33888
- const r = await fetch(`${apiBase()}/v1/forex?base=${base2}`, {
33889
- headers: jsonHeaders()
33890
- });
33929
+ let r;
33930
+ try {
33931
+ r = await rateLimitedFetch(`${apiBase()}/v1/forex?base=${base2}`, {
33932
+ headers: jsonHeaders()
33933
+ });
33934
+ } catch {
33935
+ return {};
33936
+ }
33891
33937
  if (!r.ok) return {};
33892
33938
  const j = await r.json();
33893
33939
  const rates = j?.data?.rates ?? j?.rates ?? j?.data ?? {};