@trustware/sdk-staging 1.1.9-staging.7 → 1.1.11-staging.1

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.
@@ -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.9-staging.7";
33
+ var SDK_VERSION = "1.1.11-staging.1";
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.9-staging.7";
3
+ var SDK_VERSION = "1.1.11-staging.1";
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 { B as BuildRouteResult, b as Transaction, T as TrustwareConfigOptions, W as WalletInterFaceAPI, m as ResolvedTrustwareConfig, z as TrustwareTheme, O as WalletIdentity, a1 as walletManager, H as WalletAddressResolution, a4 as buildRoute, a5 as buildDepositAddress, a6 as submitReceipt, a7 as getStatus, a8 as pollStatus } from './manager-Dn4muk74.js';
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';
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
 
@@ -26,7 +26,19 @@ declare function getBalances(chainRef: string | number, address: string, opts?:
26
26
  declare function getBalancesByAddress(address: string, opts?: BalanceStreamOptions): Promise<WalletAddressBalanceWrapper[]>;
27
27
  declare function getBalancesByAddressStream(address: string, opts?: BalanceStreamOptions): AsyncGenerator<WalletAddressBalanceWrapper[], void, void>;
28
28
 
29
- declare function sendRouteTransaction(b: BuildRouteResult, fallbackChainId?: number | string): Promise<string>;
29
+ type SendRouteTransactionOptions = {
30
+ /**
31
+ * The caller has already run the plan's approval flow (checked allowances,
32
+ * sent any approves, waited for confirmation). Skips the internal
33
+ * ensureApprovals pass entirely — re-reading an allowance immediately
34
+ * after its approve confirms can return pre-block state from a different
35
+ * RPC node, which made the SDK prompt for the same approval twice
36
+ * (BVT-330). Exactly one path must own the approval decision per
37
+ * execution; this flag is how a caller claims that ownership.
38
+ */
39
+ approvalsEnsured?: boolean;
40
+ };
41
+ declare function sendRouteTransaction(b: BuildRouteResult, fallbackChainId?: number | string, options?: SendRouteTransactionOptions): Promise<string>;
30
42
  declare function runTopUp(params: {
31
43
  fromChain?: string;
32
44
  toChain?: string;
@@ -127,6 +139,7 @@ declare const Trustware: {
127
139
  buildRoute: typeof buildRoute;
128
140
  buildDepositAddress: typeof buildDepositAddress;
129
141
  submitReceipt: typeof submitReceipt;
142
+ submitStepReceipt: typeof submitStepReceipt;
130
143
  getStatus: typeof getStatus;
131
144
  pollStatus: typeof pollStatus;
132
145
  getBalances: typeof getBalances;
@@ -1,4 +1,4 @@
1
- import { B as BuildRouteResult, b as Transaction, T as TrustwareConfigOptions, W as WalletInterFaceAPI, m as ResolvedTrustwareConfig, z as TrustwareTheme, O as WalletIdentity, a1 as walletManager, H as WalletAddressResolution, a4 as buildRoute, a5 as buildDepositAddress, a6 as submitReceipt, a7 as getStatus, a8 as pollStatus } from './manager-DWFNyouP.cjs';
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';
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
 
@@ -26,7 +26,19 @@ declare function getBalances(chainRef: string | number, address: string, opts?:
26
26
  declare function getBalancesByAddress(address: string, opts?: BalanceStreamOptions): Promise<WalletAddressBalanceWrapper[]>;
27
27
  declare function getBalancesByAddressStream(address: string, opts?: BalanceStreamOptions): AsyncGenerator<WalletAddressBalanceWrapper[], void, void>;
28
28
 
29
- declare function sendRouteTransaction(b: BuildRouteResult, fallbackChainId?: number | string): Promise<string>;
29
+ type SendRouteTransactionOptions = {
30
+ /**
31
+ * The caller has already run the plan's approval flow (checked allowances,
32
+ * sent any approves, waited for confirmation). Skips the internal
33
+ * ensureApprovals pass entirely — re-reading an allowance immediately
34
+ * after its approve confirms can return pre-block state from a different
35
+ * RPC node, which made the SDK prompt for the same approval twice
36
+ * (BVT-330). Exactly one path must own the approval decision per
37
+ * execution; this flag is how a caller claims that ownership.
38
+ */
39
+ approvalsEnsured?: boolean;
40
+ };
41
+ declare function sendRouteTransaction(b: BuildRouteResult, fallbackChainId?: number | string, options?: SendRouteTransactionOptions): Promise<string>;
30
42
  declare function runTopUp(params: {
31
43
  fromChain?: string;
32
44
  toChain?: string;
@@ -127,6 +139,7 @@ declare const Trustware: {
127
139
  buildRoute: typeof buildRoute;
128
140
  buildDepositAddress: typeof buildDepositAddress;
129
141
  submitReceipt: typeof submitReceipt;
142
+ submitStepReceipt: typeof submitStepReceipt;
130
143
  getStatus: typeof getStatus;
131
144
  pollStatus: typeof pollStatus;
132
145
  getBalances: typeof getBalances;
package/dist/core.cjs CHANGED
@@ -75,7 +75,7 @@ var init_constants = __esm({
75
75
  "src/constants.ts"() {
76
76
  "use strict";
77
77
  SDK_NAME = "@trustware/sdk";
78
- SDK_VERSION = "1.1.9-staging.7";
78
+ SDK_VERSION = "1.1.11-staging.1";
79
79
  API_ROOT = "https://bv-staging-api.trustware.io";
80
80
  API_PREFIX = "/api";
81
81
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -2006,6 +2006,20 @@ var init_eipWallets = __esm({
2006
2006
  "src/wallets/eipWallets.ts"() {
2007
2007
  "use strict";
2008
2008
  CHAIN_PARAMS = {
2009
+ 1: {
2010
+ chainIdHex: "0x1",
2011
+ chainName: "Ethereum",
2012
+ rpcUrls: ["https://eth.llamarpc.com"],
2013
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2014
+ blockExplorerUrls: ["https://etherscan.io"]
2015
+ },
2016
+ 137: {
2017
+ chainIdHex: "0x89",
2018
+ chainName: "Polygon",
2019
+ rpcUrls: ["https://polygon-rpc.com"],
2020
+ nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
2021
+ blockExplorerUrls: ["https://polygonscan.com"]
2022
+ },
2009
2023
  8453: {
2010
2024
  chainIdHex: "0x2105",
2011
2025
  chainName: "Base",
@@ -2055,6 +2069,20 @@ async function requestSDKRPC(path, init = {}) {
2055
2069
  }
2056
2070
  );
2057
2071
  }
2072
+ async function getEVMAllowance(params) {
2073
+ const search = new URLSearchParams(params);
2074
+ return requestSDKRPC(
2075
+ `/evm/allowance?${search.toString()}`,
2076
+ { method: "GET" }
2077
+ );
2078
+ }
2079
+ async function getEVMTxStatus(params) {
2080
+ const search = new URLSearchParams(params);
2081
+ return requestSDKRPC(
2082
+ `/evm/tx-status?${search.toString()}`,
2083
+ { method: "GET" }
2084
+ );
2085
+ }
2058
2086
  async function sendSolanaSerialized(body) {
2059
2087
  return requestSDKRPC(
2060
2088
  "/solana/send-serialized",
@@ -3928,6 +3956,27 @@ var init_wallets = __esm({
3928
3956
  });
3929
3957
 
3930
3958
  // src/core/routes.ts
3959
+ function assertValidPostHook(hooks) {
3960
+ const postHook = hooks?.postHook;
3961
+ if (!postHook) return;
3962
+ if (!postHook.target?.trim()) {
3963
+ throw new Error("hooks.postHook.target is required.");
3964
+ }
3965
+ if (!postHook.callData?.trim()) {
3966
+ throw new Error("hooks.postHook.callData is required.");
3967
+ }
3968
+ if (postHook.fullAmount) {
3969
+ if (postHook.amountInputPos === void 0) {
3970
+ throw new Error(
3971
+ "hooks.postHook.amountInputPos is required when fullAmount is true."
3972
+ );
3973
+ }
3974
+ } else if (!postHook.fundAmount?.trim()) {
3975
+ throw new Error(
3976
+ "hooks.postHook.fundAmount is required unless fullAmount is set."
3977
+ );
3978
+ }
3979
+ }
3931
3980
  function isEvmTxRequest(txReq) {
3932
3981
  return Boolean(txReq?.data && (txReq.to || txReq.target));
3933
3982
  }
@@ -3946,6 +3995,7 @@ async function buildRoute(body, signal) {
3946
3995
  if (!addressValidation.isValid) {
3947
3996
  throw new Error(addressValidation.error || "Invalid route addresses.");
3948
3997
  }
3998
+ assertValidPostHook(body.hooks);
3949
3999
  const cfg = TrustwareConfigStore.get();
3950
4000
  const url = `${apiBase()}/v1/routes/route`;
3951
4001
  const payload = {
@@ -3984,6 +4034,7 @@ async function buildRoute(body, signal) {
3984
4034
  return { intentId, txReq, actions, finalExchangeRate, route, sponsorship };
3985
4035
  }
3986
4036
  async function buildDepositAddress(body, signal) {
4037
+ assertValidPostHook(body.hooks);
3987
4038
  const cfg = TrustwareConfigStore.get();
3988
4039
  const url = `${apiBase()}/v1/routes/deposit-address`;
3989
4040
  const payload = {
@@ -4042,6 +4093,19 @@ async function submitReceipt(intentId, txHash, sponsorshipRequestId, eoaAddress)
4042
4093
  const j = await r.json();
4043
4094
  return j.data;
4044
4095
  }
4096
+ async function submitStepReceipt(intentId, stepIndex, txHash) {
4097
+ const r = await rateLimitedFetch(
4098
+ `${apiBase()}/v1/route-intent/${intentId}/steps/${stepIndex}/receipt`,
4099
+ {
4100
+ method: "POST",
4101
+ headers: jsonHeaders({ "Idempotency-Key": txHash }),
4102
+ body: JSON.stringify({ txHash })
4103
+ }
4104
+ );
4105
+ await assertOK(r);
4106
+ const j = await r.json();
4107
+ return j.data;
4108
+ }
4045
4109
  async function getStatus(intentId) {
4046
4110
  const r = await rateLimitedFetch(
4047
4111
  `${apiBase()}/v1/route-intent/${intentId}/status`,
@@ -6130,6 +6194,258 @@ var init_TrustwareError = __esm({
6130
6194
  }
6131
6195
  });
6132
6196
 
6197
+ // src/core/tx.ts
6198
+ function backendChainId(chain, fallback) {
6199
+ const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6200
+ return String(preferred ?? fallback ?? "");
6201
+ }
6202
+ function sleep2(ms) {
6203
+ return new Promise((resolve) => setTimeout(resolve, ms));
6204
+ }
6205
+ async function sendEvmTx(w, tx) {
6206
+ if (w.type === "eip1193") {
6207
+ const from = await w.getAddress();
6208
+ const params = {
6209
+ from,
6210
+ to: tx.to,
6211
+ data: tx.data,
6212
+ value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
6213
+ };
6214
+ if (tx.chainId !== void 0) {
6215
+ params.chainId = `0x${tx.chainId.toString(16)}`;
6216
+ }
6217
+ const hash = await w.request({
6218
+ method: "eth_sendTransaction",
6219
+ params: [params]
6220
+ });
6221
+ return hash;
6222
+ }
6223
+ const response = await w.sendTransaction({
6224
+ to: tx.to,
6225
+ data: tx.data,
6226
+ value: tx.value,
6227
+ chainId: tx.chainId
6228
+ });
6229
+ return response.hash;
6230
+ }
6231
+ async function waitForTxConfirmation(chainId, txHash) {
6232
+ const timeoutMs = 12e4;
6233
+ const intervalMs = 2e3;
6234
+ const started = Date.now();
6235
+ while (Date.now() - started < timeoutMs) {
6236
+ const status = await getEVMTxStatus({ chainId, txHash });
6237
+ if (status.status === "success") return;
6238
+ if (status.status === "reverted") {
6239
+ throw new Error("Approval transaction reverted");
6240
+ }
6241
+ await sleep2(intervalMs);
6242
+ }
6243
+ throw new Error("Timed out waiting for approval confirmation");
6244
+ }
6245
+ function requiredApprovalAmount(planAmountWei, routeAmountWei) {
6246
+ if (planAmountWei >= UNLIMITED_APPROVAL_FLOOR && routeAmountWei !== void 0 && routeAmountWei > 0n) {
6247
+ return routeAmountWei;
6248
+ }
6249
+ return planAmountWei;
6250
+ }
6251
+ function approvalSatisfied(currentAllowance, requiredWei) {
6252
+ if (requiredWei === 0n) return currentAllowance === 0n;
6253
+ return currentAllowance >= requiredWei;
6254
+ }
6255
+ async function ensureApprovals(w, approvals, fallbackChainId, intentId, routeAmountWei) {
6256
+ if (!approvals || approvals.length === 0) return;
6257
+ const owner = await w.getAddress();
6258
+ for (const [stepIndex, approval] of approvals.entries()) {
6259
+ const spender = approval.spender;
6260
+ const tokenAddress = approval.tokenAddress;
6261
+ const amount = approval.amount;
6262
+ if (!spender || !tokenAddress || !amount) continue;
6263
+ const chainId = approval.chainId || String(fallbackChainId ?? "");
6264
+ if (!chainId) continue;
6265
+ const amountWei = requiredApprovalAmount(BigInt(amount), routeAmountWei);
6266
+ let currentAllowance = 0n;
6267
+ try {
6268
+ const { allowance } = await getEVMAllowance({
6269
+ chainId,
6270
+ tokenAddress,
6271
+ ownerAddress: owner,
6272
+ spenderAddress: spender
6273
+ });
6274
+ currentAllowance = BigInt(allowance || "0");
6275
+ } catch {
6276
+ }
6277
+ if (approvalSatisfied(currentAllowance, amountWei)) continue;
6278
+ const data = (0, import_viem2.encodeFunctionData)({
6279
+ abi: erc20ApproveAbi,
6280
+ functionName: "approve",
6281
+ args: [spender, amountWei]
6282
+ });
6283
+ const hash = await sendEvmTx(w, {
6284
+ to: tokenAddress,
6285
+ data,
6286
+ value: 0n,
6287
+ chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
6288
+ });
6289
+ if (intentId) {
6290
+ void submitStepReceipt(intentId, stepIndex, hash).catch(() => {
6291
+ });
6292
+ }
6293
+ await waitForTxConfirmation(chainId, hash);
6294
+ }
6295
+ }
6296
+ function isUserRejected(e2) {
6297
+ const code = e2?.code ?? e2?.data?.code;
6298
+ if (code === 4001) return true;
6299
+ const msg = String(e2?.message || e2)?.toLowerCase?.() || "";
6300
+ return msg.includes("user rejected") || msg.includes("user denied");
6301
+ }
6302
+ async function sendRouteTransaction(b, fallbackChainId, options) {
6303
+ const w = walletManager.wallet;
6304
+ if (!w) throw new Error("Trustware.wallet not configured");
6305
+ const txReq = b.txReq;
6306
+ if (isEvmTxRequest(txReq)) {
6307
+ if (w.ecosystem !== "evm") {
6308
+ throw new Error("An EVM wallet is required for this route");
6309
+ }
6310
+ const to = txReq.to ?? txReq.target;
6311
+ const data = txReq.data;
6312
+ const value = txReq.value ? BigInt(txReq.value) : 0n;
6313
+ const target = Number(txReq.chainId ?? fallbackChainId);
6314
+ let validatedSponsorship;
6315
+ if (b.sponsorship) {
6316
+ if ((0, import_viem2.keccak256)(data) === b.sponsorship.callDataHash) {
6317
+ validatedSponsorship = b.sponsorship;
6318
+ }
6319
+ }
6320
+ if (Number.isFinite(target)) {
6321
+ const current = await w.getChainId();
6322
+ if (current !== target) {
6323
+ try {
6324
+ await w.switchChain(target);
6325
+ } catch {
6326
+ }
6327
+ }
6328
+ }
6329
+ if (!validatedSponsorship && !options?.approvalsEnsured) {
6330
+ await ensureApprovals(
6331
+ w,
6332
+ b.route?.execution?.approvals,
6333
+ Number.isFinite(target) ? target : void 0,
6334
+ b.intentId,
6335
+ BigInt(b.route?.estimate?.fromAmount ?? "0")
6336
+ );
6337
+ }
6338
+ if (w.type === "eip1193") {
6339
+ const from = await w.getAddress();
6340
+ const hexValue = value ? `0x${value.toString(16)}` : "0x0";
6341
+ const params = {
6342
+ from,
6343
+ to,
6344
+ data,
6345
+ value: hexValue
6346
+ };
6347
+ if (Number.isFinite(target)) {
6348
+ params.chainId = `0x${target.toString(16)}`;
6349
+ }
6350
+ const hash = await w.request({
6351
+ method: "eth_sendTransaction",
6352
+ params: [params]
6353
+ });
6354
+ return hash;
6355
+ }
6356
+ const response = await w.sendTransaction({
6357
+ to,
6358
+ data,
6359
+ value,
6360
+ chainId: Number.isFinite(target) ? target : void 0,
6361
+ ...validatedSponsorship ? {
6362
+ paymasterAndData: validatedSponsorship.paymasterAndData
6363
+ } : {}
6364
+ });
6365
+ return response.hash;
6366
+ }
6367
+ if (isSerializedSolanaTxRequest(txReq)) {
6368
+ if (w.ecosystem !== "solana") {
6369
+ throw new Error("A Solana wallet is required for this route");
6370
+ }
6371
+ const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6372
+ const registry = getSharedRegistry2();
6373
+ await registry.ensureChainsLoaded();
6374
+ const chain = registry.chain(
6375
+ String(fallbackChainId ?? txReq.chainId ?? "")
6376
+ );
6377
+ return w.sendSerializedTransaction(
6378
+ txReq.data,
6379
+ backendChainId(chain, fallbackChainId ?? txReq.chainId)
6380
+ );
6381
+ }
6382
+ throw new Error("Invalid route transaction payload");
6383
+ }
6384
+ async function runTopUp(params) {
6385
+ const w = walletManager.wallet;
6386
+ if (!w) throw new Error("Trustware.wallet not configured");
6387
+ const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6388
+ const reg = getSharedRegistry2();
6389
+ await reg.ensureLoaded();
6390
+ const fromAddress = await w.getAddress();
6391
+ const currentChainRef = w.ecosystem === "evm" ? String(await w.getChainId()) : await w.getChainKey?.() ?? "solana-mainnet-beta";
6392
+ const originalChain = w.ecosystem === "evm" ? await w.getChainId() : void 0;
6393
+ const fromChain = params.fromChain ?? currentChainRef;
6394
+ const { TrustwareConfigStore: TrustwareConfigStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
6395
+ const cfg = TrustwareConfigStore2.get();
6396
+ const toChain = params.toChain ?? String(cfg.routes.toChain);
6397
+ const fromToken = reg.resolveToken(
6398
+ fromChain,
6399
+ params.fromToken ?? cfg.routes.fromToken ?? void 0
6400
+ ) ?? params.fromToken;
6401
+ const toToken = reg.resolveToken(
6402
+ toChain,
6403
+ params.toToken ?? cfg.routes.toToken ?? void 0
6404
+ ) ?? params.toToken;
6405
+ if (!fromToken || !toToken) {
6406
+ throw new Error("Unable to resolve route tokens");
6407
+ }
6408
+ try {
6409
+ const build = await buildRoute({
6410
+ fromChain,
6411
+ toChain,
6412
+ fromToken,
6413
+ toToken,
6414
+ fromAmount: String(params.fromAmount),
6415
+ fromAddress,
6416
+ toAddress: params.toAddress ?? cfg.routes.toAddress ?? cfg.routes.fromAddress ?? fromAddress,
6417
+ slippage: cfg.routes.defaultSlippage
6418
+ });
6419
+ const hash = await sendRouteTransaction(build, fromChain);
6420
+ await submitReceipt(build.intentId, hash);
6421
+ return await pollStatus(build.intentId);
6422
+ } catch (e2) {
6423
+ if (isUserRejected(e2)) throw new Error("Transaction cancelled by user");
6424
+ throw e2;
6425
+ } finally {
6426
+ try {
6427
+ if (w.ecosystem === "evm" && originalChain && originalChain !== Number(fromChain)) {
6428
+ await w.switchChain(originalChain);
6429
+ }
6430
+ } catch {
6431
+ }
6432
+ }
6433
+ }
6434
+ var import_viem2, erc20ApproveAbi, UNLIMITED_APPROVAL_FLOOR;
6435
+ var init_tx = __esm({
6436
+ "src/core/tx.ts"() {
6437
+ "use strict";
6438
+ init_wallets();
6439
+ init_routes();
6440
+ init_sdkRpc();
6441
+ import_viem2 = require("viem");
6442
+ erc20ApproveAbi = (0, import_viem2.parseAbi)([
6443
+ "function approve(address spender, uint256 amount) returns (bool)"
6444
+ ]);
6445
+ UNLIMITED_APPROVAL_FLOOR = 1n << 255n;
6446
+ }
6447
+ });
6448
+
6133
6449
  // src/types/routes.ts
6134
6450
  var init_routes2 = __esm({
6135
6451
  "src/types/routes.ts"() {
@@ -6415,150 +6731,6 @@ var init_store = __esm({
6415
6731
  }
6416
6732
  });
6417
6733
 
6418
- // src/core/tx.ts
6419
- function backendChainId(chain, fallback) {
6420
- const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6421
- return String(preferred ?? fallback ?? "");
6422
- }
6423
- function isUserRejected(e2) {
6424
- const code = e2?.code ?? e2?.data?.code;
6425
- if (code === 4001) return true;
6426
- const msg = String(e2?.message || e2)?.toLowerCase?.() || "";
6427
- return msg.includes("user rejected") || msg.includes("user denied");
6428
- }
6429
- async function sendRouteTransaction(b, fallbackChainId) {
6430
- const w = walletManager.wallet;
6431
- if (!w) throw new Error("Trustware.wallet not configured");
6432
- const txReq = b.txReq;
6433
- if (isEvmTxRequest(txReq)) {
6434
- if (w.ecosystem !== "evm") {
6435
- throw new Error("An EVM wallet is required for this route");
6436
- }
6437
- const to = txReq.to ?? txReq.target;
6438
- const data = txReq.data;
6439
- const value = txReq.value ? BigInt(txReq.value) : 0n;
6440
- const target = Number(txReq.chainId ?? fallbackChainId);
6441
- let validatedSponsorship;
6442
- if (b.sponsorship) {
6443
- if ((0, import_viem2.keccak256)(data) === b.sponsorship.callDataHash) {
6444
- validatedSponsorship = b.sponsorship;
6445
- }
6446
- }
6447
- if (Number.isFinite(target)) {
6448
- const current = await w.getChainId();
6449
- if (current !== target) {
6450
- try {
6451
- await w.switchChain(target);
6452
- } catch {
6453
- }
6454
- }
6455
- }
6456
- if (w.type === "eip1193") {
6457
- const from = await w.getAddress();
6458
- const hexValue = value ? `0x${value.toString(16)}` : "0x0";
6459
- const params = {
6460
- from,
6461
- to,
6462
- data,
6463
- value: hexValue
6464
- };
6465
- if (Number.isFinite(target)) {
6466
- params.chainId = `0x${target.toString(16)}`;
6467
- }
6468
- const hash = await w.request({
6469
- method: "eth_sendTransaction",
6470
- params: [params]
6471
- });
6472
- return hash;
6473
- }
6474
- const response = await w.sendTransaction({
6475
- to,
6476
- data,
6477
- value,
6478
- chainId: Number.isFinite(target) ? target : void 0,
6479
- ...validatedSponsorship ? {
6480
- paymasterAndData: validatedSponsorship.paymasterAndData
6481
- } : {}
6482
- });
6483
- return response.hash;
6484
- }
6485
- if (isSerializedSolanaTxRequest(txReq)) {
6486
- if (w.ecosystem !== "solana") {
6487
- throw new Error("A Solana wallet is required for this route");
6488
- }
6489
- const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6490
- const registry = getSharedRegistry2();
6491
- await registry.ensureChainsLoaded();
6492
- const chain = registry.chain(
6493
- String(fallbackChainId ?? txReq.chainId ?? "")
6494
- );
6495
- return w.sendSerializedTransaction(
6496
- txReq.data,
6497
- backendChainId(chain, fallbackChainId ?? txReq.chainId)
6498
- );
6499
- }
6500
- throw new Error("Invalid route transaction payload");
6501
- }
6502
- async function runTopUp(params) {
6503
- const w = walletManager.wallet;
6504
- if (!w) throw new Error("Trustware.wallet not configured");
6505
- const { getSharedRegistry: getSharedRegistry2 } = await Promise.resolve().then(() => (init_registryClient(), registryClient_exports));
6506
- const reg = getSharedRegistry2();
6507
- await reg.ensureLoaded();
6508
- const fromAddress = await w.getAddress();
6509
- const currentChainRef = w.ecosystem === "evm" ? String(await w.getChainId()) : await w.getChainKey?.() ?? "solana-mainnet-beta";
6510
- const originalChain = w.ecosystem === "evm" ? await w.getChainId() : void 0;
6511
- const fromChain = params.fromChain ?? currentChainRef;
6512
- const { TrustwareConfigStore: TrustwareConfigStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
6513
- const cfg = TrustwareConfigStore2.get();
6514
- const toChain = params.toChain ?? String(cfg.routes.toChain);
6515
- const fromToken = reg.resolveToken(
6516
- fromChain,
6517
- params.fromToken ?? cfg.routes.fromToken ?? void 0
6518
- ) ?? params.fromToken;
6519
- const toToken = reg.resolveToken(
6520
- toChain,
6521
- params.toToken ?? cfg.routes.toToken ?? void 0
6522
- ) ?? params.toToken;
6523
- if (!fromToken || !toToken) {
6524
- throw new Error("Unable to resolve route tokens");
6525
- }
6526
- try {
6527
- const build = await buildRoute({
6528
- fromChain,
6529
- toChain,
6530
- fromToken,
6531
- toToken,
6532
- fromAmount: String(params.fromAmount),
6533
- fromAddress,
6534
- toAddress: params.toAddress ?? cfg.routes.toAddress ?? cfg.routes.fromAddress ?? fromAddress,
6535
- slippage: cfg.routes.defaultSlippage
6536
- });
6537
- const hash = await sendRouteTransaction(build, fromChain);
6538
- await submitReceipt(build.intentId, hash);
6539
- return await pollStatus(build.intentId);
6540
- } catch (e2) {
6541
- if (isUserRejected(e2)) throw new Error("Transaction cancelled by user");
6542
- throw e2;
6543
- } finally {
6544
- try {
6545
- if (w.ecosystem === "evm" && originalChain && originalChain !== Number(fromChain)) {
6546
- await w.switchChain(originalChain);
6547
- }
6548
- } catch {
6549
- }
6550
- }
6551
- }
6552
- var import_viem2;
6553
- var init_tx = __esm({
6554
- "src/core/tx.ts"() {
6555
- "use strict";
6556
- init_wallets();
6557
- init_routes();
6558
- import_viem2 = require("viem");
6559
- }
6560
- });
6561
-
6562
6734
  // src/core/index.ts
6563
6735
  var _lastValidatedKey, Trustware;
6564
6736
  var init_core = __esm({
@@ -6701,6 +6873,7 @@ var init_core = __esm({
6701
6873
  buildRoute,
6702
6874
  buildDepositAddress,
6703
6875
  submitReceipt,
6876
+ submitStepReceipt,
6704
6877
  getStatus,
6705
6878
  pollStatus,
6706
6879
  getBalances,