@trustware/sdk-staging 1.1.9-staging.5 → 1.1.9-staging.7

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-Dy_rZl5y.cjs';
2
- import './manager-B5aklGtm.cjs';
1
+ export { T as Trustware, a as TrustwareCore } from './core-gNyi5xsp.cjs';
2
+ import './manager-DWFNyouP.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-CwT8Wd1x.js';
2
- import './manager-xFiq0SHr.js';
1
+ export { T as Trustware, a as TrustwareCore } from './core-DzqVEWwP.js';
2
+ import './manager-Dn4muk74.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.5";
56
+ SDK_VERSION = "1.1.9-staging.7";
57
57
  API_ROOT = "https://bv-staging-api.trustware.io";
58
58
  API_PREFIX = "/api";
59
59
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -262,7 +262,9 @@ var init_chains = __esm({
262
262
  btc: "bitcoin",
263
263
  bitcoin: "bitcoin",
264
264
  sei: "cosmos",
265
- "pacific-1": "cosmos"
265
+ "pacific-1": "cosmos",
266
+ nibiru: "cosmos",
267
+ "cataclysm-1": "cosmos"
266
268
  };
267
269
  }
268
270
  });
@@ -1459,16 +1461,23 @@ function validateEvmAddress(address) {
1459
1461
  }
1460
1462
  return { isValid: true };
1461
1463
  }
1462
- function validateSeiAddress(address) {
1464
+ function resolveCosmosBech32Prefix(chain) {
1465
+ const chainDef = typeof chain === "object" && chain ? chain : void 0;
1466
+ const identifier = chainDef?.networkIdentifier ?? chainDef?.chainId ?? chainDef?.id ?? (typeof chain === "string" ? chain : void 0);
1467
+ const normalized = String(identifier ?? "").trim().toLowerCase();
1468
+ return COSMOS_BECH32_PREFIX_BY_CHAIN_ID[normalized] ?? "sei";
1469
+ }
1470
+ function validateCosmosAddress(address, chain) {
1463
1471
  const trimmed = address.trim();
1464
- if (isEvmAddress(trimmed)) {
1472
+ const prefix = resolveCosmosBech32Prefix(chain);
1473
+ if (prefix === "sei" && isEvmAddress(trimmed)) {
1465
1474
  return { isValid: true };
1466
1475
  }
1467
- const result = validateBech32LikeAddress(trimmed, "sei");
1476
+ const result = validateBech32LikeAddress(trimmed, prefix);
1468
1477
  if (result.isValid) return result;
1469
1478
  return {
1470
1479
  isValid: false,
1471
- error: "SEI addresses must be 0x-prefixed EVM or sei1 bech32 strings."
1480
+ error: prefix === "sei" ? "SEI addresses must be 0x-prefixed EVM or sei1 bech32 strings." : `Address must be a valid ${prefix}1 bech32 string.`
1472
1481
  };
1473
1482
  }
1474
1483
  function validateSolanaAddress(address) {
@@ -1518,15 +1527,12 @@ function validateAddressForChain(address, chain) {
1518
1527
  case "bitcoin":
1519
1528
  return validateBtcAddress(trimmed);
1520
1529
  case "cosmos":
1521
- if (chainDef?.networkIdentifier?.toLowerCase() === "sei") {
1522
- return validateSeiAddress(trimmed);
1523
- }
1524
- return validateBech32LikeAddress(trimmed, "sei");
1530
+ return validateCosmosAddress(trimmed, chainDef ?? chain);
1525
1531
  default:
1526
1532
  return { isValid: false, error: "Unsupported or unknown chain type." };
1527
1533
  }
1528
1534
  }
1529
- function validateAddressForRouteChain(address, chainType) {
1535
+ function validateAddressForRouteChain(address, chainType, chainRef) {
1530
1536
  switch (normalizeChainType(chainType)) {
1531
1537
  case "evm":
1532
1538
  return validateEvmAddress(address);
@@ -1535,7 +1541,7 @@ function validateAddressForRouteChain(address, chainType) {
1535
1541
  case "bitcoin":
1536
1542
  return validateBtcAddress(address);
1537
1543
  case "cosmos":
1538
- return validateSeiAddress(address);
1544
+ return validateCosmosAddress(address, chainRef ?? chainType);
1539
1545
  default:
1540
1546
  return { isValid: false, error: "Unsupported chain type." };
1541
1547
  }
@@ -1557,14 +1563,18 @@ function validateRouteAddresses(params) {
1557
1563
  const normalizedDirection = params.direction?.trim().toLowerCase();
1558
1564
  const isDepositFlow = normalizedDirection === "deposit" || (toType === "evm" || toType === "cosmos") && (fromType === "bitcoin" || fromType === "solana");
1559
1565
  if (isDepositFlow) {
1560
- const fromResult2 = validateAddressForRouteChain(fromAddress, fromType);
1566
+ const fromResult2 = validateAddressForRouteChain(
1567
+ fromAddress,
1568
+ fromType,
1569
+ params.fromChain
1570
+ );
1561
1571
  if (!fromResult2.isValid) {
1562
1572
  return {
1563
1573
  isValid: false,
1564
1574
  error: `From address: ${fromResult2.error ?? "Invalid address."}`
1565
1575
  };
1566
1576
  }
1567
- const toResult2 = toType === "cosmos" ? validateSeiAddress(toAddress) : validateEvmAddress(toAddress);
1577
+ const toResult2 = toType === "cosmos" ? validateCosmosAddress(toAddress, params.toChain) : validateEvmAddress(toAddress);
1568
1578
  if (!toResult2.isValid) {
1569
1579
  return {
1570
1580
  isValid: false,
@@ -1589,14 +1599,22 @@ function validateRouteAddresses(params) {
1589
1599
  }
1590
1600
  return { isValid: true };
1591
1601
  }
1592
- const fromResult = validateAddressForRouteChain(fromAddress, fromType);
1602
+ const fromResult = validateAddressForRouteChain(
1603
+ fromAddress,
1604
+ fromType,
1605
+ params.fromChain
1606
+ );
1593
1607
  if (!fromResult.isValid) {
1594
1608
  return {
1595
1609
  isValid: false,
1596
1610
  error: `From address: ${fromResult.error ?? "Invalid address."}`
1597
1611
  };
1598
1612
  }
1599
- const toResult = validateAddressForRouteChain(toAddress, toType);
1613
+ const toResult = validateAddressForRouteChain(
1614
+ toAddress,
1615
+ toType,
1616
+ params.toChain
1617
+ );
1600
1618
  if (!toResult.isValid) {
1601
1619
  return {
1602
1620
  isValid: false,
@@ -1605,13 +1623,19 @@ function validateRouteAddresses(params) {
1605
1623
  }
1606
1624
  return { isValid: true };
1607
1625
  }
1608
- var BECH32_CHARSET;
1626
+ var BECH32_CHARSET, COSMOS_BECH32_PREFIX_BY_CHAIN_ID;
1609
1627
  var init_address = __esm({
1610
1628
  "src/validation/address.ts"() {
1611
1629
  "use strict";
1612
1630
  init_index_node4();
1613
1631
  init_chains();
1614
1632
  BECH32_CHARSET = /^[023456789acdefghjklmnpqrstuvwxyz]+$/i;
1633
+ COSMOS_BECH32_PREFIX_BY_CHAIN_ID = {
1634
+ "pacific-1": "sei",
1635
+ sei: "sei",
1636
+ "cataclysm-1": "nibi",
1637
+ nibiru: "nibi"
1638
+ };
1615
1639
  }
1616
1640
  });
1617
1641
 
@@ -2448,7 +2472,7 @@ var init_walletconnect = __esm({
2448
2472
  solanaMainnet = {
2449
2473
  id: 900,
2450
2474
  chainNamespace: "solana",
2451
- caipNetworkId: "solana:5eykt4UsFv8P8NJdTREpY1vzqAQ3H1FQ",
2475
+ caipNetworkId: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
2452
2476
  name: "Solana Mainnet",
2453
2477
  nativeCurrency: {
2454
2478
  name: "Solana",
@@ -3327,8 +3351,62 @@ function getChainMeta(chainId) {
3327
3351
  rpcUrls: chain.rpcUrls.default.http
3328
3352
  };
3329
3353
  }
3330
- async function buildWalletConnectAPI(walletCfg) {
3354
+ function extractSolanaAddress(connector) {
3355
+ const caipAccount = connector.provider.session?.namespaces?.solana?.accounts?.[0];
3356
+ if (!caipAccount) return null;
3357
+ return caipAccount.split(":")[2] ?? null;
3358
+ }
3359
+ function buildWalletConnectSolanaProvider(connector) {
3360
+ return {
3361
+ get publicKey() {
3362
+ const address = extractSolanaAddress(connector);
3363
+ return address ? { toString: () => address } : void 0;
3364
+ },
3365
+ async connect() {
3366
+ const address = extractSolanaAddress(connector);
3367
+ if (!address) {
3368
+ throw new Error(
3369
+ "This wallet did not approve a Solana account over WalletConnect."
3370
+ );
3371
+ }
3372
+ return { publicKey: { toString: () => address } };
3373
+ },
3374
+ async disconnect() {
3375
+ },
3376
+ async signTransaction(transaction) {
3377
+ const tx = transaction;
3378
+ const rawBytes = "version" in tx ? tx.serialize() : tx.serialize({
3379
+ requireAllSignatures: false,
3380
+ verifySignatures: false
3381
+ });
3382
+ const result = await connector.provider.request(
3383
+ {
3384
+ method: "solana_signTransaction",
3385
+ params: { transaction: encodeBase64(rawBytes) }
3386
+ },
3387
+ solanaMainnet.caipNetworkId
3388
+ );
3389
+ if (!result.transaction) {
3390
+ throw new Error(
3391
+ "WalletConnect wallet did not return a signed Solana transaction."
3392
+ );
3393
+ }
3394
+ const signedBytes = decodeBase64(result.transaction);
3395
+ return { serialize: () => signedBytes };
3396
+ },
3397
+ on() {
3398
+ },
3399
+ off() {
3400
+ },
3401
+ removeListener() {
3402
+ }
3403
+ };
3404
+ }
3405
+ async function buildWalletConnectAPI(walletCfg, ecosystem = "evm") {
3331
3406
  const connector = await getUniversalConnector(walletCfg);
3407
+ if (ecosystem === "solana") {
3408
+ return toSolanaWalletInterface(buildWalletConnectSolanaProvider(connector));
3409
+ }
3332
3410
  const provider = connector.provider;
3333
3411
  const api = {
3334
3412
  ecosystem: "evm",
@@ -3537,44 +3615,39 @@ var init_manager = __esm({
3537
3615
  this.emit();
3538
3616
  }
3539
3617
  }
3540
- async connectWalletConnect(walletCfg) {
3541
- if (this._status === "connected" && this._connectedVia === "walletconnect" && this._wallet) {
3618
+ async connectWalletConnect(walletCfg, ecosystem = "evm") {
3619
+ if (this._status === "connected" && this._connectedVia === "walletconnect" && this._wallet && this._wallet.ecosystem === ecosystem) {
3542
3620
  this.emit();
3543
3621
  return { error: null, api: this._wallet };
3544
3622
  }
3623
+ if (this._connectedVia === "walletconnect" && this._wallet) {
3624
+ await this._wallet.disconnect?.().catch(() => {
3625
+ });
3626
+ resetUniversalConnector();
3627
+ }
3545
3628
  this._status = "connecting";
3546
3629
  this.clearConnectedState();
3547
3630
  this.emit();
3548
3631
  try {
3549
3632
  const connector = await getUniversalConnector(walletCfg);
3550
3633
  await connector.connect();
3551
- const api = await buildWalletConnectAPI(walletCfg);
3634
+ const api = await buildWalletConnectAPI(walletCfg, ecosystem);
3635
+ try {
3636
+ await api.getAddress();
3637
+ } catch {
3638
+ await api.disconnect?.().catch(() => {
3639
+ });
3640
+ resetUniversalConnector();
3641
+ throw new Error(
3642
+ `This wallet did not approve a${ecosystem === "evm" ? "n" : ""} ${ecosystem === "evm" ? "EVM" : "Solana"} account over WalletConnect.`
3643
+ );
3644
+ }
3552
3645
  this._wallet = api;
3553
3646
  this._connectedVia = "walletconnect";
3554
3647
  this._connectedWalletId = "walletconnect";
3555
- const provider = connector.provider;
3556
- this._providerCleanup = bindWalletConnectEvents(provider, {
3557
- onAccountsChanged: (accounts) => {
3558
- if (accounts.length === 0) {
3559
- this.fullReset();
3560
- this.triggerExternalDisconnect();
3561
- this.emit();
3562
- return;
3563
- }
3564
- void this.syncIdentityFromWallet("walletconnect");
3565
- this.emit();
3566
- },
3567
- onChainChanged: () => {
3568
- void this.syncIdentityFromWallet("walletconnect");
3569
- this.emit();
3570
- },
3571
- onDisconnect: () => {
3572
- this.fullReset();
3573
- resetUniversalConnector();
3574
- this.triggerExternalDisconnect();
3575
- this.emit();
3576
- }
3577
- });
3648
+ this._providerCleanup = this.bindWalletConnectProviderEvents(
3649
+ connector.provider
3650
+ );
3578
3651
  await this.syncIdentityFromWallet("walletconnect");
3579
3652
  this._status = "connected";
3580
3653
  this._error = null;
@@ -3589,6 +3662,100 @@ var init_manager = __esm({
3589
3662
  return { error: message, api: null };
3590
3663
  }
3591
3664
  }
3665
+ bindWalletConnectProviderEvents(provider) {
3666
+ return bindWalletConnectEvents(provider, {
3667
+ onAccountsChanged: (accounts) => {
3668
+ if (accounts.length === 0) {
3669
+ this.fullReset();
3670
+ this.triggerExternalDisconnect();
3671
+ this.emit();
3672
+ return;
3673
+ }
3674
+ void this.syncIdentityFromWallet("walletconnect");
3675
+ this.emit();
3676
+ },
3677
+ onChainChanged: () => {
3678
+ void this.syncIdentityFromWallet("walletconnect");
3679
+ this.emit();
3680
+ },
3681
+ onDisconnect: () => {
3682
+ this.fullReset();
3683
+ resetUniversalConnector();
3684
+ this.triggerExternalDisconnect();
3685
+ this.emit();
3686
+ }
3687
+ });
3688
+ }
3689
+ // WalletConnect's own SignClient auto-restores the last persisted session
3690
+ // from storage on every init — including after a fresh page load — but
3691
+ // that restoration happens silently inside the library. Nothing calls back
3692
+ // into our code for it. On mobile, backgrounding the tab to approve in a
3693
+ // wallet app can cause the OS to reload the page before the original
3694
+ // connect() promise ever resolves, so the connect flow that triggered the
3695
+ // approval never gets to record it as "connected" here — even though
3696
+ // WalletConnect itself already has a live, approved session sitting in
3697
+ // storage. Call this on mount to pick that back up.
3698
+ async restoreWalletConnectSession(walletCfg) {
3699
+ if (this._status === "connected" && this._connectedVia === "walletconnect") {
3700
+ return this._wallet?.ecosystem === "solana" ? "solana" : "evm";
3701
+ }
3702
+ if (typeof window === "undefined") return null;
3703
+ try {
3704
+ if (!Object.keys(window.localStorage).some((key) => key.startsWith("wc@2"))) {
3705
+ return null;
3706
+ }
3707
+ } catch {
3708
+ }
3709
+ let connector;
3710
+ try {
3711
+ connector = await getUniversalConnector(walletCfg);
3712
+ } catch (e2) {
3713
+ console.warn(
3714
+ "[Trustware SDK] Failed to restore WalletConnect session:",
3715
+ e2
3716
+ );
3717
+ return null;
3718
+ }
3719
+ const session = connector.provider.session;
3720
+ if (!session) return null;
3721
+ const ecosystem = session.namespaces?.solana?.accounts?.length ? "solana" : session.namespaces?.eip155?.accounts?.length ? "evm" : null;
3722
+ if (!ecosystem) return null;
3723
+ try {
3724
+ const api = await buildWalletConnectAPI(walletCfg, ecosystem);
3725
+ this._wallet = api;
3726
+ this._connectedVia = "walletconnect";
3727
+ this._connectedWalletId = "walletconnect";
3728
+ this._providerCleanup = this.bindWalletConnectProviderEvents(
3729
+ connector.provider
3730
+ );
3731
+ await this.syncIdentityFromWallet("walletconnect");
3732
+ this._status = "connected";
3733
+ this._error = null;
3734
+ this.emit();
3735
+ return ecosystem;
3736
+ } catch {
3737
+ return null;
3738
+ }
3739
+ }
3740
+ // Forcibly abandon an in-progress connect() call the caller has decided is
3741
+ // stuck (e.g. the UI's own connect timeout elapsed with no response).
3742
+ // There's no clean way to cancel a pending WalletConnect pairing proposal
3743
+ // from this side, so this tears down the whole connector — the next
3744
+ // connect attempt starts against a brand new SignClient/pairing instead of
3745
+ // racing the abandoned one, which would otherwise risk reproducing the
3746
+ // "No matching key. proposal" class of error a real retry needs to avoid.
3747
+ cancelWalletConnectAttempt() {
3748
+ if (this._connectedVia === "walletconnect" && this._status === "connected") {
3749
+ return;
3750
+ }
3751
+ resetUniversalConnector();
3752
+ if (this._status === "connecting") {
3753
+ this.clearConnectedState();
3754
+ this._status = "idle";
3755
+ this._error = null;
3756
+ this.emit();
3757
+ }
3758
+ }
3592
3759
  async disconnect(wagmi) {
3593
3760
  if (wagmi && this._connectedVia === "extension") {
3594
3761
  await wagmi.disconnect().catch(() => {
@@ -3836,7 +4003,7 @@ async function buildDepositAddress(body, signal) {
3836
4003
  route
3837
4004
  };
3838
4005
  }
3839
- async function submitReceipt(intentId, txHash, sponsorshipRequestId) {
4006
+ async function submitReceipt(intentId, txHash, sponsorshipRequestId, eoaAddress) {
3840
4007
  const r = await rateLimitedFetch(
3841
4008
  `${apiBase()}/v1/route-intent/${intentId}/receipt`,
3842
4009
  {
@@ -3844,7 +4011,8 @@ async function submitReceipt(intentId, txHash, sponsorshipRequestId) {
3844
4011
  headers: jsonHeaders({ "Idempotency-Key": txHash }),
3845
4012
  body: JSON.stringify({
3846
4013
  txHash,
3847
- ...sponsorshipRequestId ? { sponsorshipRequestId } : {}
4014
+ ...sponsorshipRequestId ? { sponsorshipRequestId } : {},
4015
+ ...eoaAddress ? { eoaAddress } : {}
3848
4016
  })
3849
4017
  }
3850
4018
  );
@@ -3966,7 +4134,9 @@ var init_chainHelpers = __esm({
3966
4134
  btc: "bitcoin",
3967
4135
  bitcoin: "bitcoin",
3968
4136
  sei: "cosmos",
3969
- "pacific-1": "cosmos"
4137
+ "pacific-1": "cosmos",
4138
+ nibiru: "cosmos",
4139
+ "cataclysm-1": "cosmos"
3970
4140
  };
3971
4141
  SEI_EVM_CHAIN_ID = "1329";
3972
4142
  SEI_COSMOS_CHAIN_ID = "pacific-1";
@@ -4121,7 +4291,8 @@ function filterSupportedChains(chains) {
4121
4291
  }
4122
4292
  if (chainType === "cosmos") {
4123
4293
  const seiKey = canonicalSeiChainKey(chain.chainId ?? chain.id);
4124
- if (seiKey !== "sei" && seiKey !== "pacific-1") {
4294
+ const isNibiru = normalizeChainKey2(chain.chainId ?? chain.id) === NIBIRU_COSMOS_CHAIN_ID;
4295
+ if (seiKey !== "sei" && !isNibiru) {
4125
4296
  return false;
4126
4297
  }
4127
4298
  }
@@ -4221,7 +4392,7 @@ function useChains() {
4221
4392
  error
4222
4393
  };
4223
4394
  }
4224
- var POPULAR_CHAINS_BY_TVL, POPULAR_LIMIT;
4395
+ var POPULAR_CHAINS_BY_TVL, POPULAR_LIMIT, NIBIRU_COSMOS_CHAIN_ID;
4225
4396
  var init_useChains = __esm({
4226
4397
  "src/core/useChains.ts"() {
4227
4398
  "use strict";
@@ -4231,6 +4402,7 @@ var init_useChains = __esm({
4231
4402
  init_popularChains();
4232
4403
  POPULAR_CHAINS_BY_TVL = popularChains_default.byTvl;
4233
4404
  POPULAR_LIMIT = popularChains_default.popularLimit;
4405
+ NIBIRU_COSMOS_CHAIN_ID = "cataclysm-1";
4234
4406
  }
4235
4407
  });
4236
4408
 
@@ -6015,46 +6187,80 @@ function normalizeSlippage(v) {
6015
6187
  if (n > 5) return 5;
6016
6188
  return n;
6017
6189
  }
6190
+ function warnDeprecatedSwapModeFlag() {
6191
+ if (hasWarnedDeprecatedSwapModeFlag) return;
6192
+ hasWarnedDeprecatedSwapModeFlag = true;
6193
+ console.warn(
6194
+ '[Trustware SDK] `features.swapMode` is deprecated \u2014 use `mode: "swap"` on the top-level config instead.'
6195
+ );
6196
+ }
6197
+ function resolveMode(input) {
6198
+ if (input.mode === "swap") return "swap";
6199
+ if (input.mode === "deposit") return "deposit";
6200
+ if (input.features?.swapMode) {
6201
+ warnDeprecatedSwapModeFlag();
6202
+ return "swap";
6203
+ }
6204
+ return "deposit";
6205
+ }
6018
6206
  function resolveConfig(input) {
6019
6207
  if (!input?.apiKey) {
6020
- throw new Error("TrustwareConfig: 'apiKey' is required.");
6208
+ throw new TrustwareError({
6209
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6210
+ message: "TrustwareConfig: 'apiKey' is required.",
6211
+ userMessage: "Missing required API key configuration."
6212
+ });
6021
6213
  }
6022
- if (!input.routes?.toChain || !input.routes?.toToken) {
6023
- throw new Error(
6024
- "TrustwareConfig: 'routes.toChain' and 'routes.toToken' are required."
6025
- );
6214
+ const mode = resolveMode(input);
6215
+ if (mode === "deposit" && (!input.routes?.toChain || !input.routes?.toToken)) {
6216
+ throw new TrustwareError({
6217
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6218
+ message: "TrustwareConfig: 'routes.toChain' and 'routes.toToken' are required in deposit mode.",
6219
+ userMessage: "Missing required destination chain/token configuration."
6220
+ });
6026
6221
  }
6027
- const toChain = input.routes.toChain;
6028
- if (input.routes.toAddress) {
6222
+ const toChain = input.routes?.toChain;
6223
+ if (input.routes?.toAddress && toChain) {
6029
6224
  const result = validateAddressForChain(input.routes.toAddress, toChain);
6030
6225
  if (!result.isValid) {
6031
6226
  console.error(`[Trustware SDK] Invalid toAddress: ${result.error}`);
6032
- throw new Error(`Invalid toAddress: ${result.error}`);
6227
+ throw new TrustwareError({
6228
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6229
+ message: `Invalid toAddress: ${result.error}`,
6230
+ userMessage: "The configured destination address is invalid."
6231
+ });
6033
6232
  }
6034
6233
  }
6035
- if (input.routes.fromAddress) {
6036
- const result = validateAddressForChain(
6037
- input.routes.fromAddress,
6038
- input.routes.fromChain ?? toChain
6039
- );
6040
- if (!result.isValid) {
6041
- console.error(`[Trustware SDK] Invalid fromAddress: ${result.error}`);
6042
- throw new Error(`Invalid fromAddress: ${result.error}`);
6234
+ if (input.routes?.fromAddress) {
6235
+ const fromChain = input.routes.fromChain ?? toChain;
6236
+ if (fromChain) {
6237
+ const result = validateAddressForChain(
6238
+ input.routes.fromAddress,
6239
+ fromChain
6240
+ );
6241
+ if (!result.isValid) {
6242
+ console.error(`[Trustware SDK] Invalid fromAddress: ${result.error}`);
6243
+ throw new TrustwareError({
6244
+ code: "INVALID_CONFIG" /* INVALID_CONFIG */,
6245
+ message: `Invalid fromAddress: ${result.error}`,
6246
+ userMessage: "The configured source address is invalid."
6247
+ });
6248
+ }
6043
6249
  }
6044
6250
  }
6045
6251
  const autoDetectProvider = typeof input.autoDetectProvider === "boolean" ? input.autoDetectProvider : DEFAULT_AUTO_DETECT_PROVIDER;
6046
6252
  const routes = {
6047
- toChain: input.routes.toChain,
6048
- toToken: input.routes.toToken,
6049
- fromToken: input.routes.fromToken,
6050
- fromAddress: input.routes.fromAddress,
6051
- fromChain: input.routes.fromChain,
6052
- toAddress: input.routes.toAddress,
6253
+ toChain: input.routes?.toChain ?? "",
6254
+ toToken: input.routes?.toToken ?? "",
6255
+ fromToken: input.routes?.fromToken,
6256
+ fromAddress: input.routes?.fromAddress,
6257
+ fromChain: input.routes?.fromChain,
6258
+ toAddress: input.routes?.toAddress,
6053
6259
  defaultSlippage: normalizeSlippage(
6054
- input.routes.defaultSlippage ?? DEFAULT_SLIPPAGE
6260
+ input.routes?.defaultSlippage ?? DEFAULT_SLIPPAGE
6055
6261
  ),
6056
6262
  options: {
6057
- ...input.routes.options
6263
+ ...input.routes?.options
6058
6264
  }
6059
6265
  };
6060
6266
  const theme = input.theme ?? "system";
@@ -6073,13 +6279,16 @@ function resolveConfig(input) {
6073
6279
  tokensPagination: input.features?.tokensPagination ?? DEFAULT_FEATURE_FLAGS.tokensPagination,
6074
6280
  balanceStreaming: input.features?.balanceStreaming ?? DEFAULT_FEATURE_FLAGS.balanceStreaming,
6075
6281
  shouldAllowGA4: input.features?.shouldAllowGA4 ?? DEFAULT_FEATURE_FLAGS.shouldAllowGA4,
6076
- swapMode: input.features?.swapMode ?? DEFAULT_FEATURE_FLAGS.swapMode,
6282
+ // Always mirrors the canonical `mode`, however the caller set it (new `mode` field
6283
+ // or the deprecated `features.swapMode` flag).
6284
+ swapMode: mode === "swap",
6077
6285
  swapDefaultDestToken: input.features?.swapDefaultDestToken ?? DEFAULT_FEATURE_FLAGS.swapDefaultDestToken,
6078
6286
  swapLockDestToken: input.features?.swapLockDestToken ?? DEFAULT_FEATURE_FLAGS.swapLockDestToken,
6079
6287
  swapAllowedDestTokens: input.features?.swapAllowedDestTokens ?? DEFAULT_FEATURE_FLAGS.swapAllowedDestTokens
6080
6288
  };
6081
6289
  return {
6082
6290
  apiKey: input.apiKey,
6291
+ mode,
6083
6292
  routes,
6084
6293
  autoDetectProvider,
6085
6294
  theme,
@@ -6092,12 +6301,15 @@ function resolveConfig(input) {
6092
6301
  onEvent: input.onEvent
6093
6302
  };
6094
6303
  }
6304
+ var hasWarnedDeprecatedSwapModeFlag;
6095
6305
  var init_merge = __esm({
6096
6306
  "src/config/merge.ts"() {
6097
6307
  "use strict";
6098
6308
  init_defaults();
6099
6309
  init_config();
6100
6310
  init_index();
6311
+ init_TrustwareError();
6312
+ hasWarnedDeprecatedSwapModeFlag = false;
6101
6313
  }
6102
6314
  });
6103
6315