@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.cjs CHANGED
@@ -557,16 +557,14 @@ var init_defaults = __esm({
557
557
  });
558
558
 
559
559
  // src/types/config.ts
560
- var DEFAULT_RETRY_CONFIG, DEFAULT_FEATURE_FLAGS;
560
+ var DEFAULT_RETRY_CONFIG, RATE_LIMIT_WAIT_BUDGET_MS, DEFAULT_FEATURE_FLAGS;
561
561
  var init_config = __esm({
562
562
  "src/types/config.ts"() {
563
563
  "use strict";
564
564
  DEFAULT_RETRY_CONFIG = {
565
- autoRetry: true,
566
- maxRetries: 3,
567
- baseDelayMs: 1e3,
568
565
  approachingThreshold: 5
569
566
  };
567
+ RATE_LIMIT_WAIT_BUDGET_MS = 1e4;
570
568
  DEFAULT_FEATURE_FLAGS = {
571
569
  tokensPagination: true,
572
570
  balanceStreaming: false,
@@ -585,7 +583,7 @@ var init_constants = __esm({
585
583
  "src/constants.ts"() {
586
584
  "use strict";
587
585
  SDK_NAME = "@trustware/sdk";
588
- SDK_VERSION = "1.1.11-staging.1";
586
+ SDK_VERSION = "1.1.11-staging.2";
589
587
  API_ROOT = "https://bv-staging-api.trustware.io";
590
588
  GTM_ID = "GTM-TZDGNCXB";
591
589
  API_PREFIX = "/api";
@@ -672,50 +670,54 @@ function notifyRateLimitCallbacks(info, isRateLimited, retryCount) {
672
670
  retry.onRateLimitApproaching(info, retry.approachingThreshold);
673
671
  }
674
672
  }
675
- function calculateBackoffDelay(baseDelayMs, retryCount, retryAfter) {
676
- if (retryAfter && retryAfter > 0) {
677
- return retryAfter * 1e3;
673
+ function serverDirectedWaitMs(info) {
674
+ if (!info) return null;
675
+ if (typeof info.retryAfter === "number" && info.retryAfter > 0) {
676
+ return info.retryAfter * 1e3;
678
677
  }
679
- return baseDelayMs * Math.pow(2, retryCount);
678
+ if (typeof info.reset === "number" && info.reset > 0) {
679
+ const untilReset = info.reset * 1e3 - Date.now();
680
+ if (untilReset > 0) return untilReset;
681
+ }
682
+ return null;
680
683
  }
681
684
  function sleep(ms) {
682
685
  return new Promise((resolve) => setTimeout(resolve, ms));
683
686
  }
684
- async function rateLimitedFetch(url, options = {}) {
685
- const { skipRateLimit, ...fetchOptions } = options;
686
- const cfg = TrustwareConfigStore.get();
687
- if (!cfg.retry.autoRetry || skipRateLimit) {
688
- return fetch(url, fetchOptions);
689
- }
690
- const { maxRetries, baseDelayMs } = cfg.retry;
687
+ async function withRateLimitRetry(attempt) {
688
+ let waitedMs = 0;
691
689
  let retryCount = 0;
692
690
  while (true) {
693
- const response = await fetch(url, fetchOptions);
691
+ const response = await attempt();
694
692
  const rateLimitInfo = parseRateLimitHeaders(response);
695
- if (response.status === 429) {
693
+ if (response.status !== 429) {
696
694
  if (rateLimitInfo) {
697
- notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
695
+ notifyRateLimitCallbacks(rateLimitInfo, false, 0);
698
696
  }
699
- if (retryCount >= maxRetries) {
700
- throw new RateLimitError(
701
- rateLimitInfo || { limit: 0, remaining: 0, reset: 0 },
702
- true
703
- );
704
- }
705
- const delay = calculateBackoffDelay(
706
- baseDelayMs,
707
- retryCount,
708
- rateLimitInfo?.retryAfter
709
- );
710
- await sleep(delay);
711
- retryCount++;
712
- continue;
697
+ return response;
713
698
  }
714
699
  if (rateLimitInfo) {
715
- notifyRateLimitCallbacks(rateLimitInfo, false, 0);
700
+ notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
701
+ }
702
+ const waitMs = serverDirectedWaitMs(rateLimitInfo);
703
+ const info = rateLimitInfo || { limit: 0, remaining: 0, reset: 0 };
704
+ if (waitMs === null) {
705
+ throw new RateLimitError(info, true);
706
+ }
707
+ if (waitedMs + waitMs > RATE_LIMIT_WAIT_BUDGET_MS) {
708
+ throw new RateLimitError(info, false);
716
709
  }
717
- return response;
710
+ await sleep(waitMs);
711
+ waitedMs += waitMs;
712
+ retryCount++;
713
+ }
714
+ }
715
+ async function rateLimitedFetch(url, options = {}) {
716
+ const { skipRateLimit, ...fetchOptions } = options;
717
+ if (skipRateLimit) {
718
+ return fetch(url, fetchOptions);
718
719
  }
720
+ return withRateLimitRetry(() => fetch(url, fetchOptions));
719
721
  }
720
722
  var RateLimitError;
721
723
  var init_http = __esm({
@@ -723,9 +725,11 @@ var init_http = __esm({
723
725
  "use strict";
724
726
  init_constants();
725
727
  init_config2();
728
+ init_config();
726
729
  RateLimitError = class extends Error {
727
730
  constructor(info, retriesExhausted) {
728
- 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.`;
731
+ const seconds = info.retryAfter ?? (info.reset > 0 ? Math.max(0, Math.ceil((info.reset * 1e3 - Date.now()) / 1e3)) : null);
732
+ const message = seconds === null ? "Rate limit exceeded. The server did not say when to retry." : `Rate limit exceeded. Try again in ${seconds} seconds.`;
729
733
  super(message);
730
734
  this.name = "RateLimitError";
731
735
  this.rateLimitInfo = info;
@@ -2382,7 +2386,7 @@ async function getBalances(chainRef, address, opts) {
2382
2386
  if (cached) return cached;
2383
2387
  }
2384
2388
  const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
2385
- const response = await fetch(url, {
2389
+ const response = await rateLimitedFetch(url, {
2386
2390
  method: "GET",
2387
2391
  credentials: "omit",
2388
2392
  headers: jsonHeaders()
@@ -2626,7 +2630,18 @@ async function getStatus(intentId) {
2626
2630
  );
2627
2631
  await assertOK(r);
2628
2632
  const j = await r.json();
2629
- return j.data;
2633
+ return normalizeStatusPayload(j.data);
2634
+ }
2635
+ function normalizeStatusPayload(raw) {
2636
+ if (!raw || typeof raw !== "object") return raw;
2637
+ const wire = raw;
2638
+ const out = { ...wire };
2639
+ for (const [snake, camel] of Object.entries(STATUS_WIRE_TO_CAMEL)) {
2640
+ if (out[camel] !== void 0) continue;
2641
+ if (!(snake in wire)) continue;
2642
+ out[camel] = wire[snake];
2643
+ }
2644
+ return out;
2630
2645
  }
2631
2646
  async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } = {}) {
2632
2647
  const t0 = Date.now();
@@ -2637,12 +2652,39 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
2637
2652
  await new Promise((r) => setTimeout(r, intervalMs));
2638
2653
  }
2639
2654
  }
2655
+ var STATUS_WIRE_TO_CAMEL;
2640
2656
  var init_routes = __esm({
2641
2657
  "src/core/routes.ts"() {
2642
2658
  "use strict";
2643
2659
  init_http();
2644
2660
  init_store();
2645
2661
  init_address();
2662
+ STATUS_WIRE_TO_CAMEL = {
2663
+ intent_id: "intentId",
2664
+ from_address: "fromAddress",
2665
+ to_address: "toAddress",
2666
+ from_chain_id: "fromChainId",
2667
+ to_chain_id: "toChainId",
2668
+ source_tx_hash: "sourceTxHash",
2669
+ dest_tx_hash: "destTxHash",
2670
+ request_id: "requestId",
2671
+ provider_request_id: "providerRequestId",
2672
+ transaction_request: "transactionRequest",
2673
+ status_raw: "statusRaw",
2674
+ route_path: "routePath",
2675
+ route_status: "routeStatus",
2676
+ to_amount_wei: "toAmountWei",
2677
+ from_chain_block: "fromChainBlock",
2678
+ to_chain_block: "toChainBlock",
2679
+ from_chain_tx_url: "fromChainTxUrl",
2680
+ to_chain_tx_url: "toChainTxUrl",
2681
+ gas_status: "gasStatus",
2682
+ is_gmp_transaction: "isGMPTransaction",
2683
+ axelar_transaction_url: "axelarTransactionUrl",
2684
+ create_date: "createdDate",
2685
+ update_date: "updatedDate",
2686
+ time_spent_ms: "timeSpentMs"
2687
+ };
2646
2688
  }
2647
2689
  });
2648
2690
 
@@ -2933,12 +2975,9 @@ function useTrustwareConfig() {
2933
2975
  title: "Trustware SDK",
2934
2976
  description: "Seamlessly bridge assets across chains with Trustware."
2935
2977
  },
2936
- retry: {
2937
- autoRetry: true,
2938
- maxRetries: 3,
2939
- baseDelayMs: 1e3,
2940
- approachingThreshold: 5
2941
- },
2978
+ // Shared with the resolver rather than restated, so this placeholder
2979
+ // can't drift from the real defaults.
2980
+ retry: { ...DEFAULT_RETRY_CONFIG },
2942
2981
  features: {
2943
2982
  tokensPagination: true,
2944
2983
  balanceStreaming: false,
@@ -2965,6 +3004,7 @@ var init_useTrustwareConfig = __esm({
2965
3004
  "use strict";
2966
3005
  "use client";
2967
3006
  import_react2 = require("react");
3007
+ init_config();
2968
3008
  init_store();
2969
3009
  }
2970
3010
  });
@@ -8956,9 +8996,6 @@ function resolveConfig(input) {
8956
8996
  const theme = input.theme ?? "system";
8957
8997
  const messages = deepMerge(DEFAULT_MESSAGES, input.messages);
8958
8998
  const retry = {
8959
- autoRetry: input.retry?.autoRetry ?? DEFAULT_RETRY_CONFIG.autoRetry,
8960
- maxRetries: input.retry?.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
8961
- baseDelayMs: input.retry?.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
8962
8999
  approachingThreshold: input.retry?.approachingThreshold ?? DEFAULT_RETRY_CONFIG.approachingThreshold,
8963
9000
  onRateLimitInfo: input.retry?.onRateLimitInfo,
8964
9001
  onRateLimited: input.retry?.onRateLimited,
@@ -30668,7 +30705,7 @@ var init_src = __esm({
30668
30705
  });
30669
30706
 
30670
30707
  // src/smart-account/client.ts
30671
- async function fetchWithTimeout(url, init) {
30708
+ async function fetchOnceWithTimeout(url, init) {
30672
30709
  const controller = new AbortController();
30673
30710
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
30674
30711
  try {
@@ -30689,6 +30726,9 @@ async function fetchWithTimeout(url, init) {
30689
30726
  clearTimeout(timer);
30690
30727
  }
30691
30728
  }
30729
+ async function fetchWithTimeout(url, init) {
30730
+ return withRateLimitRetry(() => fetchOnceWithTimeout(url, init));
30731
+ }
30692
30732
  function extractRevertHex(err) {
30693
30733
  if (typeof err.data === "string" && err.data.startsWith("0x"))
30694
30734
  return err.data;
@@ -31181,7 +31221,7 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
31181
31221
  tokenUnitsPerDollar = Number(fromAmountWei) / fromUSD;
31182
31222
  } else if (fromToken && fromDecimals !== void 0) {
31183
31223
  try {
31184
- const resp = await fetch(
31224
+ const resp = await rateLimitedFetch(
31185
31225
  `${apiBase()}/v1/price/token?chainId=${cid}&address=${fromToken}`,
31186
31226
  { headers: jsonHeaders() }
31187
31227
  );
@@ -31197,9 +31237,10 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
31197
31237
  return 0n;
31198
31238
  }
31199
31239
  try {
31200
- const resp = await fetch(`${apiBase()}/v1/price/native?chainId=${cid}`, {
31201
- headers: jsonHeaders()
31202
- });
31240
+ const resp = await rateLimitedFetch(
31241
+ `${apiBase()}/v1/price/native?chainId=${cid}`,
31242
+ { headers: jsonHeaders() }
31243
+ );
31203
31244
  if (!resp.ok) throw new Error(`native price HTTP ${resp.status}`);
31204
31245
  const json = await resp.json();
31205
31246
  const ethPriceUSD = parseFloat(json.data?.priceUSD ?? "0");
@@ -33944,9 +33985,14 @@ var init_useSwapExecution = __esm({
33944
33985
 
33945
33986
  // src/core/forex.ts
33946
33987
  async function fetchForexRates(base2 = "USD") {
33947
- const r = await fetch(`${apiBase()}/v1/forex?base=${base2}`, {
33948
- headers: jsonHeaders()
33949
- });
33988
+ let r;
33989
+ try {
33990
+ r = await rateLimitedFetch(`${apiBase()}/v1/forex?base=${base2}`, {
33991
+ headers: jsonHeaders()
33992
+ });
33993
+ } catch {
33994
+ return {};
33995
+ }
33950
33996
  if (!r.ok) return {};
33951
33997
  const j = await r.json();
33952
33998
  const rates = j?.data?.rates ?? j?.rates ?? j?.data ?? {};