@trustware/sdk-staging 1.1.9-staging.7 → 1.1.10-staging.0

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.
package/dist/core.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { T as Trustware, a as TrustwareCore } from './core-gNyi5xsp.cjs';
2
- import './manager-DWFNyouP.cjs';
1
+ export { T as Trustware, a as TrustwareCore } from './core-B7Ez-5-r.cjs';
2
+ import './manager-BwjyFjjz.cjs';
3
3
  import './blockchain-BxAFzp0s.cjs';
4
4
  import './types-DX3HtFcn.cjs';
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { T as Trustware, a as TrustwareCore } from './core-DzqVEWwP.js';
2
- import './manager-Dn4muk74.js';
1
+ export { T as Trustware, a as TrustwareCore } from './core-BPLiD1UG.js';
2
+ import './manager-B6NNV-E_.js';
3
3
  import './blockchain-BxAFzp0s.js';
4
4
  import './types-BJY9r-mz.js';
package/dist/core.mjs CHANGED
@@ -53,7 +53,7 @@ var init_constants = __esm({
53
53
  "src/constants.ts"() {
54
54
  "use strict";
55
55
  SDK_NAME = "@trustware/sdk";
56
- SDK_VERSION = "1.1.9-staging.7";
56
+ SDK_VERSION = "1.1.10-staging.0";
57
57
  API_ROOT = "https://bv-staging-api.trustware.io";
58
58
  API_PREFIX = "/api";
59
59
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -2033,6 +2033,20 @@ async function requestSDKRPC(path, init = {}) {
2033
2033
  }
2034
2034
  );
2035
2035
  }
2036
+ async function getEVMAllowance(params) {
2037
+ const search = new URLSearchParams(params);
2038
+ return requestSDKRPC(
2039
+ `/evm/allowance?${search.toString()}`,
2040
+ { method: "GET" }
2041
+ );
2042
+ }
2043
+ async function getEVMTxStatus(params) {
2044
+ const search = new URLSearchParams(params);
2045
+ return requestSDKRPC(
2046
+ `/evm/tx-status?${search.toString()}`,
2047
+ { method: "GET" }
2048
+ );
2049
+ }
2036
2050
  async function sendSolanaSerialized(body) {
2037
2051
  return requestSDKRPC(
2038
2052
  "/solana/send-serialized",
@@ -3906,6 +3920,27 @@ var init_wallets = __esm({
3906
3920
  });
3907
3921
 
3908
3922
  // src/core/routes.ts
3923
+ function assertValidPostHook(hooks) {
3924
+ const postHook = hooks?.postHook;
3925
+ if (!postHook) return;
3926
+ if (!postHook.target?.trim()) {
3927
+ throw new Error("hooks.postHook.target is required.");
3928
+ }
3929
+ if (!postHook.callData?.trim()) {
3930
+ throw new Error("hooks.postHook.callData is required.");
3931
+ }
3932
+ if (postHook.fullAmount) {
3933
+ if (postHook.amountInputPos === void 0) {
3934
+ throw new Error(
3935
+ "hooks.postHook.amountInputPos is required when fullAmount is true."
3936
+ );
3937
+ }
3938
+ } else if (!postHook.fundAmount?.trim()) {
3939
+ throw new Error(
3940
+ "hooks.postHook.fundAmount is required unless fullAmount is set."
3941
+ );
3942
+ }
3943
+ }
3909
3944
  function isEvmTxRequest(txReq) {
3910
3945
  return Boolean(txReq?.data && (txReq.to || txReq.target));
3911
3946
  }
@@ -3924,6 +3959,7 @@ async function buildRoute(body, signal) {
3924
3959
  if (!addressValidation.isValid) {
3925
3960
  throw new Error(addressValidation.error || "Invalid route addresses.");
3926
3961
  }
3962
+ assertValidPostHook(body.hooks);
3927
3963
  const cfg = TrustwareConfigStore.get();
3928
3964
  const url = `${apiBase()}/v1/routes/route`;
3929
3965
  const payload = {
@@ -3962,6 +3998,7 @@ async function buildRoute(body, signal) {
3962
3998
  return { intentId, txReq, actions, finalExchangeRate, route, sponsorship };
3963
3999
  }
3964
4000
  async function buildDepositAddress(body, signal) {
4001
+ assertValidPostHook(body.hooks);
3965
4002
  const cfg = TrustwareConfigStore.get();
3966
4003
  const url = `${apiBase()}/v1/routes/deposit-address`;
3967
4004
  const payload = {
@@ -6394,11 +6431,92 @@ var init_store = __esm({
6394
6431
  });
6395
6432
 
6396
6433
  // src/core/tx.ts
6397
- import { keccak256 } from "viem";
6434
+ import { keccak256, encodeFunctionData, parseAbi } from "viem";
6398
6435
  function backendChainId(chain, fallback) {
6399
6436
  const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
6400
6437
  return String(preferred ?? fallback ?? "");
6401
6438
  }
6439
+ function sleep2(ms) {
6440
+ return new Promise((resolve) => setTimeout(resolve, ms));
6441
+ }
6442
+ async function sendEvmTx(w, tx) {
6443
+ if (w.type === "eip1193") {
6444
+ const from = await w.getAddress();
6445
+ const params = {
6446
+ from,
6447
+ to: tx.to,
6448
+ data: tx.data,
6449
+ value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
6450
+ };
6451
+ if (tx.chainId !== void 0) {
6452
+ params.chainId = `0x${tx.chainId.toString(16)}`;
6453
+ }
6454
+ const hash = await w.request({
6455
+ method: "eth_sendTransaction",
6456
+ params: [params]
6457
+ });
6458
+ return hash;
6459
+ }
6460
+ const response = await w.sendTransaction({
6461
+ to: tx.to,
6462
+ data: tx.data,
6463
+ value: tx.value,
6464
+ chainId: tx.chainId
6465
+ });
6466
+ return response.hash;
6467
+ }
6468
+ async function waitForTxConfirmation(chainId, txHash) {
6469
+ const timeoutMs = 12e4;
6470
+ const intervalMs = 2e3;
6471
+ const started = Date.now();
6472
+ while (Date.now() - started < timeoutMs) {
6473
+ const status = await getEVMTxStatus({ chainId, txHash });
6474
+ if (status.status === "success") return;
6475
+ if (status.status === "reverted") {
6476
+ throw new Error("Approval transaction reverted");
6477
+ }
6478
+ await sleep2(intervalMs);
6479
+ }
6480
+ throw new Error("Timed out waiting for approval confirmation");
6481
+ }
6482
+ async function ensureApprovals(w, approvals, fallbackChainId) {
6483
+ if (!approvals || approvals.length === 0) return;
6484
+ const owner = await w.getAddress();
6485
+ for (const approval of approvals) {
6486
+ const spender = approval.spender;
6487
+ const tokenAddress = approval.tokenAddress;
6488
+ const amount = approval.amount;
6489
+ if (!spender || !tokenAddress || !amount) continue;
6490
+ const chainId = approval.chainId || String(fallbackChainId ?? "");
6491
+ if (!chainId) continue;
6492
+ const amountWei = BigInt(amount);
6493
+ if (amountWei === 0n) continue;
6494
+ let currentAllowance = 0n;
6495
+ try {
6496
+ const { allowance } = await getEVMAllowance({
6497
+ chainId,
6498
+ tokenAddress,
6499
+ ownerAddress: owner,
6500
+ spenderAddress: spender
6501
+ });
6502
+ currentAllowance = BigInt(allowance || "0");
6503
+ } catch {
6504
+ }
6505
+ if (currentAllowance >= amountWei) continue;
6506
+ const data = encodeFunctionData({
6507
+ abi: erc20ApproveAbi,
6508
+ functionName: "approve",
6509
+ args: [spender, amountWei]
6510
+ });
6511
+ const hash = await sendEvmTx(w, {
6512
+ to: tokenAddress,
6513
+ data,
6514
+ value: 0n,
6515
+ chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
6516
+ });
6517
+ await waitForTxConfirmation(chainId, hash);
6518
+ }
6519
+ }
6402
6520
  function isUserRejected(e2) {
6403
6521
  const code = e2?.code ?? e2?.data?.code;
6404
6522
  if (code === 4001) return true;
@@ -6432,6 +6550,13 @@ async function sendRouteTransaction(b, fallbackChainId) {
6432
6550
  }
6433
6551
  }
6434
6552
  }
6553
+ if (!validatedSponsorship) {
6554
+ await ensureApprovals(
6555
+ w,
6556
+ b.route?.execution?.approvals,
6557
+ Number.isFinite(target) ? target : void 0
6558
+ );
6559
+ }
6435
6560
  if (w.type === "eip1193") {
6436
6561
  const from = await w.getAddress();
6437
6562
  const hexValue = value ? `0x${value.toString(16)}` : "0x0";
@@ -6528,11 +6653,16 @@ async function runTopUp(params) {
6528
6653
  }
6529
6654
  }
6530
6655
  }
6656
+ var erc20ApproveAbi;
6531
6657
  var init_tx = __esm({
6532
6658
  "src/core/tx.ts"() {
6533
6659
  "use strict";
6534
6660
  init_wallets();
6535
6661
  init_routes();
6662
+ init_sdkRpc();
6663
+ erc20ApproveAbi = parseAbi([
6664
+ "function approve(address spender, uint256 amount) returns (bool)"
6665
+ ]);
6536
6666
  }
6537
6667
  });
6538
6668