@trustware/sdk-staging 1.1.10-staging.0 → 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-BPLiD1UG.d.ts → core-B1WCJfDI.d.ts} +15 -2
  5. package/dist/{core-B7Ez-5-r.d.cts → core-CeNTuqPz.d.cts} +15 -2
  6. package/dist/core.cjs +365 -279
  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 +363 -278
  11. package/dist/core.mjs.map +1 -1
  12. package/dist/index.cjs +375 -170
  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 +373 -169
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/{manager-B6NNV-E_.d.ts → manager-Bw8b1wSD.d.ts} +136 -21
  19. package/dist/{manager-BwjyFjjz.d.cts → manager-DNGk1YkR.d.cts} +136 -21
  20. package/dist/{metadata-BiTMMvlY.d.ts → metadata-C__KMeuz.d.ts} +1 -1
  21. package/dist/{metadata-HCflXcsF.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 +17 -12
  25. package/dist/smart-account.d.ts +17 -12
  26. package/dist/smart-account.mjs +49 -44
  27. package/dist/smart-account.mjs.map +1 -1
  28. package/dist/wallet.cjs +54 -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 +54 -39
  33. package/dist/wallet.mjs.map +1 -1
  34. package/dist/widget.cjs +369 -170
  35. package/dist/widget.cjs.map +1 -1
  36. package/dist/widget.mjs +369 -169
  37. package/dist/widget.mjs.map +1 -1
  38. package/package.json +73 -5
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.10-staging.0";
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,50 +155,54 @@ 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);
183
- }
184
- if (retryCount >= maxRetries) {
185
- throw new RateLimitError(
186
- rateLimitInfo || { limit: 0, remaining: 0, reset: 0 },
187
- true
188
- );
180
+ notifyRateLimitCallbacks(rateLimitInfo, false, 0);
189
181
  }
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);
201
191
  }
202
- return response;
192
+ if (waitedMs + waitMs > RATE_LIMIT_WAIT_BUDGET_MS) {
193
+ throw new RateLimitError(info, false);
194
+ }
195
+ await sleep(waitMs);
196
+ waitedMs += waitMs;
197
+ retryCount++;
198
+ }
199
+ }
200
+ async function rateLimitedFetch(url, options = {}) {
201
+ const { skipRateLimit, ...fetchOptions } = options;
202
+ if (skipRateLimit) {
203
+ return fetch(url, fetchOptions);
203
204
  }
205
+ return withRateLimitRetry(() => fetch(url, fetchOptions));
204
206
  }
205
207
  var RateLimitError;
206
208
  var init_http = __esm({
@@ -208,9 +210,11 @@ var init_http = __esm({
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()
@@ -2006,6 +2010,20 @@ var init_eipWallets = __esm({
2006
2010
  "src/wallets/eipWallets.ts"() {
2007
2011
  "use strict";
2008
2012
  CHAIN_PARAMS = {
2013
+ 1: {
2014
+ chainIdHex: "0x1",
2015
+ chainName: "Ethereum",
2016
+ rpcUrls: ["https://eth.llamarpc.com"],
2017
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2018
+ blockExplorerUrls: ["https://etherscan.io"]
2019
+ },
2020
+ 137: {
2021
+ chainIdHex: "0x89",
2022
+ chainName: "Polygon",
2023
+ rpcUrls: ["https://polygon-rpc.com"],
2024
+ nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
2025
+ blockExplorerUrls: ["https://polygonscan.com"]
2026
+ },
2009
2027
  8453: {
2010
2028
  chainIdHex: "0x2105",
2011
2029
  chainName: "Base",
@@ -4079,6 +4097,19 @@ async function submitReceipt(intentId, txHash, sponsorshipRequestId, eoaAddress)
4079
4097
  const j = await r.json();
4080
4098
  return j.data;
4081
4099
  }
4100
+ async function submitStepReceipt(intentId, stepIndex, txHash) {
4101
+ const r = await rateLimitedFetch(
4102
+ `${apiBase()}/v1/route-intent/${intentId}/steps/${stepIndex}/receipt`,
4103
+ {
4104
+ method: "POST",
4105
+ headers: jsonHeaders({ "Idempotency-Key": txHash }),
4106
+ body: JSON.stringify({ txHash })
4107
+ }
4108
+ );
4109
+ await assertOK(r);
4110
+ const j = await r.json();
4111
+ return j.data;
4112
+ }
4082
4113
  async function getStatus(intentId) {
4083
4114
  const r = await rateLimitedFetch(
4084
4115
  `${apiBase()}/v1/route-intent/${intentId}/status`,
@@ -4088,7 +4119,18 @@ async function getStatus(intentId) {
4088
4119
  );
4089
4120
  await assertOK(r);
4090
4121
  const j = await r.json();
4091
- 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;
4092
4134
  }
4093
4135
  async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } = {}) {
4094
4136
  const t0 = Date.now();
@@ -4099,12 +4141,39 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
4099
4141
  await new Promise((r) => setTimeout(r, intervalMs));
4100
4142
  }
4101
4143
  }
4144
+ var STATUS_WIRE_TO_CAMEL;
4102
4145
  var init_routes = __esm({
4103
4146
  "src/core/routes.ts"() {
4104
4147
  "use strict";
4105
4148
  init_http();
4106
4149
  init_store();
4107
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
+ };
4108
4177
  }
4109
4178
  });
4110
4179
 
@@ -6167,6 +6236,258 @@ var init_TrustwareError = __esm({
6167
6236
  }
6168
6237
  });
6169
6238
 
6239
+ // src/core/tx.ts
6240
+ function backendChainId(chain, fallback) {
6241
+ const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6242
+ return String(preferred ?? fallback ?? "");
6243
+ }
6244
+ function sleep2(ms) {
6245
+ return new Promise((resolve) => setTimeout(resolve, ms));
6246
+ }
6247
+ async function sendEvmTx(w, tx) {
6248
+ if (w.type === "eip1193") {
6249
+ const from = await w.getAddress();
6250
+ const params = {
6251
+ from,
6252
+ to: tx.to,
6253
+ data: tx.data,
6254
+ value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
6255
+ };
6256
+ if (tx.chainId !== void 0) {
6257
+ params.chainId = `0x${tx.chainId.toString(16)}`;
6258
+ }
6259
+ const hash = await w.request({
6260
+ method: "eth_sendTransaction",
6261
+ params: [params]
6262
+ });
6263
+ return hash;
6264
+ }
6265
+ const response = await w.sendTransaction({
6266
+ to: tx.to,
6267
+ data: tx.data,
6268
+ value: tx.value,
6269
+ chainId: tx.chainId
6270
+ });
6271
+ return response.hash;
6272
+ }
6273
+ async function waitForTxConfirmation(chainId, txHash) {
6274
+ const timeoutMs = 12e4;
6275
+ const intervalMs = 2e3;
6276
+ const started = Date.now();
6277
+ while (Date.now() - started < timeoutMs) {
6278
+ const status = await getEVMTxStatus({ chainId, txHash });
6279
+ if (status.status === "success") return;
6280
+ if (status.status === "reverted") {
6281
+ throw new Error("Approval transaction reverted");
6282
+ }
6283
+ await sleep2(intervalMs);
6284
+ }
6285
+ throw new Error("Timed out waiting for approval confirmation");
6286
+ }
6287
+ function requiredApprovalAmount(planAmountWei, routeAmountWei) {
6288
+ if (planAmountWei >= UNLIMITED_APPROVAL_FLOOR && routeAmountWei !== void 0 && routeAmountWei > 0n) {
6289
+ return routeAmountWei;
6290
+ }
6291
+ return planAmountWei;
6292
+ }
6293
+ function approvalSatisfied(currentAllowance, requiredWei) {
6294
+ if (requiredWei === 0n) return currentAllowance === 0n;
6295
+ return currentAllowance >= requiredWei;
6296
+ }
6297
+ async function ensureApprovals(w, approvals, fallbackChainId, intentId, routeAmountWei) {
6298
+ if (!approvals || approvals.length === 0) return;
6299
+ const owner = await w.getAddress();
6300
+ for (const [stepIndex, approval] of approvals.entries()) {
6301
+ const spender = approval.spender;
6302
+ const tokenAddress = approval.tokenAddress;
6303
+ const amount = approval.amount;
6304
+ if (!spender || !tokenAddress || !amount) continue;
6305
+ const chainId = approval.chainId || String(fallbackChainId ?? "");
6306
+ if (!chainId) continue;
6307
+ const amountWei = requiredApprovalAmount(BigInt(amount), routeAmountWei);
6308
+ let currentAllowance = 0n;
6309
+ try {
6310
+ const { allowance } = await getEVMAllowance({
6311
+ chainId,
6312
+ tokenAddress,
6313
+ ownerAddress: owner,
6314
+ spenderAddress: spender
6315
+ });
6316
+ currentAllowance = BigInt(allowance || "0");
6317
+ } catch {
6318
+ }
6319
+ if (approvalSatisfied(currentAllowance, amountWei)) continue;
6320
+ const data = (0, import_viem2.encodeFunctionData)({
6321
+ abi: erc20ApproveAbi,
6322
+ functionName: "approve",
6323
+ args: [spender, amountWei]
6324
+ });
6325
+ const hash = await sendEvmTx(w, {
6326
+ to: tokenAddress,
6327
+ data,
6328
+ value: 0n,
6329
+ chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
6330
+ });
6331
+ if (intentId) {
6332
+ void submitStepReceipt(intentId, stepIndex, hash).catch(() => {
6333
+ });
6334
+ }
6335
+ await waitForTxConfirmation(chainId, hash);
6336
+ }
6337
+ }
6338
+ function isUserRejected(e2) {
6339
+ const code = e2?.code ?? e2?.data?.code;
6340
+ if (code === 4001) return true;
6341
+ const msg = String(e2?.message || e2)?.toLowerCase?.() || "";
6342
+ return msg.includes("user rejected") || msg.includes("user denied");
6343
+ }
6344
+ async function sendRouteTransaction(b, fallbackChainId, options) {
6345
+ const w = walletManager.wallet;
6346
+ if (!w) throw new Error("Trustware.wallet not configured");
6347
+ const txReq = b.txReq;
6348
+ if (isEvmTxRequest(txReq)) {
6349
+ if (w.ecosystem !== "evm") {
6350
+ throw new Error("An EVM wallet is required for this route");
6351
+ }
6352
+ const to = txReq.to ?? txReq.target;
6353
+ const data = txReq.data;
6354
+ const value = txReq.value ? BigInt(txReq.value) : 0n;
6355
+ const target = Number(txReq.chainId ?? fallbackChainId);
6356
+ let validatedSponsorship;
6357
+ if (b.sponsorship) {
6358
+ if ((0, import_viem2.keccak256)(data) === b.sponsorship.callDataHash) {
6359
+ validatedSponsorship = b.sponsorship;
6360
+ }
6361
+ }
6362
+ if (Number.isFinite(target)) {
6363
+ const current = await w.getChainId();
6364
+ if (current !== target) {
6365
+ try {
6366
+ await w.switchChain(target);
6367
+ } catch {
6368
+ }
6369
+ }
6370
+ }
6371
+ if (!validatedSponsorship && !options?.approvalsEnsured) {
6372
+ await ensureApprovals(
6373
+ w,
6374
+ b.route?.execution?.approvals,
6375
+ Number.isFinite(target) ? target : void 0,
6376
+ b.intentId,
6377
+ BigInt(b.route?.estimate?.fromAmount ?? "0")
6378
+ );
6379
+ }
6380
+ if (w.type === "eip1193") {
6381
+ const from = await w.getAddress();
6382
+ const hexValue = value ? `0x${value.toString(16)}` : "0x0";
6383
+ const params = {
6384
+ from,
6385
+ to,
6386
+ data,
6387
+ value: hexValue
6388
+ };
6389
+ if (Number.isFinite(target)) {
6390
+ params.chainId = `0x${target.toString(16)}`;
6391
+ }
6392
+ const hash = await w.request({
6393
+ method: "eth_sendTransaction",
6394
+ params: [params]
6395
+ });
6396
+ return hash;
6397
+ }
6398
+ const response = await w.sendTransaction({
6399
+ to,
6400
+ data,
6401
+ value,
6402
+ chainId: Number.isFinite(target) ? target : void 0,
6403
+ ...validatedSponsorship ? {
6404
+ paymasterAndData: validatedSponsorship.paymasterAndData
6405
+ } : {}
6406
+ });
6407
+ return response.hash;
6408
+ }
6409
+ if (isSerializedSolanaTxRequest(txReq)) {
6410
+ if (w.ecosystem !== "solana") {
6411
+ throw new Error("A Solana wallet is required for this route");
6412
+ }
6413
+ const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6414
+ const registry = getSharedRegistry2();
6415
+ await registry.ensureChainsLoaded();
6416
+ const chain = registry.chain(
6417
+ String(fallbackChainId ?? txReq.chainId ?? "")
6418
+ );
6419
+ return w.sendSerializedTransaction(
6420
+ txReq.data,
6421
+ backendChainId(chain, fallbackChainId ?? txReq.chainId)
6422
+ );
6423
+ }
6424
+ throw new Error("Invalid route transaction payload");
6425
+ }
6426
+ async function runTopUp(params) {
6427
+ const w = walletManager.wallet;
6428
+ if (!w) throw new Error("Trustware.wallet not configured");
6429
+ const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6430
+ const reg = getSharedRegistry2();
6431
+ await reg.ensureLoaded();
6432
+ const fromAddress = await w.getAddress();
6433
+ const currentChainRef = w.ecosystem === "evm" ? String(await w.getChainId()) : await w.getChainKey?.() ?? "solana-mainnet-beta";
6434
+ const originalChain = w.ecosystem === "evm" ? await w.getChainId() : void 0;
6435
+ const fromChain = params.fromChain ?? currentChainRef;
6436
+ const { TrustwareConfigStore: TrustwareConfigStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
6437
+ const cfg = TrustwareConfigStore2.get();
6438
+ const toChain = params.toChain ?? String(cfg.routes.toChain);
6439
+ const fromToken = reg.resolveToken(
6440
+ fromChain,
6441
+ params.fromToken ?? cfg.routes.fromToken ?? void 0
6442
+ ) ?? params.fromToken;
6443
+ const toToken = reg.resolveToken(
6444
+ toChain,
6445
+ params.toToken ?? cfg.routes.toToken ?? void 0
6446
+ ) ?? params.toToken;
6447
+ if (!fromToken || !toToken) {
6448
+ throw new Error("Unable to resolve route tokens");
6449
+ }
6450
+ try {
6451
+ const build = await buildRoute({
6452
+ fromChain,
6453
+ toChain,
6454
+ fromToken,
6455
+ toToken,
6456
+ fromAmount: String(params.fromAmount),
6457
+ fromAddress,
6458
+ toAddress: params.toAddress ?? cfg.routes.toAddress ?? cfg.routes.fromAddress ?? fromAddress,
6459
+ slippage: cfg.routes.defaultSlippage
6460
+ });
6461
+ const hash = await sendRouteTransaction(build, fromChain);
6462
+ await submitReceipt(build.intentId, hash);
6463
+ return await pollStatus(build.intentId);
6464
+ } catch (e2) {
6465
+ if (isUserRejected(e2)) throw new Error("Transaction cancelled by user");
6466
+ throw e2;
6467
+ } finally {
6468
+ try {
6469
+ if (w.ecosystem === "evm" && originalChain && originalChain !== Number(fromChain)) {
6470
+ await w.switchChain(originalChain);
6471
+ }
6472
+ } catch {
6473
+ }
6474
+ }
6475
+ }
6476
+ var import_viem2, erc20ApproveAbi, UNLIMITED_APPROVAL_FLOOR;
6477
+ var init_tx = __esm({
6478
+ "src/core/tx.ts"() {
6479
+ "use strict";
6480
+ init_wallets();
6481
+ init_routes();
6482
+ init_sdkRpc();
6483
+ import_viem2 = require("viem");
6484
+ erc20ApproveAbi = (0, import_viem2.parseAbi)([
6485
+ "function approve(address spender, uint256 amount) returns (bool)"
6486
+ ]);
6487
+ UNLIMITED_APPROVAL_FLOOR = 1n << 255n;
6488
+ }
6489
+ });
6490
+
6170
6491
  // src/types/routes.ts
6171
6492
  var init_routes2 = __esm({
6172
6493
  "src/types/routes.ts"() {
@@ -6325,9 +6646,6 @@ function resolveConfig(input) {
6325
6646
  const theme = input.theme ?? "system";
6326
6647
  const messages = deepMerge(DEFAULT_MESSAGES, input.messages);
6327
6648
  const retry = {
6328
- autoRetry: input.retry?.autoRetry ?? DEFAULT_RETRY_CONFIG.autoRetry,
6329
- maxRetries: input.retry?.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
6330
- baseDelayMs: input.retry?.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
6331
6649
  approachingThreshold: input.retry?.approachingThreshold ?? DEFAULT_RETRY_CONFIG.approachingThreshold,
6332
6650
  onRateLimitInfo: input.retry?.onRateLimitInfo,
6333
6651
  onRateLimited: input.retry?.onRateLimited,
@@ -6452,242 +6770,6 @@ var init_store = __esm({
6452
6770
  }
6453
6771
  });
6454
6772
 
6455
- // src/core/tx.ts
6456
- function backendChainId(chain, fallback) {
6457
- const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6458
- return String(preferred ?? fallback ?? "");
6459
- }
6460
- function sleep2(ms) {
6461
- return new Promise((resolve) => setTimeout(resolve, ms));
6462
- }
6463
- async function sendEvmTx(w, tx) {
6464
- if (w.type === "eip1193") {
6465
- const from = await w.getAddress();
6466
- const params = {
6467
- from,
6468
- to: tx.to,
6469
- data: tx.data,
6470
- value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
6471
- };
6472
- if (tx.chainId !== void 0) {
6473
- params.chainId = `0x${tx.chainId.toString(16)}`;
6474
- }
6475
- const hash = await w.request({
6476
- method: "eth_sendTransaction",
6477
- params: [params]
6478
- });
6479
- return hash;
6480
- }
6481
- const response = await w.sendTransaction({
6482
- to: tx.to,
6483
- data: tx.data,
6484
- value: tx.value,
6485
- chainId: tx.chainId
6486
- });
6487
- return response.hash;
6488
- }
6489
- async function waitForTxConfirmation(chainId, txHash) {
6490
- const timeoutMs = 12e4;
6491
- const intervalMs = 2e3;
6492
- const started = Date.now();
6493
- while (Date.now() - started < timeoutMs) {
6494
- const status = await getEVMTxStatus({ chainId, txHash });
6495
- if (status.status === "success") return;
6496
- if (status.status === "reverted") {
6497
- throw new Error("Approval transaction reverted");
6498
- }
6499
- await sleep2(intervalMs);
6500
- }
6501
- throw new Error("Timed out waiting for approval confirmation");
6502
- }
6503
- async function ensureApprovals(w, approvals, fallbackChainId) {
6504
- if (!approvals || approvals.length === 0) return;
6505
- const owner = await w.getAddress();
6506
- for (const approval of approvals) {
6507
- const spender = approval.spender;
6508
- const tokenAddress = approval.tokenAddress;
6509
- const amount = approval.amount;
6510
- if (!spender || !tokenAddress || !amount) continue;
6511
- const chainId = approval.chainId || String(fallbackChainId ?? "");
6512
- if (!chainId) continue;
6513
- const amountWei = BigInt(amount);
6514
- if (amountWei === 0n) continue;
6515
- let currentAllowance = 0n;
6516
- try {
6517
- const { allowance } = await getEVMAllowance({
6518
- chainId,
6519
- tokenAddress,
6520
- ownerAddress: owner,
6521
- spenderAddress: spender
6522
- });
6523
- currentAllowance = BigInt(allowance || "0");
6524
- } catch {
6525
- }
6526
- if (currentAllowance >= amountWei) continue;
6527
- const data = (0, import_viem2.encodeFunctionData)({
6528
- abi: erc20ApproveAbi,
6529
- functionName: "approve",
6530
- args: [spender, amountWei]
6531
- });
6532
- const hash = await sendEvmTx(w, {
6533
- to: tokenAddress,
6534
- data,
6535
- value: 0n,
6536
- chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
6537
- });
6538
- await waitForTxConfirmation(chainId, hash);
6539
- }
6540
- }
6541
- function isUserRejected(e2) {
6542
- const code = e2?.code ?? e2?.data?.code;
6543
- if (code === 4001) return true;
6544
- const msg = String(e2?.message || e2)?.toLowerCase?.() || "";
6545
- return msg.includes("user rejected") || msg.includes("user denied");
6546
- }
6547
- async function sendRouteTransaction(b, fallbackChainId) {
6548
- const w = walletManager.wallet;
6549
- if (!w) throw new Error("Trustware.wallet not configured");
6550
- const txReq = b.txReq;
6551
- if (isEvmTxRequest(txReq)) {
6552
- if (w.ecosystem !== "evm") {
6553
- throw new Error("An EVM wallet is required for this route");
6554
- }
6555
- const to = txReq.to ?? txReq.target;
6556
- const data = txReq.data;
6557
- const value = txReq.value ? BigInt(txReq.value) : 0n;
6558
- const target = Number(txReq.chainId ?? fallbackChainId);
6559
- let validatedSponsorship;
6560
- if (b.sponsorship) {
6561
- if ((0, import_viem2.keccak256)(data) === b.sponsorship.callDataHash) {
6562
- validatedSponsorship = b.sponsorship;
6563
- }
6564
- }
6565
- if (Number.isFinite(target)) {
6566
- const current = await w.getChainId();
6567
- if (current !== target) {
6568
- try {
6569
- await w.switchChain(target);
6570
- } catch {
6571
- }
6572
- }
6573
- }
6574
- if (!validatedSponsorship) {
6575
- await ensureApprovals(
6576
- w,
6577
- b.route?.execution?.approvals,
6578
- Number.isFinite(target) ? target : void 0
6579
- );
6580
- }
6581
- if (w.type === "eip1193") {
6582
- const from = await w.getAddress();
6583
- const hexValue = value ? `0x${value.toString(16)}` : "0x0";
6584
- const params = {
6585
- from,
6586
- to,
6587
- data,
6588
- value: hexValue
6589
- };
6590
- if (Number.isFinite(target)) {
6591
- params.chainId = `0x${target.toString(16)}`;
6592
- }
6593
- const hash = await w.request({
6594
- method: "eth_sendTransaction",
6595
- params: [params]
6596
- });
6597
- return hash;
6598
- }
6599
- const response = await w.sendTransaction({
6600
- to,
6601
- data,
6602
- value,
6603
- chainId: Number.isFinite(target) ? target : void 0,
6604
- ...validatedSponsorship ? {
6605
- paymasterAndData: validatedSponsorship.paymasterAndData
6606
- } : {}
6607
- });
6608
- return response.hash;
6609
- }
6610
- if (isSerializedSolanaTxRequest(txReq)) {
6611
- if (w.ecosystem !== "solana") {
6612
- throw new Error("A Solana wallet is required for this route");
6613
- }
6614
- const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6615
- const registry = getSharedRegistry2();
6616
- await registry.ensureChainsLoaded();
6617
- const chain = registry.chain(
6618
- String(fallbackChainId ?? txReq.chainId ?? "")
6619
- );
6620
- return w.sendSerializedTransaction(
6621
- txReq.data,
6622
- backendChainId(chain, fallbackChainId ?? txReq.chainId)
6623
- );
6624
- }
6625
- throw new Error("Invalid route transaction payload");
6626
- }
6627
- async function runTopUp(params) {
6628
- const w = walletManager.wallet;
6629
- if (!w) throw new Error("Trustware.wallet not configured");
6630
- const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6631
- const reg = getSharedRegistry2();
6632
- await reg.ensureLoaded();
6633
- const fromAddress = await w.getAddress();
6634
- const currentChainRef = w.ecosystem === "evm" ? String(await w.getChainId()) : await w.getChainKey?.() ?? "solana-mainnet-beta";
6635
- const originalChain = w.ecosystem === "evm" ? await w.getChainId() : void 0;
6636
- const fromChain = params.fromChain ?? currentChainRef;
6637
- const { TrustwareConfigStore: TrustwareConfigStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
6638
- const cfg = TrustwareConfigStore2.get();
6639
- const toChain = params.toChain ?? String(cfg.routes.toChain);
6640
- const fromToken = reg.resolveToken(
6641
- fromChain,
6642
- params.fromToken ?? cfg.routes.fromToken ?? void 0
6643
- ) ?? params.fromToken;
6644
- const toToken = reg.resolveToken(
6645
- toChain,
6646
- params.toToken ?? cfg.routes.toToken ?? void 0
6647
- ) ?? params.toToken;
6648
- if (!fromToken || !toToken) {
6649
- throw new Error("Unable to resolve route tokens");
6650
- }
6651
- try {
6652
- const build = await buildRoute({
6653
- fromChain,
6654
- toChain,
6655
- fromToken,
6656
- toToken,
6657
- fromAmount: String(params.fromAmount),
6658
- fromAddress,
6659
- toAddress: params.toAddress ?? cfg.routes.toAddress ?? cfg.routes.fromAddress ?? fromAddress,
6660
- slippage: cfg.routes.defaultSlippage
6661
- });
6662
- const hash = await sendRouteTransaction(build, fromChain);
6663
- await submitReceipt(build.intentId, hash);
6664
- return await pollStatus(build.intentId);
6665
- } catch (e2) {
6666
- if (isUserRejected(e2)) throw new Error("Transaction cancelled by user");
6667
- throw e2;
6668
- } finally {
6669
- try {
6670
- if (w.ecosystem === "evm" && originalChain && originalChain !== Number(fromChain)) {
6671
- await w.switchChain(originalChain);
6672
- }
6673
- } catch {
6674
- }
6675
- }
6676
- }
6677
- var import_viem2, erc20ApproveAbi;
6678
- var init_tx = __esm({
6679
- "src/core/tx.ts"() {
6680
- "use strict";
6681
- init_wallets();
6682
- init_routes();
6683
- init_sdkRpc();
6684
- import_viem2 = require("viem");
6685
- erc20ApproveAbi = (0, import_viem2.parseAbi)([
6686
- "function approve(address spender, uint256 amount) returns (bool)"
6687
- ]);
6688
- }
6689
- });
6690
-
6691
6773
  // src/core/index.ts
6692
6774
  var _lastValidatedKey, Trustware;
6693
6775
  var init_core = __esm({
@@ -6696,6 +6778,7 @@ var init_core = __esm({
6696
6778
  init_store();
6697
6779
  init_wallets();
6698
6780
  init_routes();
6781
+ init_routes();
6699
6782
  init_balances();
6700
6783
  init_tx();
6701
6784
  init_http();
@@ -6830,6 +6913,7 @@ var init_core = __esm({
6830
6913
  buildRoute,
6831
6914
  buildDepositAddress,
6832
6915
  submitReceipt,
6916
+ submitStepReceipt,
6833
6917
  getStatus,
6834
6918
  pollStatus,
6835
6919
  getBalances,
@@ -6849,7 +6933,8 @@ var init_core = __esm({
6849
6933
  // src/core.ts
6850
6934
  var core_exports = {};
6851
6935
  __export(core_exports, {
6852
- Trustware: () => Trustware
6936
+ Trustware: () => Trustware,
6937
+ assertValidPostHook: () => assertValidPostHook
6853
6938
  });
6854
6939
  module.exports = __toCommonJS(core_exports);
6855
6940
  var init_core2 = __esm({
@@ -6860,6 +6945,7 @@ var init_core2 = __esm({
6860
6945
  init_core2();
6861
6946
  // Annotate the CommonJS export names for ESM import in node:
6862
6947
  0 && (module.exports = {
6863
- Trustware
6948
+ Trustware,
6949
+ assertValidPostHook
6864
6950
  });
6865
6951
  //# sourceMappingURL=core.cjs.map