@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/README.md CHANGED
@@ -37,8 +37,6 @@ The current widget flow is:
37
37
 
38
38
  `Home -> Select Token -> Confirm Deposit -> Processing -> Success/Error`
39
39
 
40
- The refactored widget keeps the same behavior, but the configuration surface is now documented around the actual `TrustwareConfigOptions` shape and the current widget step model.
41
-
42
40
  ## Installation
43
41
 
44
42
  Supports React `18.2+` and `19`.
@@ -115,7 +113,7 @@ type TrustwareConfigOptions = {
115
113
  };
116
114
  };
117
115
  autoDetectProvider?: boolean;
118
- theme?: TrustwareWidgetTheme;
116
+ theme?: "light" | "dark" | "system"; // TrustwareTheme
119
117
  messages?: Partial<TrustwareWidgetMessages>;
120
118
  retry?: RetryConfig;
121
119
  walletConnect?: WalletConnectConfig;
@@ -172,7 +170,8 @@ type TrustwareConfigOptions = {
172
170
  ### Other Config Groups
173
171
 
174
172
  - `autoDetectProvider`: enables Trustware-managed wallet discovery.
175
- - `theme`: widget color and radius customization.
173
+ - `theme`: widget color mode — `"light" | "dark" | "system"` (default
174
+ `"system"`). Switch it at runtime with `Trustware.setTheme("dark")`.
176
175
  - `messages`: top-level copy overrides.
177
176
  - `retry`: API retry and rate-limit behavior.
178
177
  - `walletConnect`: WalletConnect overrides.
@@ -232,6 +231,13 @@ export function DepositPanel() {
232
231
  }
233
232
  ```
234
233
 
234
+ `useWagmi` (like `useEIP1193`) is a plain adapter factory, not a React hook,
235
+ despite the `use` prefix. If your ESLint setup runs `react-hooks/rules-of-hooks`
236
+ it will flag the call inside the `useMemo` callback above; silence it with an
237
+ `eslint-disable-next-line react-hooks/rules-of-hooks` comment — the call is
238
+ safe. See [docs.trustware.io](https://docs.trustware.io/guides/embedded-wallets#adapt-the-embedded-wallet)
239
+ for the same pattern with embedded wallets.
240
+
235
241
  Use this mode when:
236
242
 
237
243
  - your app already owns wallet state
@@ -285,19 +291,28 @@ Use this when you want Trustware’s routing and wallet plumbing without the wid
285
291
  ```ts
286
292
  import { Trustware } from "@trustware/sdk";
287
293
 
294
+ // buildRoute states both sides explicitly. fromAmount is in the source token's
295
+ // smallest unit, and the estimate comes back on the route — there is no
296
+ // separate quote call.
288
297
  const route = await Trustware.buildRoute({
289
- amount: "0.1",
298
+ fromChain: "1",
299
+ fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
300
+ toChain: "8453",
301
+ toToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", // native on Base
302
+ fromAmount: "25000000", // 25 USDC (6 decimals)
290
303
  fromAddress: await Trustware.getAddress(),
304
+ toAddress: "0xDestination...",
291
305
  });
306
+ console.log(route.route?.estimate, route.finalExchangeRate);
292
307
 
293
- const quote = await Trustware.getQuote(route);
294
-
295
- const result = await Trustware.runTopUp({
296
- amount: "0.1",
297
- fromAddress: await Trustware.getAddress(),
298
- });
308
+ // Or let the SDK own route + submit + receipt + polling. Missing route fields
309
+ // come from the provider config; the sender comes from the attached wallet.
310
+ const tx = await Trustware.runTopUp({ fromAmount: "25000000" });
311
+ console.log(tx.status, tx.destTxHash);
299
312
  ```
300
313
 
314
+ See [docs.trustware.io](https://docs.trustware.io) for the full headless flow.
315
+
301
316
  ## Common Config Examples
302
317
 
303
318
  ### Fixed Amount Deposit
@@ -347,26 +362,44 @@ Trustware.setDestinationAddress("0xDestination...");
347
362
 
348
363
  ## Rate Limiting
349
364
 
350
- Client retry behavior is configured through `retry`.
365
+ The API is rate limited per API key, and that limit is shared by everyone using
366
+ your key — not per end user. Your key's limit, its remaining requests and the
367
+ window boundary come back on every response (`X-RateLimit-Limit`, `-Remaining`,
368
+ `-Reset`, plus `Retry-After` on a 429).
369
+
370
+ The SDK retries 429s on the schedule those headers state — it keeps no schedule
371
+ of its own to disagree with them. It waits exactly as long as the server asks,
372
+ for as long as the total stays under 10 seconds. Past that it stops and throws,
373
+ because how long your app can afford to block is the one thing the server can't
374
+ know. If a response carries no timing at all, the SDK stops rather than
375
+ guessing: the limit is a fixed window, so an invented delay either lands inside
376
+ the same closed window or overshoots one it could have read exactly.
377
+
378
+ None of that is configurable — the limit is enforced server-side, so no client
379
+ setting can widen it. If you need more headroom, ask us to raise the limit on
380
+ your key. `retry` configures observability only:
351
381
 
352
382
  ```ts
353
383
  const config = {
354
384
  ...trustwareConfig,
355
385
  retry: {
356
- autoRetry: true,
357
- maxRetries: 3,
358
- baseDelayMs: 1000,
386
+ onRateLimitInfo: (info) => console.debug(info.remaining, "requests left"),
387
+ onRateLimited: (info, attempt) => console.warn("429", attempt, info),
388
+ onRateLimitApproaching: (info) => showSoftWarning(info),
359
389
  approachingThreshold: 5,
360
390
  },
361
391
  } satisfies TrustwareConfigOptions;
362
392
  ```
363
393
 
364
- If retries are exhausted, the SDK throws `RateLimitError`.
394
+ `RateLimitError` distinguishes the two ways the SDK gives up:
395
+
396
+ - `retriesExhausted: false` — the wait is known and simply longer than the SDK
397
+ will block for. `rateLimitInfo.retryAfter` holds it, so show the user when to
398
+ come back instead of leaving them on a spinner.
399
+ - `retriesExhausted: true` — the response carried no usable timing, so there was
400
+ nothing to retry against.
365
401
 
366
402
  ## Docs
367
403
 
368
- - [Integration Guide](docs/intergrationGuide.md)
369
- - [Core Guide](docs/coreGuide.md)
370
- - [Backend RPC Offload PDR](docs/backend-rpc-offload-pdr.md)
371
- - [Widget Architecture Boundaries](docs/widget-architecture-boundaries.md)
372
- - [Widget Refactor Baseline](docs/widget-refactor-baseline.md)
404
+ Full API reference, integration guides, and examples live at
405
+ [docs.trustware.io](https://docs.trustware.io).
@@ -30,7 +30,7 @@ __export(constants_exports, {
30
30
  });
31
31
  module.exports = __toCommonJS(constants_exports);
32
32
  var SDK_NAME = "@trustware/sdk";
33
- var SDK_VERSION = "1.1.11-staging.1";
33
+ var SDK_VERSION = "1.1.11-staging.2";
34
34
  var API_ROOT = "https://bv-staging-api.trustware.io";
35
35
  var GTM_ID = "GTM-TZDGNCXB";
36
36
  var API_PREFIX = "/api";
@@ -1,6 +1,6 @@
1
1
  // src/constants.ts
2
2
  var SDK_NAME = "@trustware/sdk";
3
- var SDK_VERSION = "1.1.11-staging.1";
3
+ var SDK_VERSION = "1.1.11-staging.2";
4
4
  var API_ROOT = "https://bv-staging-api.trustware.io";
5
5
  var GTM_ID = "GTM-TZDGNCXB";
6
6
  var API_PREFIX = "/api";
@@ -1,4 +1,4 @@
1
- import { n as BuildRouteResult, k as Transaction, T as TrustwareConfigOptions, i as WalletInterFaceAPI, z as ResolvedTrustwareConfig, V as TrustwareTheme, a1 as WalletIdentity, w as walletManager, Y as WalletAddressResolution, a8 as buildRoute, a9 as buildDepositAddress, aa as submitReceipt, ab as submitStepReceipt, ac as getStatus, ad as pollStatus } from './manager-BY3NHAks.js';
1
+ import { n as BuildRouteResult, k as Transaction, T as TrustwareConfigOptions, i as WalletInterFaceAPI, A as ResolvedTrustwareConfig, X as TrustwareTheme, a2 as WalletIdentity, w as walletManager, Z as WalletAddressResolution, aa as buildRoute, ab as buildDepositAddress, ac as submitReceipt, ad as submitStepReceipt, ae as getStatus, af as pollStatus } from './manager-Bw8b1wSD.js';
2
2
  import { C as ChainDef, c as ChainType, G as GetBalancesOptions, B as BalanceRow, a as BalanceStreamOptions, W as WalletAddressBalanceWrapper } from './blockchain-BxAFzp0s.js';
3
3
  import { T as Token } from './types-BJY9r-mz.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { n as BuildRouteResult, k as Transaction, T as TrustwareConfigOptions, i as WalletInterFaceAPI, z as ResolvedTrustwareConfig, V as TrustwareTheme, a1 as WalletIdentity, w as walletManager, Y as WalletAddressResolution, a8 as buildRoute, a9 as buildDepositAddress, aa as submitReceipt, ab as submitStepReceipt, ac as getStatus, ad as pollStatus } from './manager-DT8enQbE.cjs';
1
+ import { n as BuildRouteResult, k as Transaction, T as TrustwareConfigOptions, i as WalletInterFaceAPI, A as ResolvedTrustwareConfig, X as TrustwareTheme, a2 as WalletIdentity, w as walletManager, Z as WalletAddressResolution, aa as buildRoute, ab as buildDepositAddress, ac as submitReceipt, ad as submitStepReceipt, ae as getStatus, af as pollStatus } from './manager-DNGk1YkR.cjs';
2
2
  import { C as ChainDef, c as ChainType, G as GetBalancesOptions, B as BalanceRow, a as BalanceStreamOptions, W as WalletAddressBalanceWrapper } from './blockchain-BxAFzp0s.cjs';
3
3
  import { T as Token } from './types-DX3HtFcn.cjs';
4
4
 
package/dist/core.cjs CHANGED
@@ -47,16 +47,14 @@ var init_defaults = __esm({
47
47
  });
48
48
 
49
49
  // src/types/config.ts
50
- var DEFAULT_RETRY_CONFIG, DEFAULT_FEATURE_FLAGS;
50
+ var DEFAULT_RETRY_CONFIG, RATE_LIMIT_WAIT_BUDGET_MS, DEFAULT_FEATURE_FLAGS;
51
51
  var init_config = __esm({
52
52
  "src/types/config.ts"() {
53
53
  "use strict";
54
54
  DEFAULT_RETRY_CONFIG = {
55
- autoRetry: true,
56
- maxRetries: 3,
57
- baseDelayMs: 1e3,
58
55
  approachingThreshold: 5
59
56
  };
57
+ RATE_LIMIT_WAIT_BUDGET_MS = 1e4;
60
58
  DEFAULT_FEATURE_FLAGS = {
61
59
  tokensPagination: true,
62
60
  balanceStreaming: false,
@@ -75,7 +73,7 @@ var init_constants = __esm({
75
73
  "src/constants.ts"() {
76
74
  "use strict";
77
75
  SDK_NAME = "@trustware/sdk";
78
- SDK_VERSION = "1.1.11-staging.1";
76
+ SDK_VERSION = "1.1.11-staging.2";
79
77
  API_ROOT = "https://bv-staging-api.trustware.io";
80
78
  API_PREFIX = "/api";
81
79
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -157,60 +155,66 @@ function notifyRateLimitCallbacks(info, isRateLimited, retryCount) {
157
155
  retry.onRateLimitApproaching(info, retry.approachingThreshold);
158
156
  }
159
157
  }
160
- function calculateBackoffDelay(baseDelayMs, retryCount, retryAfter) {
161
- if (retryAfter && retryAfter > 0) {
162
- return retryAfter * 1e3;
158
+ function serverDirectedWaitMs(info) {
159
+ if (!info) return null;
160
+ if (typeof info.retryAfter === "number" && info.retryAfter > 0) {
161
+ return info.retryAfter * 1e3;
163
162
  }
164
- return baseDelayMs * Math.pow(2, retryCount);
163
+ if (typeof info.reset === "number" && info.reset > 0) {
164
+ const untilReset = info.reset * 1e3 - Date.now();
165
+ if (untilReset > 0) return untilReset;
166
+ }
167
+ return null;
165
168
  }
166
169
  function sleep(ms) {
167
170
  return new Promise((resolve) => setTimeout(resolve, ms));
168
171
  }
169
- async function rateLimitedFetch(url, options = {}) {
170
- const { skipRateLimit, ...fetchOptions } = options;
171
- const cfg = TrustwareConfigStore.get();
172
- if (!cfg.retry.autoRetry || skipRateLimit) {
173
- return fetch(url, fetchOptions);
174
- }
175
- const { maxRetries, baseDelayMs } = cfg.retry;
172
+ async function withRateLimitRetry(attempt) {
173
+ let waitedMs = 0;
176
174
  let retryCount = 0;
177
175
  while (true) {
178
- const response = await fetch(url, fetchOptions);
176
+ const response = await attempt();
179
177
  const rateLimitInfo = parseRateLimitHeaders(response);
180
- if (response.status === 429) {
178
+ if (response.status !== 429) {
181
179
  if (rateLimitInfo) {
182
- notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
180
+ notifyRateLimitCallbacks(rateLimitInfo, false, 0);
183
181
  }
184
- if (retryCount >= maxRetries) {
185
- throw new RateLimitError(
186
- rateLimitInfo || { limit: 0, remaining: 0, reset: 0 },
187
- true
188
- );
189
- }
190
- const delay = calculateBackoffDelay(
191
- baseDelayMs,
192
- retryCount,
193
- rateLimitInfo?.retryAfter
194
- );
195
- await sleep(delay);
196
- retryCount++;
197
- continue;
182
+ return response;
198
183
  }
199
184
  if (rateLimitInfo) {
200
- notifyRateLimitCallbacks(rateLimitInfo, false, 0);
185
+ notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
186
+ }
187
+ const waitMs = serverDirectedWaitMs(rateLimitInfo);
188
+ const info = rateLimitInfo || { limit: 0, remaining: 0, reset: 0 };
189
+ if (waitMs === null) {
190
+ throw new RateLimitError(info, true);
191
+ }
192
+ if (waitedMs + waitMs > RATE_LIMIT_WAIT_BUDGET_MS) {
193
+ throw new RateLimitError(info, false);
201
194
  }
202
- return response;
195
+ await sleep(waitMs);
196
+ waitedMs += waitMs;
197
+ retryCount++;
203
198
  }
204
199
  }
200
+ async function rateLimitedFetch(url, options = {}) {
201
+ const { skipRateLimit, ...fetchOptions } = options;
202
+ if (skipRateLimit) {
203
+ return fetch(url, fetchOptions);
204
+ }
205
+ return withRateLimitRetry(() => fetch(url, fetchOptions));
206
+ }
205
207
  var RateLimitError;
206
208
  var init_http = __esm({
207
209
  "src/core/http.ts"() {
208
210
  "use strict";
209
211
  init_constants();
210
212
  init_config2();
213
+ init_config();
211
214
  RateLimitError = class extends Error {
212
215
  constructor(info, retriesExhausted) {
213
- 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.`;
216
+ const seconds = info.retryAfter ?? (info.reset > 0 ? Math.max(0, Math.ceil((info.reset * 1e3 - Date.now()) / 1e3)) : null);
217
+ const message = seconds === null ? "Rate limit exceeded. The server did not say when to retry." : `Rate limit exceeded. Try again in ${seconds} seconds.`;
214
218
  super(message);
215
219
  this.name = "RateLimitError";
216
220
  this.rateLimitInfo = info;
@@ -1867,7 +1871,7 @@ async function getBalances(chainRef, address, opts) {
1867
1871
  if (cached) return cached;
1868
1872
  }
1869
1873
  const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
1870
- const response = await fetch(url, {
1874
+ const response = await rateLimitedFetch(url, {
1871
1875
  method: "GET",
1872
1876
  credentials: "omit",
1873
1877
  headers: jsonHeaders()
@@ -4115,7 +4119,18 @@ async function getStatus(intentId) {
4115
4119
  );
4116
4120
  await assertOK(r);
4117
4121
  const j = await r.json();
4118
- return j.data;
4122
+ return normalizeStatusPayload(j.data);
4123
+ }
4124
+ function normalizeStatusPayload(raw) {
4125
+ if (!raw || typeof raw !== "object") return raw;
4126
+ const wire = raw;
4127
+ const out = { ...wire };
4128
+ for (const [snake, camel] of Object.entries(STATUS_WIRE_TO_CAMEL)) {
4129
+ if (out[camel] !== void 0) continue;
4130
+ if (!(snake in wire)) continue;
4131
+ out[camel] = wire[snake];
4132
+ }
4133
+ return out;
4119
4134
  }
4120
4135
  async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } = {}) {
4121
4136
  const t0 = Date.now();
@@ -4126,12 +4141,39 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
4126
4141
  await new Promise((r) => setTimeout(r, intervalMs));
4127
4142
  }
4128
4143
  }
4144
+ var STATUS_WIRE_TO_CAMEL;
4129
4145
  var init_routes = __esm({
4130
4146
  "src/core/routes.ts"() {
4131
4147
  "use strict";
4132
4148
  init_http();
4133
4149
  init_store();
4134
4150
  init_address();
4151
+ STATUS_WIRE_TO_CAMEL = {
4152
+ intent_id: "intentId",
4153
+ from_address: "fromAddress",
4154
+ to_address: "toAddress",
4155
+ from_chain_id: "fromChainId",
4156
+ to_chain_id: "toChainId",
4157
+ source_tx_hash: "sourceTxHash",
4158
+ dest_tx_hash: "destTxHash",
4159
+ request_id: "requestId",
4160
+ provider_request_id: "providerRequestId",
4161
+ transaction_request: "transactionRequest",
4162
+ status_raw: "statusRaw",
4163
+ route_path: "routePath",
4164
+ route_status: "routeStatus",
4165
+ to_amount_wei: "toAmountWei",
4166
+ from_chain_block: "fromChainBlock",
4167
+ to_chain_block: "toChainBlock",
4168
+ from_chain_tx_url: "fromChainTxUrl",
4169
+ to_chain_tx_url: "toChainTxUrl",
4170
+ gas_status: "gasStatus",
4171
+ is_gmp_transaction: "isGMPTransaction",
4172
+ axelar_transaction_url: "axelarTransactionUrl",
4173
+ create_date: "createdDate",
4174
+ update_date: "updatedDate",
4175
+ time_spent_ms: "timeSpentMs"
4176
+ };
4135
4177
  }
4136
4178
  });
4137
4179
 
@@ -6604,9 +6646,6 @@ function resolveConfig(input) {
6604
6646
  const theme = input.theme ?? "system";
6605
6647
  const messages = deepMerge(DEFAULT_MESSAGES, input.messages);
6606
6648
  const retry = {
6607
- autoRetry: input.retry?.autoRetry ?? DEFAULT_RETRY_CONFIG.autoRetry,
6608
- maxRetries: input.retry?.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
6609
- baseDelayMs: input.retry?.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
6610
6649
  approachingThreshold: input.retry?.approachingThreshold ?? DEFAULT_RETRY_CONFIG.approachingThreshold,
6611
6650
  onRateLimitInfo: input.retry?.onRateLimitInfo,
6612
6651
  onRateLimited: input.retry?.onRateLimited,
@@ -6739,6 +6778,7 @@ var init_core = __esm({
6739
6778
  init_store();
6740
6779
  init_wallets();
6741
6780
  init_routes();
6781
+ init_routes();
6742
6782
  init_balances();
6743
6783
  init_tx();
6744
6784
  init_http();
@@ -6893,7 +6933,8 @@ var init_core = __esm({
6893
6933
  // src/core.ts
6894
6934
  var core_exports = {};
6895
6935
  __export(core_exports, {
6896
- Trustware: () => Trustware
6936
+ Trustware: () => Trustware,
6937
+ assertValidPostHook: () => assertValidPostHook
6897
6938
  });
6898
6939
  module.exports = __toCommonJS(core_exports);
6899
6940
  var init_core2 = __esm({
@@ -6904,6 +6945,7 @@ var init_core2 = __esm({
6904
6945
  init_core2();
6905
6946
  // Annotate the CommonJS export names for ESM import in node:
6906
6947
  0 && (module.exports = {
6907
- Trustware
6948
+ Trustware,
6949
+ assertValidPostHook
6908
6950
  });
6909
6951
  //# sourceMappingURL=core.cjs.map