@0xsquid/react-hooks 8.11.1-beta-danal.2 → 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 (55) 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/index.d.ts +1 -1
  8. package/dist/core/types/tokens.d.ts +1 -8
  9. package/dist/core/types/wallet.d.ts +1 -8
  10. package/dist/hooks/chains/useSquidChains.d.ts +0 -1
  11. package/dist/hooks/store/useDepositAddressStore.d.ts +0 -6
  12. package/dist/hooks/swap/useDepositAddress.d.ts +0 -2
  13. package/dist/hooks/tokens/useSquidTokens.d.ts +0 -1
  14. package/dist/hooks/wallet/useMultiChainWallet.d.ts +0 -38
  15. package/dist/hooks/wallet/useWallet.d.ts +0 -42
  16. package/dist/{index-ByakOYXP.js → index-C3owE9lb.js} +740 -514
  17. package/dist/index-C3owE9lb.js.map +1 -0
  18. package/dist/{index-nTqoaD0B.js → index-CJVX-7hj.js} +739 -517
  19. package/dist/index-CJVX-7hj.js.map +1 -0
  20. package/dist/{index.es--AR2n7a0.js → index.es-09IsADsA.js} +2 -2
  21. package/dist/{index.es--AR2n7a0.js.map → index.es-09IsADsA.js.map} +1 -1
  22. package/dist/{index.es-DtFDz6qc.js → index.es-CTKuR0LC.js} +2 -2
  23. package/dist/{index.es-DtFDz6qc.js.map → index.es-CTKuR0LC.js.map} +1 -1
  24. package/dist/index.esm.js +1 -1
  25. package/dist/index.js +1 -5
  26. package/dist/index.js.map +1 -1
  27. package/dist/{secretService-cgr3P1zw.js → secretService--tJFCkzT.js} +2 -2
  28. package/dist/{secretService-cgr3P1zw.js.map → secretService--tJFCkzT.js.map} +1 -1
  29. package/dist/{secretService-29Ak2qp5.js → secretService-GHdReJBs.js} +2 -2
  30. package/dist/{secretService-29Ak2qp5.js.map → secretService-GHdReJBs.js.map} +1 -1
  31. package/dist/server.esm.js +0 -6
  32. package/dist/server.esm.js.map +1 -1
  33. package/dist/server.js +0 -6
  34. package/dist/server.js.map +1 -1
  35. package/dist/services/external/rpcService.d.ts +2 -4
  36. package/dist/services/index.d.ts +0 -1
  37. package/dist/services/internal/assetsService.d.ts +1 -1
  38. package/dist/services/internal/cantonService.d.ts +2 -0
  39. package/dist/services/internal/cantonTransferService.d.ts +3 -3
  40. package/dist/services/internal/estimateService.d.ts +1 -1
  41. package/dist/services/internal/searchService.d.ts +1 -2
  42. package/dist/services/internal/transactionService.d.ts +0 -8
  43. package/dist/{stellarService.client-B__dTUBZ.js → stellarService.client-DAxgO3m3.js} +2 -2
  44. package/dist/{stellarService.client-B__dTUBZ.js.map → stellarService.client-DAxgO3m3.js.map} +1 -1
  45. package/dist/{stellarService.client-D-zkMI5s.js → stellarService.client-DvA-2pXq.js} +2 -2
  46. package/dist/{stellarService.client-D-zkMI5s.js.map → stellarService.client-DvA-2pXq.js.map} +1 -1
  47. package/dist/tests/loopSdkContract.test.d.ts +1 -0
  48. package/dist/tests/useAutoConnectCanton.test.d.ts +1 -0
  49. package/dist/tests/useCantonRestoration.test.d.ts +1 -0
  50. package/package.json +3 -2
  51. package/dist/core/types/danal.d.ts +0 -1
  52. package/dist/index-ByakOYXP.js.map +0 -1
  53. package/dist/index-nTqoaD0B.js.map +0 -1
  54. package/dist/services/internal/danalService.d.ts +0 -8
  55. /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-cgr3P1zw.js');
23663
+ const { fetchAllSecretBalances } = await import('./secretService--tJFCkzT.js');
23718
23664
  return fetchAllSecretBalances(chainData, cosmosAddress, squidSecretTokens, keplrTypeWallet);
23719
23665
  };
23720
23666
  function getTokenAssetsKey(token) {
@@ -25295,8 +25241,7 @@ const searchTokens = (query, tokens, chains) => {
25295
25241
  .filter((chain) => chain.nativeCurrency.symbol.toLowerCase() === query.toLowerCase() ||
25296
25242
  chain.nativeCurrency.name.toLowerCase().includes(query.toLowerCase()) ||
25297
25243
  chain.networkName.toLowerCase().includes(query.toLowerCase()) ||
25298
- (chain.axelarChainName?.toLowerCase().includes(query.toLowerCase()) ??
25299
- false))
25244
+ chain.axelarChainName.toLowerCase().includes(query.toLowerCase()))
25300
25245
  .map((chain) => tokens.find((token) => token.chainId === chain.chainId &&
25301
25246
  token.address.toLowerCase() === nativeEvmTokenAddress))
25302
25247
  .filter((token) => token !== undefined);
@@ -25709,7 +25654,7 @@ const useSquidTokens = (direction) => {
25709
25654
  config.availableChains,
25710
25655
  direction,
25711
25656
  ]);
25712
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useMemo(() => {
25657
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useMemo(() => {
25713
25658
  return tokens?.reduce((acc, token) => {
25714
25659
  switch (token.type) {
25715
25660
  case ChainType.EVM:
@@ -25736,9 +25681,6 @@ const useSquidTokens = (direction) => {
25736
25681
  case ChainType.CANTON:
25737
25682
  acc.cantonTokens.push(token);
25738
25683
  break;
25739
- case ChainType.DANAL:
25740
- acc.danalTokens.push(token);
25741
- break;
25742
25684
  }
25743
25685
  return acc;
25744
25686
  }, {
@@ -25750,7 +25692,6 @@ const useSquidTokens = (direction) => {
25750
25692
  xrplTokens: [],
25751
25693
  stellarTokens: [],
25752
25694
  cantonTokens: [],
25753
- danalTokens: [],
25754
25695
  });
25755
25696
  }, [tokens]);
25756
25697
  const findToken = useCallback((address, chainId) => {
@@ -25769,7 +25710,6 @@ const useSquidTokens = (direction) => {
25769
25710
  xrplTokens,
25770
25711
  stellarTokens,
25771
25712
  cantonTokens,
25772
- danalTokens,
25773
25713
  };
25774
25714
  };
25775
25715
 
@@ -26306,7 +26246,6 @@ const chainTypeToRefetchInterval = {
26306
26246
  [ChainType.XRPL]: 1_000,
26307
26247
  [ChainType.STELLAR]: 1_000,
26308
26248
  [ChainType.CANTON]: 1_000,
26309
- [ChainType.DANAL]: 1_000,
26310
26249
  };
26311
26250
  /**
26312
26251
  * Returns the status refetch interval of a Send transaction
@@ -26573,7 +26512,7 @@ const useSquidChains = (direction) => {
26573
26512
  const chain = findChain(chainId);
26574
26513
  return chain?.chainType;
26575
26514
  }, [findChain]);
26576
- const { evmChains, cosmosChains, suiChains, stellarChains, xrplChains, cantonChains, danalChains, } = useMemo(() => {
26515
+ const { evmChains, cosmosChains, suiChains, stellarChains, xrplChains, cantonChains, } = useMemo(() => {
26577
26516
  return chains.reduce((acc, chain) => {
26578
26517
  switch (chain.chainType) {
26579
26518
  case ChainType.EVM:
@@ -26594,9 +26533,6 @@ const useSquidChains = (direction) => {
26594
26533
  case ChainType.CANTON:
26595
26534
  acc.cantonChains.push(chain);
26596
26535
  break;
26597
- case ChainType.DANAL:
26598
- acc.danalChains.push(chain);
26599
- break;
26600
26536
  }
26601
26537
  return acc;
26602
26538
  }, {
@@ -26606,7 +26542,6 @@ const useSquidChains = (direction) => {
26606
26542
  xrplChains: [],
26607
26543
  stellarChains: [],
26608
26544
  cantonChains: [],
26609
- danalChains: [],
26610
26545
  });
26611
26546
  }, [chains]);
26612
26547
  const { supportedSourceChains, supportedDestinationChains } = useMemo(() => {
@@ -26628,7 +26563,6 @@ const useSquidChains = (direction) => {
26628
26563
  xrplChains,
26629
26564
  stellarChains,
26630
26565
  cantonChains,
26631
- danalChains,
26632
26566
  getChainType,
26633
26567
  findChain,
26634
26568
  };
@@ -26942,7 +26876,343 @@ const useBitcoinContext = () => {
26942
26876
  return context;
26943
26877
  };
26944
26878
 
26945
- 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;
26946
27216
  function pickAddress(accounts) {
26947
27217
  return (accounts.find((a) => a.primary) ?? accounts[0])?.partyId;
26948
27218
  }
@@ -26951,6 +27221,7 @@ function pickAddress(accounts) {
26951
27221
  * (bound to its announce `target`) and exposes the lifecycle methods.
26952
27222
  */
26953
27223
  class CantonBrowserConnector {
27224
+ kind = "cip103";
26954
27225
  providerId;
26955
27226
  name;
26956
27227
  target;
@@ -26965,7 +27236,7 @@ class CantonBrowserConnector {
26965
27236
  client ??
26966
27237
  createCantonClient(new WindowTransport(win, {
26967
27238
  target: this.target,
26968
- timeout: REQUEST_TIMEOUT_MS,
27239
+ timeout: REQUEST_TIMEOUT_MS$1,
26969
27240
  }));
26970
27241
  }
26971
27242
  get accounts() {
@@ -27011,6 +27282,28 @@ class CantonBrowserConnector {
27011
27282
  this._accounts = await this.client.listAccounts();
27012
27283
  return this._accounts;
27013
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
+ }
27014
27307
  on(event, handler) {
27015
27308
  this.listeners[event].add(handler);
27016
27309
  }
@@ -27117,6 +27410,313 @@ function discoverInjectedCantonWallets(win) {
27117
27410
  });
27118
27411
  }
27119
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
+
27120
27720
  /**
27121
27721
  * Discovers Canton browser-extension wallets and maps each to a
27122
27722
  * {@link CantonWallet}: CIP-103 announce-protocol wallets (on mount and on
@@ -27163,7 +27763,19 @@ function useCantonWallets() {
27163
27763
  return;
27164
27764
  const announced = (await discoverCantonProviders()).map(toAnnouncedWallet);
27165
27765
  const injected = discoverInjectedCantonWallets().map(toInjectedWallet);
27166
- 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]));
27167
27779
  }, [toAnnouncedWallet, toInjectedWallet]);
27168
27780
  useEffect(() => {
27169
27781
  refresh();
@@ -27194,7 +27806,9 @@ function useCanton() {
27194
27806
  // Try to reconnect silently first (existing session, no popup)
27195
27807
  result = await wallet.connector.autoConnect();
27196
27808
  }
27197
- catch {
27809
+ catch (error) {
27810
+ if (error instanceof CantonConnectionCancelledError)
27811
+ throw error;
27198
27812
  // Otherwise prompt the wallet to connect
27199
27813
  result = await wallet.connector.connect();
27200
27814
  }
@@ -27216,8 +27830,7 @@ function useCanton() {
27216
27830
  wallet: recentCantonWallet,
27217
27831
  address,
27218
27832
  });
27219
- // eslint-disable-next-line react-hooks/exhaustive-deps
27220
- }, [wallets.map((w) => w.connectorId), recentCantonWalletId]);
27833
+ }, [wallets, recentCantonWalletId, setConnectedWallet]);
27221
27834
  useEffect(() => {
27222
27835
  const wallet = connectedCantonWallet.wallet;
27223
27836
  if (!wallet) {
@@ -27474,7 +28087,7 @@ function useStellarWallets() {
27474
28087
  try {
27475
28088
  const { allowAllModules: initializeAllModules } = await import('@creit.tech/stellar-wallets-kit');
27476
28089
  const { LedgerModule } = await import('@creit.tech/stellar-wallets-kit/modules/ledger.module.mjs');
27477
- const { formatStellarWallet } = await import('./stellarService.client-B__dTUBZ.js');
28090
+ const { formatStellarWallet } = await import('./stellarService.client-DAxgO3m3.js');
27478
28091
  const modules = [...initializeAllModules(), new LedgerModule()];
27479
28092
  const promises = modules.map(async (module) => {
27480
28093
  const isAvailable = await module.isAvailable();
@@ -28053,6 +28666,11 @@ const useWallet = () => {
28053
28666
  }
28054
28667
  }
28055
28668
  catch (error) {
28669
+ const connecting = useWalletStore.getState().connectingWalletState;
28670
+ if (connecting.wallet !== wallet ||
28671
+ connecting.status !== ConnectingWalletStatus.CONNECTING) {
28672
+ return false;
28673
+ }
28056
28674
  console.error("Failed to connect wallet", error);
28057
28675
  walletConnectionError(wallet, error);
28058
28676
  return false;
@@ -28284,8 +28902,6 @@ const useMultiChainWallet = (chain) => {
28284
28902
  chainType: chain.chainType,
28285
28903
  }),
28286
28904
  };
28287
- case ChainType.DANAL:
28288
- return {};
28289
28905
  }
28290
28906
  }, [
28291
28907
  chain?.chainType,
@@ -29124,8 +29740,6 @@ async function createClient(chain) {
29124
29740
  return new StellarRpcClient(chain.rpc);
29125
29741
  case ChainType.CANTON:
29126
29742
  return null;
29127
- case ChainType.DANAL:
29128
- return null;
29129
29743
  }
29130
29744
  }
29131
29745
 
@@ -30140,8 +30754,7 @@ const getAllStellarTokensBalance = async (userAddress, stellarTokens, stellarCha
30140
30754
  };
30141
30755
  /**
30142
30756
  * Canton balances are private: they can only be read with a wallet-authorized
30143
- * `ledgerApi` session (the connected wallet supplies a JWT that can read as the
30144
- * 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
30145
30758
  * only for that wallet's party — there's no address-only read.
30146
30759
  */
30147
30760
  const getCantonTokenBalance = async (userAddress, token, cantonConnector) => {
@@ -30150,30 +30763,14 @@ const getCantonTokenBalance = async (userAddress, token, cantonConnector) => {
30150
30763
  const instrument = parseCantonInstrument(token.originalAddress);
30151
30764
  if (!instrument)
30152
30765
  return "0";
30153
- const ledgerEnd = await cantonConnector.ledgerApi({ requestMethod: "get", resource: "/v2/state/ledger-end" });
30154
- const activeContracts = await cantonConnector.ledgerApi({
30155
- requestMethod: "post",
30156
- resource: "/v2/state/active-contracts",
30157
- body: buildHoldingsAcsRequestBody(userAddress, String(ledgerEnd.offset)),
30158
- });
30159
- const grouped = groupCantonHoldingBalances(activeContracts);
30766
+ const grouped = await cantonConnector.getBalances(userAddress);
30160
30767
  return grouped[cantonInstrumentKey(instrument)] ?? "0";
30161
30768
  };
30162
30769
  /**
30163
- * Fetch balances for all Canton tokens in one ACS query. Canton balances are
30164
- * private, so this requires a connected wallet's authorized `ledgerApi`.
30770
+ * Fetch balances for all Canton tokens through the connected wallet.
30165
30771
  */
30166
30772
  async function getAllCantonTokensBalance({ connector, partyId, tokens, }) {
30167
- const ledgerEnd = await connector.ledgerApi({
30168
- requestMethod: "get",
30169
- resource: "/v2/state/ledger-end",
30170
- });
30171
- const activeContracts = await connector.ledgerApi({
30172
- requestMethod: "post",
30173
- resource: "/v2/state/active-contracts",
30174
- body: buildHoldingsAcsRequestBody(partyId, String(ledgerEnd.offset)),
30175
- });
30176
- const grouped = groupCantonHoldingBalances(activeContracts);
30773
+ const grouped = await connector.getBalances(partyId);
30177
30774
  return tokens.map((token) => {
30178
30775
  const instrument = token.originalAddress
30179
30776
  ? parseCantonInstrument(token.originalAddress)
@@ -30392,7 +30989,7 @@ const useCantonBalance = ({ chain, token, userAddress, enabled = true, refreshIn
30392
30989
  };
30393
30990
 
30394
30991
  function useNativeTokenForChain(chain) {
30395
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useSquidTokens();
30992
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useSquidTokens();
30396
30993
  const getTokensForChainType = () => {
30397
30994
  if (!chain?.chainType)
30398
30995
  return [];
@@ -30413,8 +31010,6 @@ function useNativeTokenForChain(chain) {
30413
31010
  return stellarTokens;
30414
31011
  case ChainType.CANTON:
30415
31012
  return cantonTokens;
30416
- case ChainType.DANAL:
30417
- return danalTokens;
30418
31013
  }
30419
31014
  };
30420
31015
  const nativeTokenForChainType = useMemo(() => {
@@ -30675,9 +31270,6 @@ const useNativeBalance = (chain) => {
30675
31270
  case ChainType.CANTON:
30676
31271
  balance = nativeCantonBalance;
30677
31272
  break;
30678
- case ChainType.DANAL:
30679
- balance = undefined;
30680
- break;
30681
31273
  }
30682
31274
  const balanceFormatted = !!balance
30683
31275
  ? formatBNToReadable(balance.value, balance.decimals)
@@ -30717,8 +31309,6 @@ const useNativeBalance = (chain) => {
30717
31309
  return isStellarLoading;
30718
31310
  case ChainType.CANTON:
30719
31311
  return isCantonLoading;
30720
- case ChainType.DANAL:
30721
- return false;
30722
31312
  }
30723
31313
  }, [
30724
31314
  chain?.chainType,
@@ -30944,7 +31534,7 @@ function hederaWalletConnect(parameters) {
30944
31534
  const optionalChains = config.chains.map((x) => x.id);
30945
31535
  if (!optionalChains.length)
30946
31536
  return;
30947
- const { EthereumProvider } = await import('./index.es--AR2n7a0.js');
31537
+ const { EthereumProvider } = await import('./index.es-09IsADsA.js');
30948
31538
  const rawProvider = await EthereumProvider.init({
30949
31539
  ...restParameters,
30950
31540
  disableProviderPing: true,
@@ -31178,8 +31768,6 @@ const useSigner = ({ chain }) => {
31178
31768
  return isStellarSignerReady;
31179
31769
  case ChainType.CANTON:
31180
31770
  return isCantonSignerReady;
31181
- case ChainType.DANAL:
31182
- return false;
31183
31771
  }
31184
31772
  }, [
31185
31773
  chain?.chainType,
@@ -31632,12 +32220,8 @@ const useSendTransactionStore = create((set, get) => ({
31632
32220
  const useDepositAddressStore = create((set) => ({
31633
32221
  deposit: null,
31634
32222
  selectedPaymentMethod: "connectedWallet",
31635
- userDepositTxId: null,
31636
32223
  setDeposit: (data) => {
31637
- set({ deposit: data, userDepositTxId: null });
31638
- },
31639
- setUserDepositTxId: (txId) => {
31640
- set({ userDepositTxId: txId });
32224
+ set({ deposit: data });
31641
32225
  },
31642
32226
  setPaymentMethod: (method) => {
31643
32227
  set({ selectedPaymentMethod: method });
@@ -31649,7 +32233,7 @@ function useDepositAddress(squidRoute) {
31649
32233
  selectedPaymentMethod: state.selectedPaymentMethod,
31650
32234
  depositAddress: state.deposit?.depositAddress,
31651
32235
  }));
31652
- const { setDeposit, setPaymentMethod, deposit, userDepositTxId, setUserDepositTxId, } = useDepositAddressStore();
32236
+ const { setDeposit, setPaymentMethod, deposit } = useDepositAddressStore();
31653
32237
  const { squid } = useSquidStore();
31654
32238
  const { fromChain } = useSwap();
31655
32239
  const isAvailableAsPaymentMethod = useMemo(() => {
@@ -31659,13 +32243,11 @@ function useDepositAddress(squidRoute) {
31659
32243
  CHAIN_IDS.BITCOIN,
31660
32244
  CHAIN_IDS.SOLANA,
31661
32245
  CHAIN_IDS.CANTON,
31662
- CHAIN_IDS.DANAL_TESTNET,
31663
32246
  ];
31664
32247
  return chainsSupportingDepositAddress.includes(fromChain.chainId);
31665
32248
  }, [fromChain?.chainId]);
31666
- const routeProvidesDirectDepositAddress = (!!squidRoute?.transactionRequest &&
31667
- isDepositAddressDirectTransferRoute(squidRoute.transactionRequest)) ||
31668
- (!!squidRoute && isDanalDepositRoute(squidRoute));
32249
+ const routeProvidesDirectDepositAddress = !!squidRoute?.transactionRequest &&
32250
+ isDepositAddressDirectTransferRoute(squidRoute.transactionRequest);
31669
32251
  const swapWillGenerateDepositAddress = isChainflipDepositRoute(squidRoute) || routeProvidesDirectDepositAddress;
31670
32252
  const paymentMethod = isAvailableAsPaymentMethod
31671
32253
  ? selectedPaymentMethod
@@ -31691,19 +32273,6 @@ function useDepositAddress(squidRoute) {
31691
32273
  });
31692
32274
  return;
31693
32275
  }
31694
- else if (isDanalDepositRoute(route)) {
31695
- const transferBody = parseDanalTransferBody(route.transactionRequest.data);
31696
- if (!transferBody) {
31697
- throw new Error("Could not parse Danal transfer request body");
31698
- }
31699
- setDeposit({
31700
- amount: transferBody.amount,
31701
- depositAddress: route.transactionRequest.target,
31702
- statusTrackingId: transferBody.memo,
31703
- memo: transferBody.memo,
31704
- });
31705
- return;
31706
- }
31707
32276
  else if (isDepositAddressDirectTransferRoute(route.transactionRequest)) {
31708
32277
  // Canton case
31709
32278
  const orderHash = route.transactionRequest.data;
@@ -31726,8 +32295,6 @@ function useDepositAddress(squidRoute) {
31726
32295
  depositAddress,
31727
32296
  closeDepositChannel,
31728
32297
  depositData: deposit,
31729
- userDepositTxId,
31730
- setUserDepositTxId,
31731
32298
  };
31732
32299
  }
31733
32300
 
@@ -31755,7 +32322,7 @@ const useUrlSwapParams = () => {
31755
32322
 
31756
32323
  const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, queryOptions, }) => {
31757
32324
  const { evmChains, cosmosChains, suiChains, xrplChains, stellarChains } = useSquidChains(direction);
31758
- const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, danalTokens, } = useSquidTokens(direction);
32325
+ const { evmTokens, cosmosTokens, solanaTokens, bitcoinTokens, suiTokens, xrplTokens, stellarTokens, cantonTokens, } = useSquidTokens(direction);
31759
32326
  const { keplrTypeWallet } = useCosmosContext();
31760
32327
  const cantonConnector = useWalletStore((store) => store.connectedWalletsByChainType[ChainType.CANTON]?.wallet?.connector);
31761
32328
  const placeholderData = useMemo(() => {
@@ -31768,7 +32335,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31768
32335
  [ChainType.XRPL]: xrplTokens.map((t) => ({ ...t, balance: "0" })),
31769
32336
  [ChainType.STELLAR]: stellarTokens.map((t) => ({ ...t, balance: "0" })),
31770
32337
  [ChainType.CANTON]: cantonTokens.map((t) => ({ ...t, balance: "0" })),
31771
- [ChainType.DANAL]: danalTokens.map((t) => ({ ...t, balance: "0" })),
31772
32338
  };
31773
32339
  if (!chainType) {
31774
32340
  // Return all tokens with zero balance
@@ -31791,7 +32357,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31791
32357
  xrplTokens,
31792
32358
  stellarTokens,
31793
32359
  cantonTokens,
31794
- danalTokens,
31795
32360
  ]);
31796
32361
  const isQueryEnabled = useMemo(() => {
31797
32362
  // Respect the queryOptions.enabled override if provided
@@ -31816,8 +32381,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31816
32381
  return stellarTokens.length > 0;
31817
32382
  case ChainType.CANTON:
31818
32383
  return cantonTokens.length > 0;
31819
- case ChainType.DANAL:
31820
- return danalTokens.length > 0;
31821
32384
  }
31822
32385
  }, [
31823
32386
  chainType,
@@ -31831,7 +32394,6 @@ const useAllTokensWithBalanceForChainType = ({ chainType, address, direction, qu
31831
32394
  xrplTokens.length,
31832
32395
  stellarTokens.length,
31833
32396
  cantonTokens.length,
31834
- danalTokens.length,
31835
32397
  ]);
31836
32398
  const query = useQuery(keys().allTokensBalance(address, chainType, direction), async () => {
31837
32399
  // Return zero balances if no address
@@ -31956,12 +32518,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31956
32518
  direction,
31957
32519
  queryOptions,
31958
32520
  });
31959
- const danalBalancesQuery = useAllTokensWithBalanceForChainType({
31960
- chainType: ChainType.DANAL,
31961
- address: connectedAddresses?.[ChainType.DANAL],
31962
- direction,
31963
- queryOptions,
31964
- });
31965
32521
  // Create a map of chain type to balance query results
31966
32522
  const balanceQueries = useMemo(() => ({
31967
32523
  [ChainType.EVM]: evmBalancesQuery,
@@ -31972,7 +32528,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31972
32528
  [ChainType.XRPL]: xrplBalancesQuery,
31973
32529
  [ChainType.STELLAR]: stellarBalancesQuery,
31974
32530
  [ChainType.CANTON]: cantonBalancesQuery,
31975
- [ChainType.DANAL]: danalBalancesQuery,
31976
32531
  }), [
31977
32532
  evmBalancesQuery,
31978
32533
  cosmosBalancesQuery,
@@ -31982,7 +32537,6 @@ const useAllConnectedWalletBalances = ({ direction, queryOptions = {
31982
32537
  xrplBalancesQuery,
31983
32538
  stellarBalancesQuery,
31984
32539
  cantonBalancesQuery,
31985
- danalBalancesQuery,
31986
32540
  ]);
31987
32541
  // Combine all tokens from different chains
31988
32542
  const allTokens = useMemo(() => Object.values(balanceQueries).flatMap((query) => query.data?.tokens ?? []), [balanceQueries]);
@@ -32090,8 +32644,6 @@ const useMultiChainBalance = ({ chain, token, userAddress, enabled = true, }) =>
32090
32644
  return stellarBalance;
32091
32645
  case ChainType.CANTON:
32092
32646
  return cantonBalance;
32093
- case ChainType.DANAL:
32094
- return "0";
32095
32647
  }
32096
32648
  }, [
32097
32649
  chain?.chainType,
@@ -33201,9 +33753,8 @@ function useSendTransaction({ to, amount, token, chain, }) {
33201
33753
  chain,
33202
33754
  });
33203
33755
  break;
33204
- case ChainType.CANTON:
33205
- case ChainType.DANAL: {
33206
- throw new Error(`Send not implemented for chain type ${chain.chainType}`);
33756
+ case ChainType.CANTON: {
33757
+ throw new Error("Not implemented");
33207
33758
  }
33208
33759
  }
33209
33760
  return {
@@ -33409,8 +33960,7 @@ async function getSendTransactionStatus({ chain, txHash, }) {
33409
33960
  chain,
33410
33961
  });
33411
33962
  case ChainType.CANTON:
33412
- case ChainType.DANAL:
33413
- throw new Error(`Send not implemented for chain type ${chain.chainType}`);
33963
+ throw new Error("Not implemented");
33414
33964
  }
33415
33965
  }
33416
33966
 
@@ -37031,342 +37581,6 @@ coin.DecProto = {
37031
37581
 
37032
37582
  } (tx));
37033
37583
 
37034
- const vParty = (party) => ({ party });
37035
- const vText = (text) => ({ text });
37036
- const vNumeric = (numeric) => ({ numeric });
37037
- const vContractId = (contractId) => ({
37038
- contractId,
37039
- });
37040
- const vList = (elements) => ({
37041
- list: { elements },
37042
- });
37043
- const vRecord = (fields) => ({
37044
- record: { fields: fields.map(([label, value]) => ({ label, value })) },
37045
- });
37046
- const vTextMap = (entries) => ({ textMap: { entries } });
37047
- const vTimestamp = (isoString) => ({
37048
- timestamp: String(Math.floor(new Date(isoString).getTime() * 1000)),
37049
- });
37050
- function isRecord(value) {
37051
- return typeof value === "object" && value !== null && !Array.isArray(value);
37052
- }
37053
- function normalizeChoiceContextValue(value) {
37054
- if (typeof value === "string")
37055
- return value;
37056
- if (!isRecord(value) || typeof value.tag !== "string")
37057
- return null;
37058
- switch (value.tag) {
37059
- case "AV_Text":
37060
- case "AV_ContractId":
37061
- return typeof value.value === "string"
37062
- ? { tag: value.tag, value: value.value }
37063
- : null;
37064
- case "AV_Bool":
37065
- return typeof value.value === "boolean"
37066
- ? { tag: value.tag, value: value.value }
37067
- : null;
37068
- case "AV_List":
37069
- if (!Array.isArray(value.value))
37070
- return null;
37071
- return {
37072
- tag: value.tag,
37073
- value: value.value.flatMap((entry) => {
37074
- const normalized = normalizeChoiceContextValue(entry);
37075
- return normalized ? [normalized] : [];
37076
- }),
37077
- };
37078
- default: {
37079
- const inner = value.value;
37080
- if (typeof inner === "string" ||
37081
- typeof inner === "number" ||
37082
- typeof inner === "boolean" ||
37083
- inner === null) {
37084
- return { tag: value.tag, value: inner };
37085
- }
37086
- if (Array.isArray(inner)) {
37087
- return {
37088
- tag: value.tag,
37089
- value: inner.flatMap((entry) => {
37090
- const normalized = normalizeChoiceContextValue(entry);
37091
- return normalized ? [normalized] : [];
37092
- }),
37093
- };
37094
- }
37095
- if (!isRecord(inner))
37096
- return null;
37097
- const normalizedObject = {};
37098
- for (const [key, entry] of Object.entries(inner)) {
37099
- if (typeof entry !== "string" &&
37100
- typeof entry !== "number" &&
37101
- typeof entry !== "boolean" &&
37102
- entry !== null) {
37103
- return null;
37104
- }
37105
- normalizedObject[key] = entry;
37106
- }
37107
- return { tag: value.tag, value: normalizedObject };
37108
- }
37109
- }
37110
- }
37111
- function stringifyChoiceContextValue(value) {
37112
- return typeof value === "string" ? value : String(value);
37113
- }
37114
- function choiceContextValueToAnyValue(value) {
37115
- if (typeof value === "string") {
37116
- return {
37117
- variant: { constructor: "AV_Text", value: vText(value) },
37118
- };
37119
- }
37120
- switch (value.tag) {
37121
- case "AV_ContractId":
37122
- if (typeof value.value !== "string") {
37123
- throw new TypeError("AV_ContractId values must be strings");
37124
- }
37125
- return {
37126
- variant: { constructor: value.tag, value: vContractId(value.value) },
37127
- };
37128
- case "AV_Bool":
37129
- if (typeof value.value !== "boolean") {
37130
- throw new TypeError("AV_Bool values must be booleans");
37131
- }
37132
- return {
37133
- variant: { constructor: value.tag, value: { bool: value.value } },
37134
- };
37135
- case "AV_List":
37136
- if (!Array.isArray(value.value)) {
37137
- throw new TypeError("AV_List values must be arrays");
37138
- }
37139
- return {
37140
- variant: {
37141
- constructor: value.tag,
37142
- value: vList(value.value.map(choiceContextValueToAnyValue)),
37143
- },
37144
- };
37145
- default:
37146
- return {
37147
- variant: {
37148
- constructor: value.tag,
37149
- value: vText(stringifyChoiceContextValue(value.value)),
37150
- },
37151
- };
37152
- }
37153
- }
37154
-
37155
- /** Metadata key used by Splice token-standard transfers to carry our Squid orderhash memo. */
37156
- const CANTON_MEMO_KEY = "splice.lfdecentralizedtrust.org/reason";
37157
- /** Interface id for the transfer factory contract returned by the token registry. */
37158
- const TRANSFER_FACTORY_INTERFACE_ID = "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory";
37159
- /** Choice exercised on the transfer factory to create the token-standard transfer. */
37160
- const TRANSFER_FACTORY_CHOICE = "TransferFactory_Transfer";
37161
- /** CIP-056 (non-Amulet) tokens expose a registrar parameterized by admin party. */
37162
- const CIP056_REGISTRAR_BASE = "https://api.utilities.digitalasset.com/api/token-standard/v0/registrars";
37163
- const TRANSFER_REQUESTED_AT_SKEW_MS = 60_000;
37164
- const TRANSFER_EXECUTE_WINDOW_MS = 24 * 60 * 60 * 1000;
37165
- function resolveCantonRegistryUrl(instrument) {
37166
- if (instrument.id === CANTON_AMULET_INSTRUMENT_ID) {
37167
- return CANTON_AMULET_REGISTRY_URL;
37168
- }
37169
- return `${CIP056_REGISTRAR_BASE}/${encodeURIComponent(instrument.admin)}`;
37170
- }
37171
- /**
37172
- * Build the plain JSON arguments expected by the registry transfer-factory
37173
- * endpoint before it adds choice context and disclosed contracts.
37174
- */
37175
- function buildTransferChoiceArgs({ sender, receiver, amount, instrument, inputHoldingCids, memo, nowMs, }) {
37176
- return {
37177
- expectedAdmin: instrument.admin,
37178
- transfer: {
37179
- sender,
37180
- receiver,
37181
- amount,
37182
- instrumentId: { admin: instrument.admin, id: instrument.id },
37183
- requestedAt: new Date(nowMs - TRANSFER_REQUESTED_AT_SKEW_MS).toISOString(),
37184
- executeBefore: new Date(nowMs + TRANSFER_EXECUTE_WINDOW_MS).toISOString(),
37185
- inputHoldingCids,
37186
- meta: { values: { [CANTON_MEMO_KEY]: memo } },
37187
- },
37188
- extraArgs: { context: { values: {} }, meta: { values: {} } },
37189
- };
37190
- }
37191
- /**
37192
- * Canton's Holding contracts follow Bitcoin-style UTXOs model.
37193
- *
37194
- * Pick Holding contract ids covering `amount` for the instrument: prefer a
37195
- * single exact-amount holding, else accumulate largest-first.
37196
- */
37197
- function selectInputHoldingCids(holdings, instrument, amount) {
37198
- const spendableHoldings = holdings.filter((h) => !h.locked &&
37199
- h.instrument.admin === instrument.admin &&
37200
- h.instrument.id === instrument.id);
37201
- const target = new BigNumber(amount);
37202
- const exact = spendableHoldings.find((h) => new BigNumber(h.amount).eq(target));
37203
- if (exact)
37204
- return [exact.contractId];
37205
- const sorted = [...spendableHoldings].sort((a, b) => new BigNumber(b.amount).comparedTo(new BigNumber(a.amount)));
37206
- const selected = [];
37207
- let sum = new BigNumber(0);
37208
- for (const holding of sorted) {
37209
- selected.push(holding.contractId);
37210
- sum = sum.plus(holding.amount);
37211
- if (sum.gte(target))
37212
- break;
37213
- }
37214
- if (sum.lt(target)) {
37215
- throw new Error("Insufficient Canton holdings to cover transfer amount");
37216
- }
37217
- return selected;
37218
- }
37219
- async function fetchInputHoldingCids(connector, party, instrument, amount) {
37220
- const ledgerEnd = await connector.ledgerApi({
37221
- requestMethod: "get",
37222
- resource: "/v2/state/ledger-end",
37223
- });
37224
- const activeContracts = await connector.ledgerApi({
37225
- requestMethod: "post",
37226
- resource: "/v2/state/active-contracts",
37227
- body: buildHoldingsAcsRequestBody(party, String(ledgerEnd.offset)),
37228
- });
37229
- return selectInputHoldingCids(parseCantonHoldings(activeContracts), instrument, amount);
37230
- }
37231
- /**
37232
- * Ask the token registry for the transfer factory contract and extra context
37233
- * required to exercise its transfer choice.
37234
- */
37235
- async function fetchTransferFactory(registryUrl, choiceArgs) {
37236
- const response = await fetch(`${registryUrl}/registry/transfer-instruction/v1/transfer-factory`, {
37237
- method: "POST",
37238
- headers: { "Content-Type": "application/json" },
37239
- body: JSON.stringify({
37240
- choiceArguments: choiceArgs,
37241
- excludeDebugFields: true,
37242
- }),
37243
- });
37244
- if (!response.ok) {
37245
- throw new Error(`Canton transfer-factory request failed (${response.status})`);
37246
- }
37247
- return response.json();
37248
- }
37249
- /**
37250
- * Convert transfer choice args into strict Daml Value JSON for the wallet's
37251
- * prepareExecute ExerciseCommand.
37252
- */
37253
- function buildPrepareChoiceArgument(choiceArgs) {
37254
- const contextValues = Object.entries(choiceArgs.extraArgs.context?.values ?? {})
37255
- .map(([key, value]) => {
37256
- const normalized = normalizeChoiceContextValue(value);
37257
- return normalized
37258
- ? { key, value: choiceContextValueToAnyValue(normalized) }
37259
- : undefined;
37260
- })
37261
- .filter((entry) => Boolean(entry));
37262
- return vRecord([
37263
- ["expectedAdmin", vParty(choiceArgs.expectedAdmin)],
37264
- [
37265
- "transfer",
37266
- vRecord([
37267
- ["sender", vParty(choiceArgs.transfer.sender)],
37268
- ["receiver", vParty(choiceArgs.transfer.receiver)],
37269
- ["amount", vNumeric(choiceArgs.transfer.amount)],
37270
- [
37271
- "instrumentId",
37272
- vRecord([
37273
- ["admin", vParty(choiceArgs.transfer.instrumentId.admin)],
37274
- ["id", vText(choiceArgs.transfer.instrumentId.id)],
37275
- ]),
37276
- ],
37277
- ["requestedAt", vTimestamp(choiceArgs.transfer.requestedAt)],
37278
- ["executeBefore", vTimestamp(choiceArgs.transfer.executeBefore)],
37279
- [
37280
- "inputHoldingCids",
37281
- vList(choiceArgs.transfer.inputHoldingCids.map(vContractId)),
37282
- ],
37283
- [
37284
- "meta",
37285
- vRecord([
37286
- [
37287
- "values",
37288
- vTextMap(Object.entries(choiceArgs.transfer.meta.values).map(([key, value]) => ({ key, value: vText(value) }))),
37289
- ],
37290
- ]),
37291
- ],
37292
- ]),
37293
- ],
37294
- [
37295
- "extraArgs",
37296
- vRecord([
37297
- ["context", vRecord([["values", vTextMap(contextValues)]])],
37298
- ["meta", vRecord([["values", vTextMap([])]])],
37299
- ]),
37300
- ],
37301
- ]);
37302
- }
37303
- /**
37304
- * Convert a registry disclosed contract into the wallet submission shape,
37305
- * dropping debug fields and entries without a usable createdEventBlob.
37306
- */
37307
- function toDisclosedContract(raw) {
37308
- if (typeof raw.createdEventBlob !== "string")
37309
- return null;
37310
- return {
37311
- createdEventBlob: raw.createdEventBlob,
37312
- contractId: typeof raw.contractId === "string" ? raw.contractId : undefined,
37313
- synchronizerId: typeof raw.synchronizerId === "string" ? raw.synchronizerId : undefined,
37314
- };
37315
- }
37316
- /**
37317
- * Build a Splice token-standard transfer of `amount` of `token` from `sender`
37318
- * to `receiver`, carrying `memo`, ready to hand to a wallet's prepareExecute.
37319
- * Returns the full prepareExecute params (commandId + commands + actAs +
37320
- * disclosedContracts).
37321
- */
37322
- async function buildCantonTransfer(connector, { sender, receiver, amount, token, memo, nowMs, }) {
37323
- if (!token.originalAddress) {
37324
- throw new Error("Canton token originalAddress is required");
37325
- }
37326
- const instrument = parseCantonInstrument(token.originalAddress);
37327
- if (!instrument) {
37328
- throw new Error(`Invalid Canton token address: ${token.originalAddress}`);
37329
- }
37330
- const registryUrl = resolveCantonRegistryUrl(instrument);
37331
- const inputHoldingCids = await fetchInputHoldingCids(connector, sender, instrument, amount);
37332
- const choiceArgs = buildTransferChoiceArgs({
37333
- sender,
37334
- receiver,
37335
- amount,
37336
- instrument,
37337
- inputHoldingCids,
37338
- memo,
37339
- nowMs,
37340
- });
37341
- const factory = await fetchTransferFactory(registryUrl, choiceArgs);
37342
- const choiceContextData = factory.choiceContext.choiceContextData;
37343
- if (!choiceContextData) {
37344
- throw new Error("Transfer factory choice context is missing");
37345
- }
37346
- choiceArgs.extraArgs.context = choiceContextData;
37347
- const disclosedContracts = (factory.choiceContext?.disclosedContracts ?? []).flatMap((raw) => {
37348
- const disclosedContract = toDisclosedContract(raw);
37349
- return disclosedContract ? [disclosedContract] : [];
37350
- });
37351
- // Command ID: client-supplied identifier used to deduplicate submissions
37352
- const commandId = `canton-${memo}`;
37353
- return {
37354
- commandId,
37355
- commands: [
37356
- {
37357
- ExerciseCommand: {
37358
- templateId: TRANSFER_FACTORY_INTERFACE_ID,
37359
- contractId: factory.factoryId,
37360
- choice: TRANSFER_FACTORY_CHOICE,
37361
- choiceArgument: buildPrepareChoiceArgument(choiceArgs),
37362
- },
37363
- },
37364
- ],
37365
- actAs: [sender],
37366
- disclosedContracts,
37367
- };
37368
- }
37369
-
37370
37584
  const useExecuteTransaction = (squidRoute) => {
37371
37585
  const { fromChain, toChain, fromToken, toToken, isSameChain } = useSwap();
37372
37586
  // A route completes on source tx only if it's same-chain AND
@@ -37981,7 +38195,7 @@ const useExecuteTransaction = (squidRoute) => {
37981
38195
  }
37982
38196
  const amount = formatBNToReadable(fromAmount, token.decimals);
37983
38197
  dispatchSignatureRequestEvent(route);
37984
- const transferParams = await buildCantonTransfer(cantonSigner, {
38198
+ const result = await cantonSigner.transfer({
37985
38199
  sender: sourceUserAddress,
37986
38200
  receiver,
37987
38201
  amount,
@@ -37989,15 +38203,14 @@ const useExecuteTransaction = (squidRoute) => {
37989
38203
  memo: orderHash,
37990
38204
  nowMs: Date.now(),
37991
38205
  });
37992
- const result = await cantonSigner.prepareExecuteAndWait(transferParams);
37993
- const txHash = result.tx?.payload?.updateId ?? "";
38206
+ const txHash = result.updateId;
37994
38207
  if (txHash) {
37995
38208
  resetQueriesAfterTxSigned();
37996
38209
  }
37997
38210
  WidgetEvents.getInstance().dispatchSwapExecuteCall(route, txHash);
37998
38211
  const txParams = setTransactionState({
37999
38212
  route,
38000
- txHash: txHash,
38213
+ txHash,
38001
38214
  userAddress: sourceUserAddress,
38002
38215
  status: TransactionStatus.INITIAL_LOADING,
38003
38216
  sourceStatus: TransactionStatus.ONGOING,
@@ -38280,7 +38493,7 @@ refetchIntervalInBackground = false, refetchInterval = 30000, quoteOnly = true,
38280
38493
  //
38281
38494
  // If deposit address is not selected, we use the connected address as the source address instead
38282
38495
  const sourceUserAddress = isDepositAddressActive
38283
- ? depositRefundAddress ?? sourceConnectedAddress
38496
+ ? (depositRefundAddress ?? sourceConnectedAddress)
38284
38497
  : sourceConnectedAddress;
38285
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), [
38286
38499
  fromChain?.chainId,
@@ -38572,6 +38785,10 @@ const useAutoConnect = () => {
38572
38785
  const { chains } = useSquidChains();
38573
38786
  const { isInitialized } = useConfigStore();
38574
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);
38575
38792
  const { autoConnectEvm } = useEvmContext();
38576
38793
  const { autoConnectSolana } = useSolanaContext();
38577
38794
  const { autoConnectSui } = useSuiContext();
@@ -38639,6 +38856,15 @@ const useAutoConnect = () => {
38639
38856
  useEffect(() => {
38640
38857
  autoConnect();
38641
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]);
38642
38868
  return { autoConnect };
38643
38869
  };
38644
38870
 
@@ -38947,5 +39173,5 @@ const SquidProvider = ({ children, config, placeholder, }) => {
38947
39173
  React.createElement(CosmosProvider, null, children))))))))))) : (placeholder);
38948
39174
  };
38949
39175
 
38950
- 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 };
38951
- //# sourceMappingURL=index-ByakOYXP.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