@0xsquid/react-hooks 8.11.1-beta-danal.1 → 8.12.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.
Files changed (52) hide show
  1. package/dist/core/canton/cantonConnector.d.ts +5 -2
  2. package/dist/core/canton/errors.d.ts +4 -0
  3. package/dist/core/canton/loopCantonConnector.d.ts +38 -0
  4. package/dist/core/client/index.d.ts +0 -1
  5. package/dist/core/constants.d.ts +0 -2
  6. package/dist/core/types/canton.d.ts +37 -3
  7. package/dist/core/types/wallet.d.ts +1 -8
  8. package/dist/hooks/chains/useSquidChains.d.ts +0 -1
  9. package/dist/hooks/store/useDepositAddressStore.d.ts +0 -6
  10. package/dist/hooks/swap/useDepositAddress.d.ts +0 -2
  11. package/dist/hooks/tokens/useSquidTokens.d.ts +0 -1
  12. package/dist/hooks/wallet/useMultiChainWallet.d.ts +0 -38
  13. package/dist/hooks/wallet/useWallet.d.ts +0 -42
  14. package/dist/{index-D6rznmR_.js → index-C3owE9lb.js} +739 -512
  15. package/dist/index-C3owE9lb.js.map +1 -0
  16. package/dist/{index-BT6G_mgr.js → index-CJVX-7hj.js} +738 -515
  17. package/dist/index-CJVX-7hj.js.map +1 -0
  18. package/dist/{index.es-Dl19u5sy.js → index.es-09IsADsA.js} +2 -2
  19. package/dist/{index.es-Dl19u5sy.js.map → index.es-09IsADsA.js.map} +1 -1
  20. package/dist/{index.es-BZb8tg2z.js → index.es-CTKuR0LC.js} +2 -2
  21. package/dist/{index.es-BZb8tg2z.js.map → index.es-CTKuR0LC.js.map} +1 -1
  22. package/dist/index.esm.js +1 -1
  23. package/dist/index.js +1 -5
  24. package/dist/index.js.map +1 -1
  25. package/dist/{secretService-Dvc9Dg4U.js → secretService--tJFCkzT.js} +2 -2
  26. package/dist/{secretService-Dvc9Dg4U.js.map → secretService--tJFCkzT.js.map} +1 -1
  27. package/dist/{secretService-TP5V9Jwg.js → secretService-GHdReJBs.js} +2 -2
  28. package/dist/{secretService-TP5V9Jwg.js.map → secretService-GHdReJBs.js.map} +1 -1
  29. package/dist/server.esm.js +0 -6
  30. package/dist/server.esm.js.map +1 -1
  31. package/dist/server.js +0 -6
  32. package/dist/server.js.map +1 -1
  33. package/dist/services/external/rpcService.d.ts +2 -4
  34. package/dist/services/index.d.ts +0 -1
  35. package/dist/services/internal/assetsService.d.ts +1 -1
  36. package/dist/services/internal/cantonService.d.ts +2 -0
  37. package/dist/services/internal/cantonTransferService.d.ts +3 -3
  38. package/dist/services/internal/estimateService.d.ts +1 -1
  39. package/dist/services/internal/transactionService.d.ts +0 -8
  40. package/dist/{stellarService.client-c48cnGgL.js → stellarService.client-DAxgO3m3.js} +2 -2
  41. package/dist/{stellarService.client-c48cnGgL.js.map → stellarService.client-DAxgO3m3.js.map} +1 -1
  42. package/dist/{stellarService.client-WTkVJJhn.js → stellarService.client-DvA-2pXq.js} +2 -2
  43. package/dist/{stellarService.client-WTkVJJhn.js.map → stellarService.client-DvA-2pXq.js.map} +1 -1
  44. package/dist/tests/loopSdkContract.test.d.ts +1 -0
  45. package/dist/tests/useAutoConnectCanton.test.d.ts +1 -0
  46. package/dist/tests/useCantonRestoration.test.d.ts +1 -0
  47. package/package.json +3 -2
  48. package/dist/core/types/danal.d.ts +0 -1
  49. package/dist/index-BT6G_mgr.js.map +0 -1
  50. package/dist/index-D6rznmR_.js.map +0 -1
  51. package/dist/services/internal/danalService.d.ts +0 -8
  52. /package/dist/tests/{danalService.test.d.ts → loopCantonConnector.test.d.ts} +0 -0
@@ -59,7 +59,6 @@ const suiZeroAddress = "0x0000000000000000000000000000000000000000";
59
59
  const xrplZeroAddress = "rrrrrrrrrrrrrrrrrrrrrhoLvTp";
60
60
  const stellarZeroAddress = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
61
61
  const cantonZeroAddress = "none::12200000000000000000000000000000000000000000000000000000000000000000";
62
- const danalZeroAddress = "PCI00000000000000000000000000000000000000000000000000";
63
62
  const chainTypeToZeroAddressMap = {
64
63
  [ChainType.EVM]: zeroAddress$1,
65
64
  [ChainType.COSMOS]: cosmosZeroAddress,
@@ -69,7 +68,6 @@ const chainTypeToZeroAddressMap = {
69
68
  [ChainType.XRPL]: xrplZeroAddress,
70
69
  [ChainType.STELLAR]: stellarZeroAddress,
71
70
  [ChainType.CANTON]: cantonZeroAddress,
72
- [ChainType.DANAL]: danalZeroAddress,
73
71
  };
74
72
  const nativeEvmTokenAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
75
73
  const nativeCosmosTokenAddress = "uosmo";
@@ -79,7 +77,6 @@ const nativeSuiTokenAddress = "0x00000000000000000000000000000000000000000000000
79
77
  const nativeXrplTokenAddress = "xrp";
80
78
  const nativeStellarTokenAddress = "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
81
79
  const nativeCantonTokenAddress = "DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc";
82
- const nativeDanalTokenAddress = "pci";
83
80
  // by setting slippage to undefined, it's set to "auto"
84
81
  const defaultSlippage = undefined;
85
82
  const destinationAddressResetValue = "null";
@@ -145,7 +142,6 @@ const CHAIN_IDS = {
145
142
  STELLAR: "stellar-mainnet",
146
143
  STELLAR_TESTNET: "stellar-testnet",
147
144
  CANTON: "canton",
148
- DANAL_TESTNET: "danal-testnet",
149
145
  };
150
146
  const chainTypeToDefaultChainIdMap = {
151
147
  [ChainType.EVM]: CHAIN_IDS.ETHEREUM,
@@ -156,7 +152,6 @@ const chainTypeToDefaultChainIdMap = {
156
152
  [ChainType.XRPL]: CHAIN_IDS.XRPL,
157
153
  [ChainType.STELLAR]: CHAIN_IDS.STELLAR,
158
154
  [ChainType.CANTON]: CHAIN_IDS.CANTON,
159
- [ChainType.DANAL]: CHAIN_IDS.DANAL_TESTNET,
160
155
  };
161
156
  const chainTypeToNativeTokenAddressMap = {
162
157
  [ChainType.EVM]: nativeEvmTokenAddress,
@@ -167,7 +162,6 @@ const chainTypeToNativeTokenAddressMap = {
167
162
  [ChainType.XRPL]: nativeXrplTokenAddress,
168
163
  [ChainType.STELLAR]: nativeStellarTokenAddress,
169
164
  [ChainType.CANTON]: nativeCantonTokenAddress,
170
- [ChainType.DANAL]: nativeDanalTokenAddress,
171
165
  };
172
166
  const defaultConfigValues = {
173
167
  integratorId: INTEGRATOR_ID,
@@ -20949,6 +20943,9 @@ const isBitcoinAddressValid = (address$1) => {
20949
20943
  }
20950
20944
  };
20951
20945
 
20946
+ function getCantonCommandId(memo) {
20947
+ return `canton-${memo}`;
20948
+ }
20952
20949
  /**
20953
20950
  * Format a Canton connector into a Squid {@link CantonWallet}. Shared by the
20954
20951
  * announce-discovery and injected-provider paths.
@@ -21099,51 +21096,16 @@ function cantonInstrumentKey(instrument) {
21099
21096
  * is already a Decimal, not base units).
21100
21097
  */
21101
21098
  function groupCantonHoldingBalances(acsResponse) {
21099
+ return sumCantonHoldingBalances(parseCantonHoldings(acsResponse).filter((holding) => !holding.locked));
21100
+ }
21101
+ function sumCantonHoldingBalances(holdings) {
21102
21102
  const totals = {};
21103
- for (const holding of parseCantonHoldings(acsResponse)) {
21104
- // Locked holdings are not spendable, skip them
21105
- if (holding.locked)
21106
- continue;
21103
+ for (const holding of holdings) {
21107
21104
  const key = cantonInstrumentKey(holding.instrument);
21108
21105
  const total = totals[key] ?? new BigNumber(0);
21109
21106
  totals[key] = total.plus(new BigNumber(holding.amount));
21110
21107
  }
21111
- return Object.fromEntries(Object.entries(totals).map(([key, total]) => [key, total.toString(10)]));
21112
- }
21113
-
21114
- // Matches the backend validation: "PCI" + 50 uppercase-hex chars, case-sensitive.
21115
- const DANAL_ADDRESS_REGEX = /^PCI[0-9A-F]{50}$/;
21116
- function isDanalAddressValid(address) {
21117
- if (!address)
21118
- return false;
21119
- return DANAL_ADDRESS_REGEX.test(address);
21120
- }
21121
- // Fabric transaction id: 64 hex chars, no 0x prefix
21122
- const DANAL_TX_HASH_REGEX = /^[0-9a-fA-F]{64}$/;
21123
- function isDanalTxHashValid(hash) {
21124
- if (!hash)
21125
- return false;
21126
- return DANAL_TX_HASH_REGEX.test(hash);
21127
- }
21128
- function isDanalTransferRequestBody(value) {
21129
- if (typeof value !== "object" || value === null)
21130
- return false;
21131
- const { receiver, amount, memo } = value;
21132
- return (typeof receiver === "string" &&
21133
- receiver.length > 0 &&
21134
- typeof amount === "string" &&
21135
- amount.length > 0 &&
21136
- typeof memo === "string" &&
21137
- memo.length > 0);
21138
- }
21139
- function parseDanalTransferBody(data) {
21140
- try {
21141
- const parsed = JSON.parse(data);
21142
- return isDanalTransferRequestBody(parsed) ? parsed : null;
21143
- }
21144
- catch {
21145
- return null;
21146
- }
21108
+ return Object.fromEntries(Object.entries(totals).map(([key, total]) => [key, total.toFixed()]));
21147
21109
  }
21148
21110
 
21149
21111
  const solanaTokenProgramIdByAddress = {
@@ -21482,15 +21444,6 @@ function isOnChainTxData(squidData) {
21482
21444
  function isDepositAddressDirectTransferRoute(squidData) {
21483
21445
  return squidData.type === SquidDataType.DepositAddressDirectTransfer;
21484
21446
  }
21485
- /**
21486
- * Danal keeps SquidDataType.DepositAddressWithMemo, which XRPL/Stellar use for
21487
- * wallet-signed transactions — so the deposit treatment is gated on the chain,
21488
- * not just the type
21489
- */
21490
- function isDanalDepositRoute(route) {
21491
- return (route.params.fromChain === CHAIN_IDS.DANAL_TESTNET &&
21492
- route.transactionRequest?.type === SquidDataType.DepositAddressWithMemo);
21493
- }
21494
21447
  function getHistoryTransactionId(tx) {
21495
21448
  switch (tx.txType) {
21496
21449
  case HistoryTxType.SWAP:
@@ -22015,11 +21968,6 @@ const chainTypeToTrimLength = {
22015
21968
  start: 3,
22016
21969
  end: 3,
22017
21970
  },
22018
- // PCI0180...E77E
22019
- [ChainType.DANAL]: {
22020
- start: 7,
22021
- end: 4,
22022
- },
22023
21971
  };
22024
21972
  const truncateWithEllipsis = (value, startLength, endLength) => value.length <= startLength + endLength
22025
21973
  ? value
@@ -22068,8 +22016,6 @@ const isWalletAddressValid = (chainData, address) => {
22068
22016
  return isStellarAddressValid(address);
22069
22017
  case ChainType.CANTON:
22070
22018
  return isCantonAddressValid(address);
22071
- case ChainType.DANAL:
22072
- return isDanalAddressValid(address);
22073
22019
  }
22074
22020
  };
22075
22021
  const redirectToExtensionsStore = (wallet) => {
@@ -22354,8 +22300,6 @@ const connectByChainType = async (chainType, wallet, defaultChain, params) => {
22354
22300
  connector,
22355
22301
  },
22356
22302
  });
22357
- case ChainType.DANAL:
22358
- return null;
22359
22303
  }
22360
22304
  };
22361
22305
  const getChainTypesToConnect = (selectedChainTypes, defaultChain, supportedChains) => {
@@ -22480,6 +22424,8 @@ const cancelConnectWallet = (wallet) => {
22480
22424
  return;
22481
22425
  }
22482
22426
  switch (wallet.type) {
22427
+ case ChainType.CANTON:
22428
+ return wallet.connector.cancelConnect?.();
22483
22429
  case ChainType.XRPL:
22484
22430
  return wallet.connector.cancelConnect?.();
22485
22431
  default:
@@ -23340,7 +23286,7 @@ const handleDestinationAddressOnSwapChange = ({ fromChainId, fromTokenAddress, t
23340
23286
  });
23341
23287
  let destinationTokenAddress = toChainId && !toTokenAddress
23342
23288
  ? defaultToAddress
23343
- : toTokenAddress ?? swapRoute?.toTokenAddress;
23289
+ : (toTokenAddress ?? swapRoute?.toTokenAddress);
23344
23290
  const lowerCaseDestinationTokenAddress = destinationTokenAddress?.toLowerCase();
23345
23291
  if (destinationTokensFiltered.find((t) => t.address === lowerCaseDestinationTokenAddress) === undefined) {
23346
23292
  destinationTokenAddress = defaultToAddress;
@@ -23392,7 +23338,7 @@ const getNewSwapParamsFromInput = ({ inputParams, initialSwapRoute, tokens, chai
23392
23338
  toTokenAddress === initialSwapRoute?.fromTokenAddress;
23393
23339
  const sourceTokenAddress = sameNewDestAndInitialSource || onlySourceChainIdChanged
23394
23340
  ? defaultFromAddress
23395
- : fromTokenAddress ?? initialSwapRoute?.fromTokenAddress;
23341
+ : (fromTokenAddress ?? initialSwapRoute?.fromTokenAddress);
23396
23342
  let destinationTokenAddress = undefined;
23397
23343
  if (!sameNewSourceAndInitialDest) {
23398
23344
  if (onlySourceChainIdChanged) {
@@ -23714,7 +23660,7 @@ const filterViewableTokens = (tokens, config, direction) => {
23714
23660
  };
23715
23661
  const getSecretNetworkBalances = async (chainData, cosmosAddress, squidTokens, keplrTypeWallet) => {
23716
23662
  const squidSecretTokens = squidTokens.filter((t) => t.chainId === CHAIN_IDS.SECRET);
23717
- const { fetchAllSecretBalances } = await import('./secretService-Dvc9Dg4U.js');
23663
+ const { fetchAllSecretBalances } = await import('./secretService--tJFCkzT.js');
23718
23664
  return fetchAllSecretBalances(chainData, cosmosAddress, squidSecretTokens, keplrTypeWallet);
23719
23665
  };
23720
23666
  function getTokenAssetsKey(token) {
@@ -25708,7 +25654,7 @@ const useSquidTokens = (direction) => {
25708
25654
  config.availableChains,
25709
25655
  direction,
25710
25656
  ]);
25711
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useMemo(() => {
25657
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useMemo(() => {
25712
25658
  return tokens?.reduce((acc, token) => {
25713
25659
  switch (token.type) {
25714
25660
  case ChainType.EVM:
@@ -25735,9 +25681,6 @@ const useSquidTokens = (direction) => {
25735
25681
  case ChainType.CANTON:
25736
25682
  acc.cantonTokens.push(token);
25737
25683
  break;
25738
- case ChainType.DANAL:
25739
- acc.danalTokens.push(token);
25740
- break;
25741
25684
  }
25742
25685
  return acc;
25743
25686
  }, {
@@ -25749,7 +25692,6 @@ const useSquidTokens = (direction) => {
25749
25692
  xrplTokens: [],
25750
25693
  stellarTokens: [],
25751
25694
  cantonTokens: [],
25752
- danalTokens: [],
25753
25695
  });
25754
25696
  }, [tokens]);
25755
25697
  const findToken = useCallback((address, chainId) => {
@@ -25768,7 +25710,6 @@ const useSquidTokens = (direction) => {
25768
25710
  xrplTokens,
25769
25711
  stellarTokens,
25770
25712
  cantonTokens,
25771
- danalTokens,
25772
25713
  };
25773
25714
  };
25774
25715
 
@@ -26305,7 +26246,6 @@ const chainTypeToRefetchInterval = {
26305
26246
  [ChainType.XRPL]: 1_000,
26306
26247
  [ChainType.STELLAR]: 1_000,
26307
26248
  [ChainType.CANTON]: 1_000,
26308
- [ChainType.DANAL]: 1_000,
26309
26249
  };
26310
26250
  /**
26311
26251
  * Returns the status refetch interval of a Send transaction
@@ -26572,7 +26512,7 @@ const useSquidChains = (direction) => {
26572
26512
  const chain = findChain(chainId);
26573
26513
  return chain?.chainType;
26574
26514
  }, [findChain]);
26575
- const { evmChains, cosmosChains, suiChains, stellarChains, xrplChains, cantonChains, danalChains, } = useMemo(() => {
26515
+ const { evmChains, cosmosChains, suiChains, stellarChains, xrplChains, cantonChains, } = useMemo(() => {
26576
26516
  return chains.reduce((acc, chain) => {
26577
26517
  switch (chain.chainType) {
26578
26518
  case ChainType.EVM:
@@ -26593,9 +26533,6 @@ const useSquidChains = (direction) => {
26593
26533
  case ChainType.CANTON:
26594
26534
  acc.cantonChains.push(chain);
26595
26535
  break;
26596
- case ChainType.DANAL:
26597
- acc.danalChains.push(chain);
26598
- break;
26599
26536
  }
26600
26537
  return acc;
26601
26538
  }, {
@@ -26605,7 +26542,6 @@ const useSquidChains = (direction) => {
26605
26542
  xrplChains: [],
26606
26543
  stellarChains: [],
26607
26544
  cantonChains: [],
26608
- danalChains: [],
26609
26545
  });
26610
26546
  }, [chains]);
26611
26547
  const { supportedSourceChains, supportedDestinationChains } = useMemo(() => {
@@ -26627,7 +26563,6 @@ const useSquidChains = (direction) => {
26627
26563
  xrplChains,
26628
26564
  stellarChains,
26629
26565
  cantonChains,
26630
- danalChains,
26631
26566
  getChainType,
26632
26567
  findChain,
26633
26568
  };
@@ -26941,7 +26876,343 @@ const useBitcoinContext = () => {
26941
26876
  return context;
26942
26877
  };
26943
26878
 
26944
- const REQUEST_TIMEOUT_MS = 60_000;
26879
+ const vParty = (party) => ({ party });
26880
+ const vText = (text) => ({ text });
26881
+ const vNumeric = (numeric) => ({ numeric });
26882
+ const vContractId = (contractId) => ({
26883
+ contractId,
26884
+ });
26885
+ const vList = (elements) => ({
26886
+ list: { elements },
26887
+ });
26888
+ const vRecord = (fields) => ({
26889
+ record: { fields: fields.map(([label, value]) => ({ label, value })) },
26890
+ });
26891
+ const vTextMap = (entries) => ({ textMap: { entries } });
26892
+ const vTimestamp = (isoString) => ({
26893
+ timestamp: String(Math.floor(new Date(isoString).getTime() * 1000)),
26894
+ });
26895
+ function isRecord(value) {
26896
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26897
+ }
26898
+ function normalizeChoiceContextValue(value) {
26899
+ if (typeof value === "string")
26900
+ return value;
26901
+ if (!isRecord(value) || typeof value.tag !== "string")
26902
+ return null;
26903
+ switch (value.tag) {
26904
+ case "AV_Text":
26905
+ case "AV_ContractId":
26906
+ return typeof value.value === "string"
26907
+ ? { tag: value.tag, value: value.value }
26908
+ : null;
26909
+ case "AV_Bool":
26910
+ return typeof value.value === "boolean"
26911
+ ? { tag: value.tag, value: value.value }
26912
+ : null;
26913
+ case "AV_List":
26914
+ if (!Array.isArray(value.value))
26915
+ return null;
26916
+ return {
26917
+ tag: value.tag,
26918
+ value: value.value.flatMap((entry) => {
26919
+ const normalized = normalizeChoiceContextValue(entry);
26920
+ return normalized ? [normalized] : [];
26921
+ }),
26922
+ };
26923
+ default: {
26924
+ const inner = value.value;
26925
+ if (typeof inner === "string" ||
26926
+ typeof inner === "number" ||
26927
+ typeof inner === "boolean" ||
26928
+ inner === null) {
26929
+ return { tag: value.tag, value: inner };
26930
+ }
26931
+ if (Array.isArray(inner)) {
26932
+ return {
26933
+ tag: value.tag,
26934
+ value: inner.flatMap((entry) => {
26935
+ const normalized = normalizeChoiceContextValue(entry);
26936
+ return normalized ? [normalized] : [];
26937
+ }),
26938
+ };
26939
+ }
26940
+ if (!isRecord(inner))
26941
+ return null;
26942
+ const normalizedObject = {};
26943
+ for (const [key, entry] of Object.entries(inner)) {
26944
+ if (typeof entry !== "string" &&
26945
+ typeof entry !== "number" &&
26946
+ typeof entry !== "boolean" &&
26947
+ entry !== null) {
26948
+ return null;
26949
+ }
26950
+ normalizedObject[key] = entry;
26951
+ }
26952
+ return { tag: value.tag, value: normalizedObject };
26953
+ }
26954
+ }
26955
+ }
26956
+ function stringifyChoiceContextValue(value) {
26957
+ return typeof value === "string" ? value : String(value);
26958
+ }
26959
+ function choiceContextValueToAnyValue(value) {
26960
+ if (typeof value === "string") {
26961
+ return {
26962
+ variant: { constructor: "AV_Text", value: vText(value) },
26963
+ };
26964
+ }
26965
+ switch (value.tag) {
26966
+ case "AV_ContractId":
26967
+ if (typeof value.value !== "string") {
26968
+ throw new TypeError("AV_ContractId values must be strings");
26969
+ }
26970
+ return {
26971
+ variant: { constructor: value.tag, value: vContractId(value.value) },
26972
+ };
26973
+ case "AV_Bool":
26974
+ if (typeof value.value !== "boolean") {
26975
+ throw new TypeError("AV_Bool values must be booleans");
26976
+ }
26977
+ return {
26978
+ variant: { constructor: value.tag, value: { bool: value.value } },
26979
+ };
26980
+ case "AV_List":
26981
+ if (!Array.isArray(value.value)) {
26982
+ throw new TypeError("AV_List values must be arrays");
26983
+ }
26984
+ return {
26985
+ variant: {
26986
+ constructor: value.tag,
26987
+ value: vList(value.value.map(choiceContextValueToAnyValue)),
26988
+ },
26989
+ };
26990
+ default:
26991
+ return {
26992
+ variant: {
26993
+ constructor: value.tag,
26994
+ value: vText(stringifyChoiceContextValue(value.value)),
26995
+ },
26996
+ };
26997
+ }
26998
+ }
26999
+
27000
+ /** Metadata key used by Splice token-standard transfers to carry our Squid orderhash memo. */
27001
+ const CANTON_MEMO_KEY = "splice.lfdecentralizedtrust.org/reason";
27002
+ /** Interface id for the transfer factory contract returned by the token registry. */
27003
+ const TRANSFER_FACTORY_INTERFACE_ID = "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory";
27004
+ /** Choice exercised on the transfer factory to create the token-standard transfer. */
27005
+ const TRANSFER_FACTORY_CHOICE = "TransferFactory_Transfer";
27006
+ /** CIP-056 (non-Amulet) tokens expose a registrar parameterized by admin party. */
27007
+ const CIP056_REGISTRAR_BASE = "https://api.utilities.digitalasset.com/api/token-standard/v0/registrars";
27008
+ const TRANSFER_REQUESTED_AT_SKEW_MS = 60_000;
27009
+ const TRANSFER_EXECUTE_WINDOW_MS = 24 * 60 * 60 * 1000;
27010
+ function resolveCantonRegistryUrl(instrument) {
27011
+ if (instrument.id === CANTON_AMULET_INSTRUMENT_ID) {
27012
+ return CANTON_AMULET_REGISTRY_URL;
27013
+ }
27014
+ return `${CIP056_REGISTRAR_BASE}/${encodeURIComponent(instrument.admin)}`;
27015
+ }
27016
+ /**
27017
+ * Build the plain JSON arguments expected by the registry transfer-factory
27018
+ * endpoint before it adds choice context and disclosed contracts.
27019
+ */
27020
+ function buildTransferChoiceArgs({ sender, receiver, amount, instrument, inputHoldingCids, memo, nowMs, }) {
27021
+ return {
27022
+ expectedAdmin: instrument.admin,
27023
+ transfer: {
27024
+ sender,
27025
+ receiver,
27026
+ amount,
27027
+ instrumentId: { admin: instrument.admin, id: instrument.id },
27028
+ requestedAt: new Date(nowMs - TRANSFER_REQUESTED_AT_SKEW_MS).toISOString(),
27029
+ executeBefore: new Date(nowMs + TRANSFER_EXECUTE_WINDOW_MS).toISOString(),
27030
+ inputHoldingCids,
27031
+ meta: { values: { [CANTON_MEMO_KEY]: memo } },
27032
+ },
27033
+ extraArgs: { context: { values: {} }, meta: { values: {} } },
27034
+ };
27035
+ }
27036
+ /**
27037
+ * Canton's Holding contracts follow Bitcoin-style UTXOs model.
27038
+ *
27039
+ * Pick Holding contract ids covering `amount` for the instrument: prefer a
27040
+ * single exact-amount holding, else accumulate largest-first.
27041
+ */
27042
+ function selectInputHoldingCids(holdings, instrument, amount) {
27043
+ const spendableHoldings = holdings.filter((h) => !h.locked &&
27044
+ h.instrument.admin === instrument.admin &&
27045
+ h.instrument.id === instrument.id);
27046
+ const target = new BigNumber(amount);
27047
+ const exact = spendableHoldings.find((h) => new BigNumber(h.amount).eq(target));
27048
+ if (exact)
27049
+ return [exact.contractId];
27050
+ const sorted = [...spendableHoldings].sort((a, b) => new BigNumber(b.amount).comparedTo(new BigNumber(a.amount)));
27051
+ const selected = [];
27052
+ let sum = new BigNumber(0);
27053
+ for (const holding of sorted) {
27054
+ selected.push(holding.contractId);
27055
+ sum = sum.plus(holding.amount);
27056
+ if (sum.gte(target))
27057
+ break;
27058
+ }
27059
+ if (sum.lt(target)) {
27060
+ throw new Error("Insufficient Canton holdings to cover transfer amount");
27061
+ }
27062
+ return selected;
27063
+ }
27064
+ async function fetchInputHoldingCids(connector, party, instrument, amount) {
27065
+ const ledgerEnd = await connector.ledgerApi({
27066
+ requestMethod: "get",
27067
+ resource: "/v2/state/ledger-end",
27068
+ });
27069
+ const activeContracts = await connector.ledgerApi({
27070
+ requestMethod: "post",
27071
+ resource: "/v2/state/active-contracts",
27072
+ body: buildHoldingsAcsRequestBody(party, String(ledgerEnd.offset)),
27073
+ });
27074
+ return selectInputHoldingCids(parseCantonHoldings(activeContracts), instrument, amount);
27075
+ }
27076
+ /**
27077
+ * Ask the token registry for the transfer factory contract and extra context
27078
+ * required to exercise its transfer choice.
27079
+ */
27080
+ async function fetchTransferFactory(registryUrl, choiceArgs) {
27081
+ const response = await fetch(`${registryUrl}/registry/transfer-instruction/v1/transfer-factory`, {
27082
+ method: "POST",
27083
+ headers: { "Content-Type": "application/json" },
27084
+ body: JSON.stringify({
27085
+ choiceArguments: choiceArgs,
27086
+ excludeDebugFields: true,
27087
+ }),
27088
+ });
27089
+ if (!response.ok) {
27090
+ throw new Error(`Canton transfer-factory request failed (${response.status})`);
27091
+ }
27092
+ return response.json();
27093
+ }
27094
+ /**
27095
+ * Convert transfer choice args into strict Daml Value JSON for the wallet's
27096
+ * prepareExecute ExerciseCommand.
27097
+ */
27098
+ function buildPrepareChoiceArgument(choiceArgs) {
27099
+ const contextValues = Object.entries(choiceArgs.extraArgs.context?.values ?? {})
27100
+ .map(([key, value]) => {
27101
+ const normalized = normalizeChoiceContextValue(value);
27102
+ return normalized
27103
+ ? { key, value: choiceContextValueToAnyValue(normalized) }
27104
+ : undefined;
27105
+ })
27106
+ .filter((entry) => Boolean(entry));
27107
+ return vRecord([
27108
+ ["expectedAdmin", vParty(choiceArgs.expectedAdmin)],
27109
+ [
27110
+ "transfer",
27111
+ vRecord([
27112
+ ["sender", vParty(choiceArgs.transfer.sender)],
27113
+ ["receiver", vParty(choiceArgs.transfer.receiver)],
27114
+ ["amount", vNumeric(choiceArgs.transfer.amount)],
27115
+ [
27116
+ "instrumentId",
27117
+ vRecord([
27118
+ ["admin", vParty(choiceArgs.transfer.instrumentId.admin)],
27119
+ ["id", vText(choiceArgs.transfer.instrumentId.id)],
27120
+ ]),
27121
+ ],
27122
+ ["requestedAt", vTimestamp(choiceArgs.transfer.requestedAt)],
27123
+ ["executeBefore", vTimestamp(choiceArgs.transfer.executeBefore)],
27124
+ [
27125
+ "inputHoldingCids",
27126
+ vList(choiceArgs.transfer.inputHoldingCids.map(vContractId)),
27127
+ ],
27128
+ [
27129
+ "meta",
27130
+ vRecord([
27131
+ [
27132
+ "values",
27133
+ vTextMap(Object.entries(choiceArgs.transfer.meta.values).map(([key, value]) => ({ key, value: vText(value) }))),
27134
+ ],
27135
+ ]),
27136
+ ],
27137
+ ]),
27138
+ ],
27139
+ [
27140
+ "extraArgs",
27141
+ vRecord([
27142
+ ["context", vRecord([["values", vTextMap(contextValues)]])],
27143
+ ["meta", vRecord([["values", vTextMap([])]])],
27144
+ ]),
27145
+ ],
27146
+ ]);
27147
+ }
27148
+ /**
27149
+ * Convert a registry disclosed contract into the wallet submission shape,
27150
+ * dropping debug fields and entries without a usable createdEventBlob.
27151
+ */
27152
+ function toDisclosedContract(raw) {
27153
+ if (typeof raw.createdEventBlob !== "string")
27154
+ return null;
27155
+ return {
27156
+ createdEventBlob: raw.createdEventBlob,
27157
+ contractId: typeof raw.contractId === "string" ? raw.contractId : undefined,
27158
+ synchronizerId: typeof raw.synchronizerId === "string" ? raw.synchronizerId : undefined,
27159
+ };
27160
+ }
27161
+ /**
27162
+ * Build a Splice token-standard transfer of `amount` of `token` from `sender`
27163
+ * to `receiver`, carrying `memo`, ready to hand to a wallet's prepareExecute.
27164
+ * Returns the full prepareExecute params (commandId + commands + actAs +
27165
+ * disclosedContracts).
27166
+ */
27167
+ async function buildCantonTransfer(connector, { sender, receiver, amount, token, memo, nowMs, }) {
27168
+ if (!token.originalAddress) {
27169
+ throw new Error("Canton token originalAddress is required");
27170
+ }
27171
+ const instrument = parseCantonInstrument(token.originalAddress);
27172
+ if (!instrument) {
27173
+ throw new Error(`Invalid Canton token address: ${token.originalAddress}`);
27174
+ }
27175
+ const registryUrl = resolveCantonRegistryUrl(instrument);
27176
+ const inputHoldingCids = await fetchInputHoldingCids(connector, sender, instrument, amount);
27177
+ const choiceArgs = buildTransferChoiceArgs({
27178
+ sender,
27179
+ receiver,
27180
+ amount,
27181
+ instrument,
27182
+ inputHoldingCids,
27183
+ memo,
27184
+ nowMs,
27185
+ });
27186
+ const factory = await fetchTransferFactory(registryUrl, choiceArgs);
27187
+ const choiceContextData = factory.choiceContext.choiceContextData;
27188
+ if (!choiceContextData) {
27189
+ throw new Error("Transfer factory choice context is missing");
27190
+ }
27191
+ choiceArgs.extraArgs.context = choiceContextData;
27192
+ const disclosedContracts = (factory.choiceContext?.disclosedContracts ?? []).flatMap((raw) => {
27193
+ const disclosedContract = toDisclosedContract(raw);
27194
+ return disclosedContract ? [disclosedContract] : [];
27195
+ });
27196
+ // Command ID: client-supplied identifier used to deduplicate submissions
27197
+ const commandId = getCantonCommandId(memo);
27198
+ return {
27199
+ commandId,
27200
+ commands: [
27201
+ {
27202
+ ExerciseCommand: {
27203
+ templateId: TRANSFER_FACTORY_INTERFACE_ID,
27204
+ contractId: factory.factoryId,
27205
+ choice: TRANSFER_FACTORY_CHOICE,
27206
+ choiceArgument: buildPrepareChoiceArgument(choiceArgs),
27207
+ },
27208
+ },
27209
+ ],
27210
+ actAs: [sender],
27211
+ disclosedContracts,
27212
+ };
27213
+ }
27214
+
27215
+ const REQUEST_TIMEOUT_MS$1 = 60_000;
26945
27216
  function pickAddress(accounts) {
26946
27217
  return (accounts.find((a) => a.primary) ?? accounts[0])?.partyId;
26947
27218
  }
@@ -26950,6 +27221,7 @@ function pickAddress(accounts) {
26950
27221
  * (bound to its announce `target`) and exposes the lifecycle methods.
26951
27222
  */
26952
27223
  class CantonBrowserConnector {
27224
+ kind = "cip103";
26953
27225
  providerId;
26954
27226
  name;
26955
27227
  target;
@@ -26964,7 +27236,7 @@ class CantonBrowserConnector {
26964
27236
  client ??
26965
27237
  createCantonClient(new WindowTransport(win, {
26966
27238
  target: this.target,
26967
- timeout: REQUEST_TIMEOUT_MS,
27239
+ timeout: REQUEST_TIMEOUT_MS$1,
26968
27240
  }));
26969
27241
  }
26970
27242
  get accounts() {
@@ -27010,6 +27282,28 @@ class CantonBrowserConnector {
27010
27282
  this._accounts = await this.client.listAccounts();
27011
27283
  return this._accounts;
27012
27284
  }
27285
+ async getBalances(partyId) {
27286
+ const { offset } = await this.ledgerApi({
27287
+ requestMethod: "get",
27288
+ resource: "/v2/state/ledger-end",
27289
+ });
27290
+ const contracts = await this.ledgerApi({
27291
+ requestMethod: "post",
27292
+ resource: "/v2/state/active-contracts",
27293
+ body: buildHoldingsAcsRequestBody(partyId, String(offset)),
27294
+ });
27295
+ return groupCantonHoldingBalances(contracts);
27296
+ }
27297
+ async transfer(params) {
27298
+ const payload = await buildCantonTransfer(this, params);
27299
+ const result = await this.prepareExecuteAndWait(payload);
27300
+ const updateId = result.tx?.payload?.updateId ?? "";
27301
+ return {
27302
+ status: "completed",
27303
+ commandId: getCantonCommandId(params.memo),
27304
+ updateId,
27305
+ };
27306
+ }
27013
27307
  on(event, handler) {
27014
27308
  this.listeners[event].add(handler);
27015
27309
  }
@@ -27116,6 +27410,313 @@ function discoverInjectedCantonWallets(win) {
27116
27410
  });
27117
27411
  }
27118
27412
 
27413
+ class CantonConnectionCancelledError extends Error {
27414
+ code = 4001;
27415
+ constructor() {
27416
+ super("Wallet connection cancelled");
27417
+ }
27418
+ }
27419
+
27420
+ const REQUEST_TIMEOUT_MS = 5 * 60_000;
27421
+ const OVERLAY_ID = "loop-sdk-connect-overlay";
27422
+ class LoopSubmissionUnknownError extends Error {
27423
+ constructor(cause) {
27424
+ super("Loop transfer outcome is unknown. Check Loop before trying again.", {
27425
+ cause,
27426
+ });
27427
+ }
27428
+ }
27429
+ function parseLoopTransferUpdate(value, commandId) {
27430
+ if (!value || typeof value !== "object")
27431
+ return undefined;
27432
+ const response = value;
27433
+ if (response.command_id !== commandId)
27434
+ return undefined;
27435
+ if (response.status === "failed" || response.error) {
27436
+ const error = response.error;
27437
+ return {
27438
+ status: "failed",
27439
+ commandId,
27440
+ message: typeof error?.error_message === "string"
27441
+ ? error.error_message
27442
+ : "Loop transaction failed",
27443
+ };
27444
+ }
27445
+ if (typeof response.update_id === "string" && response.update_id) {
27446
+ return { status: "completed", commandId, updateId: response.update_id };
27447
+ }
27448
+ return undefined;
27449
+ }
27450
+ class LoopCantonConnector {
27451
+ loadSdk;
27452
+ kind = "loop";
27453
+ providerId = "canton-loop";
27454
+ name = "Loop";
27455
+ target = undefined;
27456
+ module;
27457
+ initialization;
27458
+ provider;
27459
+ pendingConnection;
27460
+ connectionStart = Promise.resolve();
27461
+ transfers = new Map();
27462
+ listeners = { connect: new Set(), disconnect: new Set() };
27463
+ constructor(loadSdk = () => import('@fivenorth/loop-sdk')) {
27464
+ this.loadSdk = loadSdk;
27465
+ }
27466
+ get accounts() {
27467
+ return this.provider
27468
+ ? [{ partyId: this.provider.party_id, primary: true }]
27469
+ : [];
27470
+ }
27471
+ get address() {
27472
+ return this.provider?.party_id;
27473
+ }
27474
+ connect() {
27475
+ return this.startConnection(true);
27476
+ }
27477
+ autoConnect() {
27478
+ return this.startConnection(false);
27479
+ }
27480
+ cancelConnect() {
27481
+ if (!this.pendingConnection)
27482
+ return;
27483
+ this.rejectConnection(new CantonConnectionCancelledError());
27484
+ this.module?.loop.logout();
27485
+ }
27486
+ async disconnect() {
27487
+ this.cancelConnect();
27488
+ this.module?.loop.logout();
27489
+ this.provider = undefined;
27490
+ this.emit("disconnect");
27491
+ }
27492
+ async getAccounts() {
27493
+ const provider = this.requireProvider();
27494
+ try {
27495
+ const account = await provider.getAccount();
27496
+ if (account.party_id !== provider.party_id) {
27497
+ await this.disconnect();
27498
+ throw new Error("Loop account changed. Connect again.");
27499
+ }
27500
+ return this.accounts;
27501
+ }
27502
+ catch (error) {
27503
+ if (this.module && error instanceof this.module.UnauthorizedError) {
27504
+ await this.disconnect();
27505
+ }
27506
+ throw error;
27507
+ }
27508
+ }
27509
+ async getBalances(partyId) {
27510
+ const provider = this.requireProvider();
27511
+ if (partyId !== provider.party_id) {
27512
+ throw new Error("Loop balances require the connected account");
27513
+ }
27514
+ const holdings = await provider.getHolding();
27515
+ return sumCantonHoldingBalances(holdings.map((holding) => {
27516
+ const amount = new BigNumber(holding.total_unlocked_coin);
27517
+ if (!amount.isFinite() || amount.isNegative()) {
27518
+ throw new Error("Loop returned an invalid balance");
27519
+ }
27520
+ return {
27521
+ instrument: holding.instrument_id,
27522
+ amount: holding.total_unlocked_coin,
27523
+ };
27524
+ }));
27525
+ }
27526
+ transfer(params) {
27527
+ const commandId = getCantonCommandId(params.memo);
27528
+ const existing = this.transfers.get(commandId);
27529
+ if (existing)
27530
+ return existing;
27531
+ const request = this.submitTransfer(params, commandId).catch((error) => {
27532
+ if (!(error instanceof LoopSubmissionUnknownError))
27533
+ this.transfers.delete(commandId);
27534
+ throw error;
27535
+ });
27536
+ this.transfers.set(commandId, request);
27537
+ return request;
27538
+ }
27539
+ on(event, handler) {
27540
+ this.listeners[event].add(handler);
27541
+ }
27542
+ off(event, handler) {
27543
+ this.listeners[event].delete(handler);
27544
+ }
27545
+ emit(event, ...args) {
27546
+ this.listeners[event].forEach((handler) => handler(...args));
27547
+ }
27548
+ initialize() {
27549
+ if (!this.initialization) {
27550
+ this.initialization = this.loadSdk()
27551
+ .then((module) => {
27552
+ module.loop.init({
27553
+ appName: SQUID_METADATA.name,
27554
+ network: "mainnet",
27555
+ onAccept: (provider) => this.acceptConnection(provider),
27556
+ onReject: () => {
27557
+ this.rejectConnection(new CantonConnectionCancelledError());
27558
+ this.provider = undefined;
27559
+ this.emit("disconnect");
27560
+ },
27561
+ });
27562
+ this.module = module;
27563
+ })
27564
+ .catch((error) => {
27565
+ this.initialization = undefined;
27566
+ throw error;
27567
+ });
27568
+ }
27569
+ return this.initialization;
27570
+ }
27571
+ startConnection(interactive) {
27572
+ if (this.pendingConnection)
27573
+ return this.pendingConnection.promise;
27574
+ let resolve;
27575
+ let reject;
27576
+ const promise = new Promise((accept, decline) => {
27577
+ resolve = accept;
27578
+ reject = decline;
27579
+ });
27580
+ const timer = setTimeout(() => {
27581
+ this.rejectConnection(new Error("Loop connection timed out"));
27582
+ this.module?.loop.logout();
27583
+ }, REQUEST_TIMEOUT_MS);
27584
+ let observer;
27585
+ const pending = {
27586
+ promise,
27587
+ resolve,
27588
+ reject,
27589
+ cleanup: () => {
27590
+ clearTimeout(timer);
27591
+ observer?.disconnect();
27592
+ },
27593
+ };
27594
+ this.pendingConnection = pending;
27595
+ this.connectionStart = this.connectionStart
27596
+ .then(async () => {
27597
+ await this.initialize();
27598
+ if (this.pendingConnection !== pending)
27599
+ return;
27600
+ if (interactive && typeof MutationObserver !== "undefined") {
27601
+ let sawOverlay = false;
27602
+ observer = new MutationObserver(() => {
27603
+ const overlay = document.getElementById(OVERLAY_ID);
27604
+ if (overlay)
27605
+ sawOverlay = true;
27606
+ if (sawOverlay && !overlay && this.pendingConnection === pending) {
27607
+ this.cancelConnect();
27608
+ }
27609
+ });
27610
+ observer.observe(document.body, { childList: true });
27611
+ }
27612
+ const sdk = this.module.loop;
27613
+ if (interactive)
27614
+ await sdk.connect();
27615
+ else
27616
+ await sdk.autoConnect();
27617
+ if (!interactive && this.pendingConnection === pending) {
27618
+ this.rejectConnection(new Error("No saved Loop connection"));
27619
+ }
27620
+ else if (interactive &&
27621
+ this.pendingConnection !== pending &&
27622
+ !this.provider) {
27623
+ sdk.logout();
27624
+ }
27625
+ })
27626
+ .catch((error) => {
27627
+ if (this.pendingConnection === pending)
27628
+ this.rejectConnection(error);
27629
+ });
27630
+ return promise;
27631
+ }
27632
+ acceptConnection(provider) {
27633
+ const pending = this.pendingConnection;
27634
+ if (!pending)
27635
+ return;
27636
+ if (!provider.party_id) {
27637
+ this.rejectConnection(new Error("Loop returned no account"));
27638
+ return;
27639
+ }
27640
+ this.provider = provider;
27641
+ this.pendingConnection = undefined;
27642
+ pending.cleanup();
27643
+ pending.resolve({ address: provider.party_id, accounts: this.accounts });
27644
+ this.emit("connect", provider.party_id);
27645
+ }
27646
+ rejectConnection(error) {
27647
+ const pending = this.pendingConnection;
27648
+ if (!pending)
27649
+ return;
27650
+ this.pendingConnection = undefined;
27651
+ pending.cleanup();
27652
+ pending.reject(error);
27653
+ }
27654
+ requireProvider() {
27655
+ if (!this.provider)
27656
+ throw new Error("Loop wallet is not connected");
27657
+ return this.provider;
27658
+ }
27659
+ async submitTransfer(params, commandId) {
27660
+ const provider = this.requireProvider();
27661
+ if (params.sender !== provider.party_id)
27662
+ throw new Error("Loop account does not match the sender");
27663
+ const instrument = params.token.originalAddress
27664
+ ? parseCantonInstrument(params.token.originalAddress)
27665
+ : null;
27666
+ if (!instrument)
27667
+ throw new Error("Canton token originalAddress is required");
27668
+ if (!new BigNumber(params.amount).isFinite() ||
27669
+ !new BigNumber(params.amount).isPositive()) {
27670
+ throw new Error("Canton transfer amount must be positive");
27671
+ }
27672
+ const payload = await provider.connection.prepareTransfer(provider.getAuthToken(), {
27673
+ recipient: params.receiver,
27674
+ amount: params.amount,
27675
+ instrument: {
27676
+ instrument_admin: instrument.admin,
27677
+ instrument_id: instrument.id,
27678
+ },
27679
+ memo: params.memo,
27680
+ requested_at: new Date(params.nowMs - 60_000).toISOString(),
27681
+ execute_before: new Date(params.nowMs + 24 * 60 * 60_000).toISOString(),
27682
+ });
27683
+ if (this.provider !== provider)
27684
+ throw new Error("Loop account disconnected before submission");
27685
+ let response;
27686
+ let timer;
27687
+ try {
27688
+ const submission = { ...payload, commandId };
27689
+ const submitted = provider.submitAndWaitForTransaction(submission, {
27690
+ requestTimeout: REQUEST_TIMEOUT_MS,
27691
+ });
27692
+ response = await Promise.race([
27693
+ submitted,
27694
+ new Promise((_, reject) => {
27695
+ timer = setTimeout(() => reject(new Error("Loop submission timed out")), REQUEST_TIMEOUT_MS);
27696
+ }),
27697
+ ]);
27698
+ }
27699
+ catch (error) {
27700
+ if (this.module && error instanceof this.module.RejectRequestError) {
27701
+ throw Object.assign(new Error("Loop transaction rejected"), {
27702
+ code: 4001,
27703
+ });
27704
+ }
27705
+ throw new LoopSubmissionUnknownError(error);
27706
+ }
27707
+ finally {
27708
+ clearTimeout(timer);
27709
+ }
27710
+ const update = parseLoopTransferUpdate(response, commandId);
27711
+ if (update?.status === "failed")
27712
+ throw new Error(update.message);
27713
+ if (!update)
27714
+ throw new LoopSubmissionUnknownError();
27715
+ return update;
27716
+ }
27717
+ }
27718
+ const loopCantonConnector = new LoopCantonConnector();
27719
+
27119
27720
  /**
27120
27721
  * Discovers Canton browser-extension wallets and maps each to a
27121
27722
  * {@link CantonWallet}: CIP-103 announce-protocol wallets (on mount and on
@@ -27162,7 +27763,19 @@ function useCantonWallets() {
27162
27763
  return;
27163
27764
  const announced = (await discoverCantonProviders()).map(toAnnouncedWallet);
27164
27765
  const injected = discoverInjectedCantonWallets().map(toInjectedWallet);
27165
- setWallets(mergeInjectedCantonWallets(announced, injected));
27766
+ const loopWallet = {
27767
+ ...formatCantonWallet({
27768
+ connectorId: "canton-loop",
27769
+ name: "Loop",
27770
+ icon: "https://raw.githubusercontent.com/0xsquid/assets/main/images/master/wallets/canton-loop.svg",
27771
+ connector: loopCantonConnector,
27772
+ }),
27773
+ links: { website: "https://cantonloop.com" },
27774
+ isInstalled: () => false,
27775
+ skipInstallCheck: true,
27776
+ isMobile: true,
27777
+ };
27778
+ setWallets(mergeInjectedCantonWallets(announced, [...injected, loopWallet]));
27166
27779
  }, [toAnnouncedWallet, toInjectedWallet]);
27167
27780
  useEffect(() => {
27168
27781
  refresh();
@@ -27193,7 +27806,9 @@ function useCanton() {
27193
27806
  // Try to reconnect silently first (existing session, no popup)
27194
27807
  result = await wallet.connector.autoConnect();
27195
27808
  }
27196
- catch {
27809
+ catch (error) {
27810
+ if (error instanceof CantonConnectionCancelledError)
27811
+ throw error;
27197
27812
  // Otherwise prompt the wallet to connect
27198
27813
  result = await wallet.connector.connect();
27199
27814
  }
@@ -27215,8 +27830,7 @@ function useCanton() {
27215
27830
  wallet: recentCantonWallet,
27216
27831
  address,
27217
27832
  });
27218
- // eslint-disable-next-line react-hooks/exhaustive-deps
27219
- }, [wallets.map((w) => w.connectorId), recentCantonWalletId]);
27833
+ }, [wallets, recentCantonWalletId, setConnectedWallet]);
27220
27834
  useEffect(() => {
27221
27835
  const wallet = connectedCantonWallet.wallet;
27222
27836
  if (!wallet) {
@@ -27473,7 +28087,7 @@ function useStellarWallets() {
27473
28087
  try {
27474
28088
  const { allowAllModules: initializeAllModules } = await import('@creit.tech/stellar-wallets-kit');
27475
28089
  const { LedgerModule } = await import('@creit.tech/stellar-wallets-kit/modules/ledger.module.mjs');
27476
- const { formatStellarWallet } = await import('./stellarService.client-c48cnGgL.js');
28090
+ const { formatStellarWallet } = await import('./stellarService.client-DAxgO3m3.js');
27477
28091
  const modules = [...initializeAllModules(), new LedgerModule()];
27478
28092
  const promises = modules.map(async (module) => {
27479
28093
  const isAvailable = await module.isAvailable();
@@ -28052,6 +28666,11 @@ const useWallet = () => {
28052
28666
  }
28053
28667
  }
28054
28668
  catch (error) {
28669
+ const connecting = useWalletStore.getState().connectingWalletState;
28670
+ if (connecting.wallet !== wallet ||
28671
+ connecting.status !== ConnectingWalletStatus.CONNECTING) {
28672
+ return false;
28673
+ }
28055
28674
  console.error("Failed to connect wallet", error);
28056
28675
  walletConnectionError(wallet, error);
28057
28676
  return false;
@@ -28283,8 +28902,6 @@ const useMultiChainWallet = (chain) => {
28283
28902
  chainType: chain.chainType,
28284
28903
  }),
28285
28904
  };
28286
- case ChainType.DANAL:
28287
- return {};
28288
28905
  }
28289
28906
  }, [
28290
28907
  chain?.chainType,
@@ -29123,8 +29740,6 @@ async function createClient(chain) {
29123
29740
  return new StellarRpcClient(chain.rpc);
29124
29741
  case ChainType.CANTON:
29125
29742
  return null;
29126
- case ChainType.DANAL:
29127
- return null;
29128
29743
  }
29129
29744
  }
29130
29745
 
@@ -30139,8 +30754,7 @@ const getAllStellarTokensBalance = async (userAddress, stellarTokens, stellarCha
30139
30754
  };
30140
30755
  /**
30141
30756
  * Canton balances are private: they can only be read with a wallet-authorized
30142
- * `ledgerApi` session (the connected wallet supplies a JWT that can read as the
30143
- * party). So balance is fetchable only when a Canton wallet is connected, and
30757
+ * session. Balance is fetchable only when a Canton wallet is connected, and
30144
30758
  * only for that wallet's party — there's no address-only read.
30145
30759
  */
30146
30760
  const getCantonTokenBalance = async (userAddress, token, cantonConnector) => {
@@ -30149,30 +30763,14 @@ const getCantonTokenBalance = async (userAddress, token, cantonConnector) => {
30149
30763
  const instrument = parseCantonInstrument(token.originalAddress);
30150
30764
  if (!instrument)
30151
30765
  return "0";
30152
- const ledgerEnd = await cantonConnector.ledgerApi({ requestMethod: "get", resource: "/v2/state/ledger-end" });
30153
- const activeContracts = await cantonConnector.ledgerApi({
30154
- requestMethod: "post",
30155
- resource: "/v2/state/active-contracts",
30156
- body: buildHoldingsAcsRequestBody(userAddress, String(ledgerEnd.offset)),
30157
- });
30158
- const grouped = groupCantonHoldingBalances(activeContracts);
30766
+ const grouped = await cantonConnector.getBalances(userAddress);
30159
30767
  return grouped[cantonInstrumentKey(instrument)] ?? "0";
30160
30768
  };
30161
30769
  /**
30162
- * Fetch balances for all Canton tokens in one ACS query. Canton balances are
30163
- * private, so this requires a connected wallet's authorized `ledgerApi`.
30770
+ * Fetch balances for all Canton tokens through the connected wallet.
30164
30771
  */
30165
30772
  async function getAllCantonTokensBalance({ connector, partyId, tokens, }) {
30166
- const ledgerEnd = await connector.ledgerApi({
30167
- requestMethod: "get",
30168
- resource: "/v2/state/ledger-end",
30169
- });
30170
- const activeContracts = await connector.ledgerApi({
30171
- requestMethod: "post",
30172
- resource: "/v2/state/active-contracts",
30173
- body: buildHoldingsAcsRequestBody(partyId, String(ledgerEnd.offset)),
30174
- });
30175
- const grouped = groupCantonHoldingBalances(activeContracts);
30773
+ const grouped = await connector.getBalances(partyId);
30176
30774
  return tokens.map((token) => {
30177
30775
  const instrument = token.originalAddress
30178
30776
  ? parseCantonInstrument(token.originalAddress)
@@ -30391,7 +30989,7 @@ const useCantonBalance = ({ chain, token, userAddress, enabled = true, refreshIn
30391
30989
  };
30392
30990
 
30393
30991
  function useNativeTokenForChain(chain) {
30394
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useSquidTokens();
30992
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useSquidTokens();
30395
30993
  const getTokensForChainType = () => {
30396
30994
  if (!chain?.chainType)
30397
30995
  return [];
@@ -30412,8 +31010,6 @@ function useNativeTokenForChain(chain) {
30412
31010
  return stellarTokens;
30413
31011
  case ChainType.CANTON:
30414
31012
  return cantonTokens;
30415
- case ChainType.DANAL:
30416
- return danalTokens;
30417
31013
  }
30418
31014
  };
30419
31015
  const nativeTokenForChainType = useMemo(() => {
@@ -30674,9 +31270,6 @@ const useNativeBalance = (chain) => {
30674
31270
  case ChainType.CANTON:
30675
31271
  balance = nativeCantonBalance;
30676
31272
  break;
30677
- case ChainType.DANAL:
30678
- balance = undefined;
30679
- break;
30680
31273
  }
30681
31274
  const balanceFormatted = !!balance
30682
31275
  ? formatBNToReadable(balance.value, balance.decimals)
@@ -30716,8 +31309,6 @@ const useNativeBalance = (chain) => {
30716
31309
  return isStellarLoading;
30717
31310
  case ChainType.CANTON:
30718
31311
  return isCantonLoading;
30719
- case ChainType.DANAL:
30720
- return false;
30721
31312
  }
30722
31313
  }, [
30723
31314
  chain?.chainType,
@@ -30943,7 +31534,7 @@ function hederaWalletConnect(parameters) {
30943
31534
  const optionalChains = config.chains.map((x) => x.id);
30944
31535
  if (!optionalChains.length)
30945
31536
  return;
30946
- const { EthereumProvider } = await import('./index.es-Dl19u5sy.js');
31537
+ const { EthereumProvider } = await import('./index.es-09IsADsA.js');
30947
31538
  const rawProvider = await EthereumProvider.init({
30948
31539
  ...restParameters,
30949
31540
  disableProviderPing: true,
@@ -31177,8 +31768,6 @@ const useSigner = ({ chain }) => {
31177
31768
  return isStellarSignerReady;
31178
31769
  case ChainType.CANTON:
31179
31770
  return isCantonSignerReady;
31180
- case ChainType.DANAL:
31181
- return false;
31182
31771
  }
31183
31772
  }, [
31184
31773
  chain?.chainType,
@@ -31631,12 +32220,8 @@ const useSendTransactionStore = create((set, get) => ({
31631
32220
  const useDepositAddressStore = create((set) => ({
31632
32221
  deposit: null,
31633
32222
  selectedPaymentMethod: "connectedWallet",
31634
- userDepositTxId: null,
31635
32223
  setDeposit: (data) => {
31636
- set({ deposit: data, userDepositTxId: null });
31637
- },
31638
- setUserDepositTxId: (txId) => {
31639
- set({ userDepositTxId: txId });
32224
+ set({ deposit: data });
31640
32225
  },
31641
32226
  setPaymentMethod: (method) => {
31642
32227
  set({ selectedPaymentMethod: method });
@@ -31648,7 +32233,7 @@ function useDepositAddress(squidRoute) {
31648
32233
  selectedPaymentMethod: state.selectedPaymentMethod,
31649
32234
  depositAddress: state.deposit?.depositAddress,
31650
32235
  }));
31651
- const { setDeposit, setPaymentMethod, deposit, userDepositTxId, setUserDepositTxId, } = useDepositAddressStore();
32236
+ const { setDeposit, setPaymentMethod, deposit } = useDepositAddressStore();
31652
32237
  const { squid } = useSquidStore();
31653
32238
  const { fromChain } = useSwap();
31654
32239
  const isAvailableAsPaymentMethod = useMemo(() => {
@@ -31658,13 +32243,11 @@ function useDepositAddress(squidRoute) {
31658
32243
  CHAIN_IDS.BITCOIN,
31659
32244
  CHAIN_IDS.SOLANA,
31660
32245
  CHAIN_IDS.CANTON,
31661
- CHAIN_IDS.DANAL_TESTNET,
31662
32246
  ];
31663
32247
  return chainsSupportingDepositAddress.includes(fromChain.chainId);
31664
32248
  }, [fromChain?.chainId]);
31665
- const routeProvidesDirectDepositAddress = (!!squidRoute?.transactionRequest &&
31666
- isDepositAddressDirectTransferRoute(squidRoute.transactionRequest)) ||
31667
- (!!squidRoute && isDanalDepositRoute(squidRoute));
32249
+ const routeProvidesDirectDepositAddress = !!squidRoute?.transactionRequest &&
32250
+ isDepositAddressDirectTransferRoute(squidRoute.transactionRequest);
31668
32251
  const swapWillGenerateDepositAddress = isChainflipDepositRoute(squidRoute) || routeProvidesDirectDepositAddress;
31669
32252
  const paymentMethod = isAvailableAsPaymentMethod
31670
32253
  ? selectedPaymentMethod
@@ -31690,19 +32273,6 @@ function useDepositAddress(squidRoute) {
31690
32273
  });
31691
32274
  return;
31692
32275
  }
31693
- else if (isDanalDepositRoute(route)) {
31694
- const transferBody = parseDanalTransferBody(route.transactionRequest.data);
31695
- if (!transferBody) {
31696
- throw new Error("Could not parse Danal transfer request body");
31697
- }
31698
- setDeposit({
31699
- amount: transferBody.amount,
31700
- depositAddress: route.transactionRequest.target,
31701
- statusTrackingId: transferBody.memo,
31702
- memo: transferBody.memo,
31703
- });
31704
- return;
31705
- }
31706
32276
  else if (isDepositAddressDirectTransferRoute(route.transactionRequest)) {
31707
32277
  // Canton case
31708
32278
  const orderHash = route.transactionRequest.data;
@@ -31725,8 +32295,6 @@ function useDepositAddress(squidRoute) {
31725
32295
  depositAddress,
31726
32296
  closeDepositChannel,
31727
32297
  depositData: deposit,
31728
- userDepositTxId,
31729
- setUserDepositTxId,
31730
32298
  };
31731
32299
  }
31732
32300
 
@@ -31754,7 +32322,7 @@ const useUrlSwapParams = () => {
31754
32322
 
31755
32323
  const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, queryOptions, }) => {
31756
32324
  const { evmChains, cosmosChains, suiChains, xrplChains, stellarChains } = useSquidChains(direction);
31757
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useSquidTokens(direction);
32325
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useSquidTokens(direction);
31758
32326
  const { keplrTypeWallet } = useCosmosContext();
31759
32327
  const cantonConnector = useWalletStore((store) => store.connectedWalletsByChainType[ChainType.CANTON]?.wallet?.connector);
31760
32328
  const placeholderData = useMemo(() => {
@@ -31767,7 +32335,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31767
32335
  [ChainType.XRPL]: xrplTokens.map((t) => ({ ...t, balance: "0" })),
31768
32336
  [ChainType.STELLAR]: stellarTokens.map((t) => ({ ...t, balance: "0" })),
31769
32337
  [ChainType.CANTON]: cantonTokens.map((t) => ({ ...t, balance: "0" })),
31770
- [ChainType.DANAL]: danalTokens.map((t) => ({ ...t, balance: "0" })),
31771
32338
  };
31772
32339
  if (!chainType) {
31773
32340
  // Return all tokens with zero balance
@@ -31790,7 +32357,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31790
32357
  xrplTokens,
31791
32358
  stellarTokens,
31792
32359
  cantonTokens,
31793
- danalTokens,
31794
32360
  ]);
31795
32361
  const isQueryEnabled = useMemo(() => {
31796
32362
  // Respect the queryOptions.enabled override if provided
@@ -31815,8 +32381,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31815
32381
  return stellarTokens.length > 0;
31816
32382
  case ChainType.CANTON:
31817
32383
  return cantonTokens.length > 0;
31818
- case ChainType.DANAL:
31819
- return danalTokens.length > 0;
31820
32384
  }
31821
32385
  }, [
31822
32386
  chainType,
@@ -31830,7 +32394,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31830
32394
  xrplTokens.length,
31831
32395
  stellarTokens.length,
31832
32396
  cantonTokens.length,
31833
- danalTokens.length,
31834
32397
  ]);
31835
32398
  const query = useQuery(keys().allTokensBalance(address, chainType, direction), async () => {
31836
32399
  // Return zero balances if no address
@@ -31955,12 +32518,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31955
32518
  direction,
31956
32519
  queryOptions,
31957
32520
  });
31958
- const danalBalancesQuery = useAllTokensWithBalanceForChainType({
31959
- chainType: ChainType.DANAL,
31960
- address: connectedAddresses?.[ChainType.DANAL],
31961
- direction,
31962
- queryOptions,
31963
- });
31964
32521
  // Create a map of chain type to balance query results
31965
32522
  const balanceQueries = useMemo(() => ({
31966
32523
  [ChainType.EVM]: evmBalancesQuery,
@@ -31971,7 +32528,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31971
32528
  [ChainType.XRPL]: xrplBalancesQuery,
31972
32529
  [ChainType.STELLAR]: stellarBalancesQuery,
31973
32530
  [ChainType.CANTON]: cantonBalancesQuery,
31974
- [ChainType.DANAL]: danalBalancesQuery,
31975
32531
  }), [
31976
32532
  evmBalancesQuery,
31977
32533
  cosmosBalancesQuery,
@@ -31981,7 +32537,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31981
32537
  xrplBalancesQuery,
31982
32538
  stellarBalancesQuery,
31983
32539
  cantonBalancesQuery,
31984
- danalBalancesQuery,
31985
32540
  ]);
31986
32541
  // Combine all tokens from different chains
31987
32542
  const allTokens = useMemo(() => Object.values(balanceQueries).flatMap((query) => query.data?.tokens ?? []), [balanceQueries]);
@@ -32089,8 +32644,6 @@ const useMultiChainBalance = ({ chain, token, userAddress, enabled = true, }) =>
32089
32644
  return stellarBalance;
32090
32645
  case ChainType.CANTON:
32091
32646
  return cantonBalance;
32092
- case ChainType.DANAL:
32093
- return "0";
32094
32647
  }
32095
32648
  }, [
32096
32649
  chain?.chainType,
@@ -33200,9 +33753,8 @@ function useSendTransaction({ to, amount, token, chain, }) {
33200
33753
  chain,
33201
33754
  });
33202
33755
  break;
33203
- case ChainType.CANTON:
33204
- case ChainType.DANAL: {
33205
- throw new Error(`Send not implemented for chain type ${chain.chainType}`);
33756
+ case ChainType.CANTON: {
33757
+ throw new Error("Not implemented");
33206
33758
  }
33207
33759
  }
33208
33760
  return {
@@ -33408,8 +33960,7 @@ async function getSendTransactionStatus({ chain, txHash, }) {
33408
33960
  chain,
33409
33961
  });
33410
33962
  case ChainType.CANTON:
33411
- case ChainType.DANAL:
33412
- throw new Error(`Send not implemented for chain type ${chain.chainType}`);
33963
+ throw new Error("Not implemented");
33413
33964
  }
33414
33965
  }
33415
33966
 
@@ -37030,342 +37581,6 @@ coin.DecProto = {
37030
37581
 
37031
37582
  } (tx));
37032
37583
 
37033
- const vParty = (party) => ({ party });
37034
- const vText = (text) => ({ text });
37035
- const vNumeric = (numeric) => ({ numeric });
37036
- const vContractId = (contractId) => ({
37037
- contractId,
37038
- });
37039
- const vList = (elements) => ({
37040
- list: { elements },
37041
- });
37042
- const vRecord = (fields) => ({
37043
- record: { fields: fields.map(([label, value]) => ({ label, value })) },
37044
- });
37045
- const vTextMap = (entries) => ({ textMap: { entries } });
37046
- const vTimestamp = (isoString) => ({
37047
- timestamp: String(Math.floor(new Date(isoString).getTime() * 1000)),
37048
- });
37049
- function isRecord(value) {
37050
- return typeof value === "object" && value !== null && !Array.isArray(value);
37051
- }
37052
- function normalizeChoiceContextValue(value) {
37053
- if (typeof value === "string")
37054
- return value;
37055
- if (!isRecord(value) || typeof value.tag !== "string")
37056
- return null;
37057
- switch (value.tag) {
37058
- case "AV_Text":
37059
- case "AV_ContractId":
37060
- return typeof value.value === "string"
37061
- ? { tag: value.tag, value: value.value }
37062
- : null;
37063
- case "AV_Bool":
37064
- return typeof value.value === "boolean"
37065
- ? { tag: value.tag, value: value.value }
37066
- : null;
37067
- case "AV_List":
37068
- if (!Array.isArray(value.value))
37069
- return null;
37070
- return {
37071
- tag: value.tag,
37072
- value: value.value.flatMap((entry) => {
37073
- const normalized = normalizeChoiceContextValue(entry);
37074
- return normalized ? [normalized] : [];
37075
- }),
37076
- };
37077
- default: {
37078
- const inner = value.value;
37079
- if (typeof inner === "string" ||
37080
- typeof inner === "number" ||
37081
- typeof inner === "boolean" ||
37082
- inner === null) {
37083
- return { tag: value.tag, value: inner };
37084
- }
37085
- if (Array.isArray(inner)) {
37086
- return {
37087
- tag: value.tag,
37088
- value: inner.flatMap((entry) => {
37089
- const normalized = normalizeChoiceContextValue(entry);
37090
- return normalized ? [normalized] : [];
37091
- }),
37092
- };
37093
- }
37094
- if (!isRecord(inner))
37095
- return null;
37096
- const normalizedObject = {};
37097
- for (const [key, entry] of Object.entries(inner)) {
37098
- if (typeof entry !== "string" &&
37099
- typeof entry !== "number" &&
37100
- typeof entry !== "boolean" &&
37101
- entry !== null) {
37102
- return null;
37103
- }
37104
- normalizedObject[key] = entry;
37105
- }
37106
- return { tag: value.tag, value: normalizedObject };
37107
- }
37108
- }
37109
- }
37110
- function stringifyChoiceContextValue(value) {
37111
- return typeof value === "string" ? value : String(value);
37112
- }
37113
- function choiceContextValueToAnyValue(value) {
37114
- if (typeof value === "string") {
37115
- return {
37116
- variant: { constructor: "AV_Text", value: vText(value) },
37117
- };
37118
- }
37119
- switch (value.tag) {
37120
- case "AV_ContractId":
37121
- if (typeof value.value !== "string") {
37122
- throw new TypeError("AV_ContractId values must be strings");
37123
- }
37124
- return {
37125
- variant: { constructor: value.tag, value: vContractId(value.value) },
37126
- };
37127
- case "AV_Bool":
37128
- if (typeof value.value !== "boolean") {
37129
- throw new TypeError("AV_Bool values must be booleans");
37130
- }
37131
- return {
37132
- variant: { constructor: value.tag, value: { bool: value.value } },
37133
- };
37134
- case "AV_List":
37135
- if (!Array.isArray(value.value)) {
37136
- throw new TypeError("AV_List values must be arrays");
37137
- }
37138
- return {
37139
- variant: {
37140
- constructor: value.tag,
37141
- value: vList(value.value.map(choiceContextValueToAnyValue)),
37142
- },
37143
- };
37144
- default:
37145
- return {
37146
- variant: {
37147
- constructor: value.tag,
37148
- value: vText(stringifyChoiceContextValue(value.value)),
37149
- },
37150
- };
37151
- }
37152
- }
37153
-
37154
- /** Metadata key used by Splice token-standard transfers to carry our Squid orderhash memo. */
37155
- const CANTON_MEMO_KEY = "splice.lfdecentralizedtrust.org/reason";
37156
- /** Interface id for the transfer factory contract returned by the token registry. */
37157
- const TRANSFER_FACTORY_INTERFACE_ID = "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory";
37158
- /** Choice exercised on the transfer factory to create the token-standard transfer. */
37159
- const TRANSFER_FACTORY_CHOICE = "TransferFactory_Transfer";
37160
- /** CIP-056 (non-Amulet) tokens expose a registrar parameterized by admin party. */
37161
- const CIP056_REGISTRAR_BASE = "https://api.utilities.digitalasset.com/api/token-standard/v0/registrars";
37162
- const TRANSFER_REQUESTED_AT_SKEW_MS = 60_000;
37163
- const TRANSFER_EXECUTE_WINDOW_MS = 24 * 60 * 60 * 1000;
37164
- function resolveCantonRegistryUrl(instrument) {
37165
- if (instrument.id === CANTON_AMULET_INSTRUMENT_ID) {
37166
- return CANTON_AMULET_REGISTRY_URL;
37167
- }
37168
- return `${CIP056_REGISTRAR_BASE}/${encodeURIComponent(instrument.admin)}`;
37169
- }
37170
- /**
37171
- * Build the plain JSON arguments expected by the registry transfer-factory
37172
- * endpoint before it adds choice context and disclosed contracts.
37173
- */
37174
- function buildTransferChoiceArgs({ sender, receiver, amount, instrument, inputHoldingCids, memo, nowMs, }) {
37175
- return {
37176
- expectedAdmin: instrument.admin,
37177
- transfer: {
37178
- sender,
37179
- receiver,
37180
- amount,
37181
- instrumentId: { admin: instrument.admin, id: instrument.id },
37182
- requestedAt: new Date(nowMs - TRANSFER_REQUESTED_AT_SKEW_MS).toISOString(),
37183
- executeBefore: new Date(nowMs + TRANSFER_EXECUTE_WINDOW_MS).toISOString(),
37184
- inputHoldingCids,
37185
- meta: { values: { [CANTON_MEMO_KEY]: memo } },
37186
- },
37187
- extraArgs: { context: { values: {} }, meta: { values: {} } },
37188
- };
37189
- }
37190
- /**
37191
- * Canton's Holding contracts follow Bitcoin-style UTXOs model.
37192
- *
37193
- * Pick Holding contract ids covering `amount` for the instrument: prefer a
37194
- * single exact-amount holding, else accumulate largest-first.
37195
- */
37196
- function selectInputHoldingCids(holdings, instrument, amount) {
37197
- const spendableHoldings = holdings.filter((h) => !h.locked &&
37198
- h.instrument.admin === instrument.admin &&
37199
- h.instrument.id === instrument.id);
37200
- const target = new BigNumber(amount);
37201
- const exact = spendableHoldings.find((h) => new BigNumber(h.amount).eq(target));
37202
- if (exact)
37203
- return [exact.contractId];
37204
- const sorted = [...spendableHoldings].sort((a, b) => new BigNumber(b.amount).comparedTo(new BigNumber(a.amount)));
37205
- const selected = [];
37206
- let sum = new BigNumber(0);
37207
- for (const holding of sorted) {
37208
- selected.push(holding.contractId);
37209
- sum = sum.plus(holding.amount);
37210
- if (sum.gte(target))
37211
- break;
37212
- }
37213
- if (sum.lt(target)) {
37214
- throw new Error("Insufficient Canton holdings to cover transfer amount");
37215
- }
37216
- return selected;
37217
- }
37218
- async function fetchInputHoldingCids(connector, party, instrument, amount) {
37219
- const ledgerEnd = await connector.ledgerApi({
37220
- requestMethod: "get",
37221
- resource: "/v2/state/ledger-end",
37222
- });
37223
- const activeContracts = await connector.ledgerApi({
37224
- requestMethod: "post",
37225
- resource: "/v2/state/active-contracts",
37226
- body: buildHoldingsAcsRequestBody(party, String(ledgerEnd.offset)),
37227
- });
37228
- return selectInputHoldingCids(parseCantonHoldings(activeContracts), instrument, amount);
37229
- }
37230
- /**
37231
- * Ask the token registry for the transfer factory contract and extra context
37232
- * required to exercise its transfer choice.
37233
- */
37234
- async function fetchTransferFactory(registryUrl, choiceArgs) {
37235
- const response = await fetch(`${registryUrl}/registry/transfer-instruction/v1/transfer-factory`, {
37236
- method: "POST",
37237
- headers: { "Content-Type": "application/json" },
37238
- body: JSON.stringify({
37239
- choiceArguments: choiceArgs,
37240
- excludeDebugFields: true,
37241
- }),
37242
- });
37243
- if (!response.ok) {
37244
- throw new Error(`Canton transfer-factory request failed (${response.status})`);
37245
- }
37246
- return response.json();
37247
- }
37248
- /**
37249
- * Convert transfer choice args into strict Daml Value JSON for the wallet's
37250
- * prepareExecute ExerciseCommand.
37251
- */
37252
- function buildPrepareChoiceArgument(choiceArgs) {
37253
- const contextValues = Object.entries(choiceArgs.extraArgs.context?.values ?? {})
37254
- .map(([key, value]) => {
37255
- const normalized = normalizeChoiceContextValue(value);
37256
- return normalized
37257
- ? { key, value: choiceContextValueToAnyValue(normalized) }
37258
- : undefined;
37259
- })
37260
- .filter((entry) => Boolean(entry));
37261
- return vRecord([
37262
- ["expectedAdmin", vParty(choiceArgs.expectedAdmin)],
37263
- [
37264
- "transfer",
37265
- vRecord([
37266
- ["sender", vParty(choiceArgs.transfer.sender)],
37267
- ["receiver", vParty(choiceArgs.transfer.receiver)],
37268
- ["amount", vNumeric(choiceArgs.transfer.amount)],
37269
- [
37270
- "instrumentId",
37271
- vRecord([
37272
- ["admin", vParty(choiceArgs.transfer.instrumentId.admin)],
37273
- ["id", vText(choiceArgs.transfer.instrumentId.id)],
37274
- ]),
37275
- ],
37276
- ["requestedAt", vTimestamp(choiceArgs.transfer.requestedAt)],
37277
- ["executeBefore", vTimestamp(choiceArgs.transfer.executeBefore)],
37278
- [
37279
- "inputHoldingCids",
37280
- vList(choiceArgs.transfer.inputHoldingCids.map(vContractId)),
37281
- ],
37282
- [
37283
- "meta",
37284
- vRecord([
37285
- [
37286
- "values",
37287
- vTextMap(Object.entries(choiceArgs.transfer.meta.values).map(([key, value]) => ({ key, value: vText(value) }))),
37288
- ],
37289
- ]),
37290
- ],
37291
- ]),
37292
- ],
37293
- [
37294
- "extraArgs",
37295
- vRecord([
37296
- ["context", vRecord([["values", vTextMap(contextValues)]])],
37297
- ["meta", vRecord([["values", vTextMap([])]])],
37298
- ]),
37299
- ],
37300
- ]);
37301
- }
37302
- /**
37303
- * Convert a registry disclosed contract into the wallet submission shape,
37304
- * dropping debug fields and entries without a usable createdEventBlob.
37305
- */
37306
- function toDisclosedContract(raw) {
37307
- if (typeof raw.createdEventBlob !== "string")
37308
- return null;
37309
- return {
37310
- createdEventBlob: raw.createdEventBlob,
37311
- contractId: typeof raw.contractId === "string" ? raw.contractId : undefined,
37312
- synchronizerId: typeof raw.synchronizerId === "string" ? raw.synchronizerId : undefined,
37313
- };
37314
- }
37315
- /**
37316
- * Build a Splice token-standard transfer of `amount` of `token` from `sender`
37317
- * to `receiver`, carrying `memo`, ready to hand to a wallet's prepareExecute.
37318
- * Returns the full prepareExecute params (commandId + commands + actAs +
37319
- * disclosedContracts).
37320
- */
37321
- async function buildCantonTransfer(connector, { sender, receiver, amount, token, memo, nowMs, }) {
37322
- if (!token.originalAddress) {
37323
- throw new Error("Canton token originalAddress is required");
37324
- }
37325
- const instrument = parseCantonInstrument(token.originalAddress);
37326
- if (!instrument) {
37327
- throw new Error(`Invalid Canton token address: ${token.originalAddress}`);
37328
- }
37329
- const registryUrl = resolveCantonRegistryUrl(instrument);
37330
- const inputHoldingCids = await fetchInputHoldingCids(connector, sender, instrument, amount);
37331
- const choiceArgs = buildTransferChoiceArgs({
37332
- sender,
37333
- receiver,
37334
- amount,
37335
- instrument,
37336
- inputHoldingCids,
37337
- memo,
37338
- nowMs,
37339
- });
37340
- const factory = await fetchTransferFactory(registryUrl, choiceArgs);
37341
- const choiceContextData = factory.choiceContext.choiceContextData;
37342
- if (!choiceContextData) {
37343
- throw new Error("Transfer factory choice context is missing");
37344
- }
37345
- choiceArgs.extraArgs.context = choiceContextData;
37346
- const disclosedContracts = (factory.choiceContext?.disclosedContracts ?? []).flatMap((raw) => {
37347
- const disclosedContract = toDisclosedContract(raw);
37348
- return disclosedContract ? [disclosedContract] : [];
37349
- });
37350
- // Command ID: client-supplied identifier used to deduplicate submissions
37351
- const commandId = `canton-${memo}`;
37352
- return {
37353
- commandId,
37354
- commands: [
37355
- {
37356
- ExerciseCommand: {
37357
- templateId: TRANSFER_FACTORY_INTERFACE_ID,
37358
- contractId: factory.factoryId,
37359
- choice: TRANSFER_FACTORY_CHOICE,
37360
- choiceArgument: buildPrepareChoiceArgument(choiceArgs),
37361
- },
37362
- },
37363
- ],
37364
- actAs: [sender],
37365
- disclosedContracts,
37366
- };
37367
- }
37368
-
37369
37584
  const useExecuteTransaction = (squidRoute) => {
37370
37585
  const { fromChain, toChain, fromToken, toToken, isSameChain } = useSwap();
37371
37586
  // A route completes on source tx only if it's same-chain AND
@@ -37980,7 +38195,7 @@ const useExecuteTransaction = (squidRoute) => {
37980
38195
  }
37981
38196
  const amount = formatBNToReadable(fromAmount, token.decimals);
37982
38197
  dispatchSignatureRequestEvent(route);
37983
- const transferParams = await buildCantonTransfer(cantonSigner, {
38198
+ const result = await cantonSigner.transfer({
37984
38199
  sender: sourceUserAddress,
37985
38200
  receiver,
37986
38201
  amount,
@@ -37988,15 +38203,14 @@ const useExecuteTransaction = (squidRoute) => {
37988
38203
  memo: orderHash,
37989
38204
  nowMs: Date.now(),
37990
38205
  });
37991
- const result = await cantonSigner.prepareExecuteAndWait(transferParams);
37992
- const txHash = result.tx?.payload?.updateId ?? "";
38206
+ const txHash = result.updateId;
37993
38207
  if (txHash) {
37994
38208
  resetQueriesAfterTxSigned();
37995
38209
  }
37996
38210
  WidgetEvents.getInstance().dispatchSwapExecuteCall(route, txHash);
37997
38211
  const txParams = setTransactionState({
37998
38212
  route,
37999
- txHash: txHash,
38213
+ txHash,
38000
38214
  userAddress: sourceUserAddress,
38001
38215
  status: TransactionStatus.INITIAL_LOADING,
38002
38216
  sourceStatus: TransactionStatus.ONGOING,
@@ -38279,7 +38493,7 @@ refetchIntervalInBackground = false, refetchInterval = 30000, quoteOnly = true,
38279
38493
  //
38280
38494
  // If deposit address is not selected, we use the connected address as the source address instead
38281
38495
  const sourceUserAddress = isDepositAddressActive
38282
- ? depositRefundAddress ?? sourceConnectedAddress
38496
+ ? (depositRefundAddress ?? sourceConnectedAddress)
38283
38497
  : sourceConnectedAddress;
38284
38498
  const squidRouteQueryKeys = useMemo(() => keys().transaction(fromChain?.chainId, toChain?.chainId, toToken?.address, fromToken?.address, fromPrice, config.slippage, sourceUserAddress, config.degenMode, destinationAddress, fallbackAddress, quoteOnly, fromChain?.chainType, config.preHook, config.postHook, config.overrideGasRefundAddress), [
38285
38499
  fromChain?.chainId,
@@ -38571,6 +38785,10 @@ const useAutoConnect = () => {
38571
38785
  const { chains } = useSquidChains();
38572
38786
  const { isInitialized } = useConfigStore();
38573
38787
  const hasAttemptedReconnect = useRef(false);
38788
+ const hasAttemptedCantonReconnect = useRef(false);
38789
+ const { autoConnectCanton, wallets: cantonWallets } = useCantonContext();
38790
+ const recentCantonWalletId = useWalletStore((state) => state.recentConnectorIds[ChainType.CANTON]);
38791
+ const hasRecentCantonWallet = cantonWallets.some((wallet) => wallet.connectorId === recentCantonWalletId);
38574
38792
  const { autoConnectEvm } = useEvmContext();
38575
38793
  const { autoConnectSolana } = useSolanaContext();
38576
38794
  const { autoConnectSui } = useSuiContext();
@@ -38638,6 +38856,15 @@ const useAutoConnect = () => {
38638
38856
  useEffect(() => {
38639
38857
  autoConnect();
38640
38858
  }, [autoConnect]);
38859
+ useEffect(() => {
38860
+ if (!isInitialized ||
38861
+ chains.length === 0 ||
38862
+ !hasRecentCantonWallet ||
38863
+ hasAttemptedCantonReconnect.current)
38864
+ return;
38865
+ hasAttemptedCantonReconnect.current = true;
38866
+ autoConnectCanton().catch(() => undefined);
38867
+ }, [autoConnectCanton, hasRecentCantonWallet, isInitialized, chains.length]);
38641
38868
  return { autoConnect };
38642
38869
  };
38643
38870
 
@@ -38946,5 +39173,5 @@ const SquidProvider = ({ children, config, placeholder, }) => {
38946
39173
  React.createElement(CosmosProvider, null, children))))))))))) : (placeholder);
38947
39174
  };
38948
39175
 
38949
- export { useWalletStore as $, AxelarStatusResponseType as A, useHederaAccountActivation as B, CHAIN_IDS as C, DEFAULT_LOCALE as D, useHederaTokenAssociations as E, useKeyboardNavigation as F, useSquidQueryClient as G, HistoryTxType as H, useSquid as I, useStellarAccountActivation as J, useStellarTrustLine as K, useAddressBookStore as L, useAssetsColorsStore as M, Nr as N, useFavoriteTokensStore as O, useHistoryStore as P, QueryKeys as Q, useSendTransactionStore as R, SquidStatusErrorType as S, TransactionErrorType as T, useConfigStore as U, useSquidStore as V, Wo as W, XamanXrplNetwork as X, useSwapRoutePersistStore as Y, useTransactionStore as Z, ConnectingWalletStatus as _, WindowWalletFlag as a, useAvailableQuotes as a$, useDepositAddress as a0, useSwap as a1, buildUrlSearchParamsFromSwapEvent as a2, parseInitialAssetsFromUrl as a3, useUrlSwapParams as a4, useAllConnectedWalletBalances as a5, useAllTokensWithBalanceForChainType as a6, useCosmosBalance as a7, useEvmBalance as a8, useMultiChainBalance as a9, useRouteWarnings as aA, useSendTransactionStatus as aB, useSwapTransactionStatus as aC, useAvatar as aD, useHistory as aE, useDebouncedValue as aF, useAddToken as aG, useAutoConnect as aH, useEnsDataForAddress as aI, useEnsSearch as aJ, useGnosisContext as aK, useIsSameAddressAndGnosisContext as aL, useIntegratorContext as aM, useMultiChainWallet as aN, useSigner as aO, useWallet as aP, useWallets as aQ, useXrplTrustLine as aR, TX_STATUS_CONSTANTS as aS, FINAL_TRANSACTION_STATUSES as aT, useGetFiatQuote as aU, useGetOnRampConfig as aV, useExecuteFiatQuote as aW, useFiatOnRampTxStatus as aX, useFiatTransactions as aY, useCurrencyDetails as aZ, useCountryDetails as a_, useMultipleTokenPrices as aa, useBitcoinNativeBalance as ab, useCosmosNativeBalance as ac, useEvmNativeBalance as ad, useNativeBalance as ae, useSolanaNativeBalance as af, useStellarNativeBalance as ag, useSuiNativeBalance as ah, useXrplNativeBalance as ai, useNativeTokenForChain as aj, useSingleTokenPrice as ak, useSourceChainGasToken as al, useSquidTokens as am, useHistoricalData as an, useTokensData as ao, useEstimateSendTransaction as ap, useSendTransaction as aq, useSendTransactionGas as ar, useAllTransactionsStatus as as, useApproval as at, useDepositTransactionStatus as au, useEstimate as av, useEstimatePriceImpact as aw, useExecuteTransaction as ax, useGetRoute as ay, useGetRouteWrapper as az, DEFAULT_ROUTE_REFETCH_INTERVAL as b, createQuoteRequestParamsHash as b$, useRecommendedQuote as b0, useGetOnrampPaymentTypes as b1, useSuggestedFiatAmounts as b2, SquidProvider as b3, EnsService as b4, getXummClient as b5, isXamanXAppContext as b6, getQueryHeaders as b7, getStatusCode as b8, is404Error as b9, randomIntFromInterval as bA, getTokensForChain as bB, getFirstAvailableChainId as bC, fetchHighestBalanceToken as bD, getInitialOrDefaultTokenAddressForChain as bE, getInitialTokenAddressForChain as bF, filterTokensForDestination as bG, getInitialChainIdFromConfig as bH, getCosmosKey as bI, getKeysSettled as bJ, getAllKeysForSupportedCosmosChains as bK, isCosmosAddressValid as bL, getCosmosSigningClient as bM, getCosmosChainInfosObject as bN, connectCosmosWallet as bO, isFallbackAddressNeeded as bP, suggestChainOrThrow as bQ, isDanalAddressValid as bR, isDanalTxHashValid as bS, parseDanalTransferBody as bT, normalizeError as bU, transactionErrorCode as bV, isUserRejectionError as bW, getTransactionError as bX, handleTransactionErrorEvents as bY, isSwapRouteError as bZ, isStatusError as b_, assetsBaseUrl as ba, shareSubgraphId as bb, sortTokensBySharedSubgraphIds as bc, getSupportedChainIdsForDirection as bd, filterChains as be, filterTokens as bf, getTokenImage as bg, getNewSwapParamsFromInput as bh, sortAllTokens as bi, findToken as bj, findNativeToken as bk, normalizeIbcAddress as bl, groupTokensBySymbol as bm, groupTokensByChainId as bn, filterViewableTokens as bo, getSecretNetworkBalances as bp, getTokenAssetsKey as bq, fetchAssetsColors as br, isSupportedChainType as bs, initializeSquidData as bt, isEmptyObject as bu, normalizeTokenSymbol as bv, areTokenSymbolsCompatible as bw, isEvmosChain as bx, resolveChainIdFromAsset as by, getConfigWithDefaults as bz, chainTypeToNativeTokenAddressMap as c, getHalfSuccessState as c$, WidgetEvents as c0, EvmNetworkNotSupportedErrorCode as c1, addEthereumChain as c2, parseEvmAddress as c3, formatEvmWallet as c4, filterWagmiConnector as c5, waitForReceiptWithRetry as c6, getUserCountry as c7, getCountryData as c8, getCurrencyData as c9, stellarAddressToScVal as cA, getStellarTrustLineAsset as cB, isStellarToken as cC, isStellarIssuedToken as cD, getStellarHorizonApiUrl as cE, isValidIssuedAsset as cF, isValidHorizonAsset as cG, formatTransactionHistoryDate as cH, getAxelarExplorerTxUrl as cI, getSourceExplorerTxUrl as cJ, getMainExplorerUrl as cK, formatDistance as cL, formatSeconds as cM, formatSwapTxStatusResponseForStorage as cN, simplifyRouteAction as cO, fetchSwapTransactionStatus as cP, compareTransactionIds as cQ, isCoralBridgeAction as cR, isActionCompletedOnSourceTx as cS, sleep as cT, isChainflipDepositRoute as cU, isChainflipBridgeTransaction as cV, isOnChainTxData as cW, isDepositAddressDirectTransferRoute as cX, isDanalDepositRoute as cY, getHistoryTransactionId as cZ, getStepStatuses as c_, adaptiveRound as ca, getSuggestedAmountsForCurrency as cb, HederaExtensionHelper as cc, convertHederaAccountIdToEvmAddress as cd, convertEvmAddressToHederaAccountId as ce, scaleHbarToWei as cf, scaleWeiToHbar as cg, parseToBigInt as ch, roundNumericValue as ci, formatUnitsRounded as cj, formatTokenAmount as ck, formatUsdAmount as cl, trimExtraDecimals as cm, getNumericValue as cn, cleanAmount as co, convertTokenAmountToUSD as cp, convertUSDToTokenAmount as cq, calculateTotal24hChange as cr, getRouteExpiry as cs, searchTokens as ct, filterSolanaWallets as cu, isSolanaAddressValid as cv, executeSolanaSwap as cw, executeSolanaTransfer as cx, isStellarAddressValid as cy, getStellarNetwork as cz, definedInWindow as d, getStepsInfos as d0, getSwapTxStatusRefetchInterval as d1, getSendTxStatusRefetchInterval as d2, chainflipMultihopBridgeType as d3, getBridgeType as d4, getTransactionStatus as d5, getTransactionEndStatus as d6, isHistoryTransactionPending as d7, isHistoryTransactionFailed as d8, isHistoryTransactionWarning as d9, parseXrplTokenAddress as dA, isHistoryTransactionEnded as da, formatHash as db, isWalletAddressValid as dc, redirectToExtensionsStore as dd, populateWallets as de, buildFallbackWallets as df, getDefaultChain as dg, sortWallets as dh, areSameAddress as di, sortAddressBook as dj, calculateTotalUsdBalanceUSD as dk, addTokenToWallet as dl, isEvmChainNotSupportedError as dm, getWalletSupportedChainTypes as dn, getConnectorForChainType as dp, walletSupportsChainType as dq, connectWallet as dr, cancelConnectWallet as ds, isProblematicConnector as dt, mergeWallets as du, isXionSmartContractAddress as dv, isXrplAddressValid as dw, buildXrplTrustSetTx as dx, getXrplNetwork as dy, parseXrplPaymentTx as dz, er as e, formatBNToReadable as f, chainTypeToZeroAddressMap as g, destinationAddressResetValue as h, fallbackAddressResetValue as i, nativeCantonTokenAddress as j, nativeCosmosTokenAddress as k, nativeEvmTokenAddress as l, nativeSolanaTokenAddress as m, nativeBitcoinTokenAddress as n, nativeStellarTokenAddress as o, nativeSuiTokenAddress as p, nativeXrplTokenAddress as q, CosmosProvider as r, SendTransactionStatus as s, TransactionStatus as t, useCosmosContext as u, useTrackSearchEmpty as v, walletIconBaseUrl as w, useSquidChains as x, useClient as y, useCosmosForChain as z };
38950
- //# sourceMappingURL=index-D6rznmR_.js.map
39176
+ export { useWalletStore as $, AxelarStatusResponseType as A, useHederaAccountActivation as B, CHAIN_IDS as C, DEFAULT_LOCALE as D, useHederaTokenAssociations as E, useKeyboardNavigation as F, useSquidQueryClient as G, HistoryTxType as H, useSquid as I, useStellarAccountActivation as J, useStellarTrustLine as K, useAddressBookStore as L, useAssetsColorsStore as M, Nr as N, useFavoriteTokensStore as O, useHistoryStore as P, QueryKeys as Q, useSendTransactionStore as R, SquidStatusErrorType as S, TransactionErrorType as T, useConfigStore as U, useSquidStore as V, Wo as W, XamanXrplNetwork as X, useSwapRoutePersistStore as Y, useTransactionStore as Z, ConnectingWalletStatus as _, WindowWalletFlag as a, useAvailableQuotes as a$, useDepositAddress as a0, useSwap as a1, buildUrlSearchParamsFromSwapEvent as a2, parseInitialAssetsFromUrl as a3, useUrlSwapParams as a4, useAllConnectedWalletBalances as a5, useAllTokensWithBalanceForChainType as a6, useCosmosBalance as a7, useEvmBalance as a8, useMultiChainBalance as a9, useRouteWarnings as aA, useSendTransactionStatus as aB, useSwapTransactionStatus as aC, useAvatar as aD, useHistory as aE, useDebouncedValue as aF, useAddToken as aG, useAutoConnect as aH, useEnsDataForAddress as aI, useEnsSearch as aJ, useGnosisContext as aK, useIsSameAddressAndGnosisContext as aL, useIntegratorContext as aM, useMultiChainWallet as aN, useSigner as aO, useWallet as aP, useWallets as aQ, useXrplTrustLine as aR, TX_STATUS_CONSTANTS as aS, FINAL_TRANSACTION_STATUSES as aT, useGetFiatQuote as aU, useGetOnRampConfig as aV, useExecuteFiatQuote as aW, useFiatOnRampTxStatus as aX, useFiatTransactions as aY, useCurrencyDetails as aZ, useCountryDetails as a_, useMultipleTokenPrices as aa, useBitcoinNativeBalance as ab, useCosmosNativeBalance as ac, useEvmNativeBalance as ad, useNativeBalance as ae, useSolanaNativeBalance as af, useStellarNativeBalance as ag, useSuiNativeBalance as ah, useXrplNativeBalance as ai, useNativeTokenForChain as aj, useSingleTokenPrice as ak, useSourceChainGasToken as al, useSquidTokens as am, useHistoricalData as an, useTokensData as ao, useEstimateSendTransaction as ap, useSendTransaction as aq, useSendTransactionGas as ar, useAllTransactionsStatus as as, useApproval as at, useDepositTransactionStatus as au, useEstimate as av, useEstimatePriceImpact as aw, useExecuteTransaction as ax, useGetRoute as ay, useGetRouteWrapper as az, DEFAULT_ROUTE_REFETCH_INTERVAL as b, addEthereumChain as b$, useRecommendedQuote as b0, useGetOnrampPaymentTypes as b1, useSuggestedFiatAmounts as b2, SquidProvider as b3, EnsService as b4, getXummClient as b5, isXamanXAppContext as b6, getQueryHeaders as b7, getStatusCode as b8, is404Error as b9, randomIntFromInterval as bA, getTokensForChain as bB, getFirstAvailableChainId as bC, fetchHighestBalanceToken as bD, getInitialOrDefaultTokenAddressForChain as bE, getInitialTokenAddressForChain as bF, filterTokensForDestination as bG, getInitialChainIdFromConfig as bH, getCosmosKey as bI, getKeysSettled as bJ, getAllKeysForSupportedCosmosChains as bK, isCosmosAddressValid as bL, getCosmosSigningClient as bM, getCosmosChainInfosObject as bN, connectCosmosWallet as bO, isFallbackAddressNeeded as bP, suggestChainOrThrow as bQ, normalizeError as bR, transactionErrorCode as bS, isUserRejectionError as bT, getTransactionError as bU, handleTransactionErrorEvents as bV, isSwapRouteError as bW, isStatusError as bX, createQuoteRequestParamsHash as bY, WidgetEvents as bZ, EvmNetworkNotSupportedErrorCode as b_, assetsBaseUrl as ba, shareSubgraphId as bb, sortTokensBySharedSubgraphIds as bc, getSupportedChainIdsForDirection as bd, filterChains as be, filterTokens as bf, getTokenImage as bg, getNewSwapParamsFromInput as bh, sortAllTokens as bi, findToken as bj, findNativeToken as bk, normalizeIbcAddress as bl, groupTokensBySymbol as bm, groupTokensByChainId as bn, filterViewableTokens as bo, getSecretNetworkBalances as bp, getTokenAssetsKey as bq, fetchAssetsColors as br, isSupportedChainType as bs, initializeSquidData as bt, isEmptyObject as bu, normalizeTokenSymbol as bv, areTokenSymbolsCompatible as bw, isEvmosChain as bx, resolveChainIdFromAsset as by, getConfigWithDefaults as bz, chainTypeToNativeTokenAddressMap as c, chainflipMultihopBridgeType as c$, parseEvmAddress as c0, formatEvmWallet as c1, filterWagmiConnector as c2, waitForReceiptWithRetry as c3, getUserCountry as c4, getCountryData as c5, getCurrencyData as c6, adaptiveRound as c7, getSuggestedAmountsForCurrency as c8, HederaExtensionHelper as c9, isStellarIssuedToken as cA, getStellarHorizonApiUrl as cB, isValidIssuedAsset as cC, isValidHorizonAsset as cD, formatTransactionHistoryDate as cE, getAxelarExplorerTxUrl as cF, getSourceExplorerTxUrl as cG, getMainExplorerUrl as cH, formatDistance as cI, formatSeconds as cJ, formatSwapTxStatusResponseForStorage as cK, simplifyRouteAction as cL, fetchSwapTransactionStatus as cM, compareTransactionIds as cN, isCoralBridgeAction as cO, isActionCompletedOnSourceTx as cP, sleep as cQ, isChainflipDepositRoute as cR, isChainflipBridgeTransaction as cS, isOnChainTxData as cT, isDepositAddressDirectTransferRoute as cU, getHistoryTransactionId as cV, getStepStatuses as cW, getHalfSuccessState as cX, getStepsInfos as cY, getSwapTxStatusRefetchInterval as cZ, getSendTxStatusRefetchInterval as c_, convertHederaAccountIdToEvmAddress as ca, convertEvmAddressToHederaAccountId as cb, scaleHbarToWei as cc, scaleWeiToHbar as cd, parseToBigInt as ce, roundNumericValue as cf, formatUnitsRounded as cg, formatTokenAmount as ch, formatUsdAmount as ci, trimExtraDecimals as cj, getNumericValue as ck, cleanAmount as cl, convertTokenAmountToUSD as cm, convertUSDToTokenAmount as cn, calculateTotal24hChange as co, getRouteExpiry as cp, searchTokens as cq, filterSolanaWallets as cr, isSolanaAddressValid as cs, executeSolanaSwap as ct, executeSolanaTransfer as cu, isStellarAddressValid as cv, getStellarNetwork as cw, stellarAddressToScVal as cx, getStellarTrustLineAsset as cy, isStellarToken as cz, definedInWindow as d, getBridgeType as d0, getTransactionStatus as d1, getTransactionEndStatus as d2, isHistoryTransactionPending as d3, isHistoryTransactionFailed as d4, isHistoryTransactionWarning as d5, isHistoryTransactionEnded as d6, formatHash as d7, isWalletAddressValid as d8, redirectToExtensionsStore as d9, populateWallets as da, buildFallbackWallets as db, getDefaultChain as dc, sortWallets as dd, areSameAddress as de, sortAddressBook as df, calculateTotalUsdBalanceUSD as dg, addTokenToWallet as dh, isEvmChainNotSupportedError as di, getWalletSupportedChainTypes as dj, getConnectorForChainType as dk, walletSupportsChainType as dl, connectWallet as dm, cancelConnectWallet as dn, isProblematicConnector as dp, mergeWallets as dq, isXionSmartContractAddress as dr, isXrplAddressValid as ds, buildXrplTrustSetTx as dt, getXrplNetwork as du, parseXrplPaymentTx as dv, parseXrplTokenAddress as dw, er as e, formatBNToReadable as f, chainTypeToZeroAddressMap as g, destinationAddressResetValue as h, fallbackAddressResetValue as i, nativeCantonTokenAddress as j, nativeCosmosTokenAddress as k, nativeEvmTokenAddress as l, nativeSolanaTokenAddress as m, nativeBitcoinTokenAddress as n, nativeStellarTokenAddress as o, nativeSuiTokenAddress as p, nativeXrplTokenAddress as q, CosmosProvider as r, SendTransactionStatus as s, TransactionStatus as t, useCosmosContext as u, useTrackSearchEmpty as v, walletIconBaseUrl as w, useSquidChains as x, useClient as y, useCosmosForChain as z };
39177
+ //# sourceMappingURL=index-C3owE9lb.js.map