@subwallet/extension-base 1.3.31-1 → 1.3.33-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 (140) hide show
  1. package/background/KoniTypes.d.ts +94 -3
  2. package/background/KoniTypes.js +14 -0
  3. package/background/errors/CardanoProviderError.d.ts +6 -0
  4. package/background/errors/CardanoProviderError.js +61 -0
  5. package/background/types.d.ts +2 -2
  6. package/cjs/background/KoniTypes.js +16 -1
  7. package/cjs/background/errors/CardanoProviderError.js +67 -0
  8. package/cjs/constants/environment.js +4 -2
  9. package/cjs/constants/index.js +4 -1
  10. package/cjs/core/logic-validation/request.js +50 -3
  11. package/cjs/koni/api/contract-handler/evm/web3.js +21 -0
  12. package/cjs/koni/api/staking/bonding/utils.js +24 -3
  13. package/cjs/koni/background/handlers/Extension.js +141 -107
  14. package/cjs/koni/background/handlers/State.js +232 -6
  15. package/cjs/koni/background/handlers/Tabs.js +277 -55
  16. package/cjs/packageInfo.js +1 -1
  17. package/cjs/page/cardano/cips/cip30.js +63 -0
  18. package/cjs/page/cardano/cips/index.js +20 -0
  19. package/cjs/page/cardano/index.js +41 -0
  20. package/cjs/page/{SubWalleEvmProvider.js → evm/index.js} +2 -2
  21. package/cjs/page/index.js +9 -4
  22. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +6 -2
  23. package/cjs/services/balance-service/transfer/xcm/index.js +2 -0
  24. package/cjs/services/chain-service/handler/CardanoApi.js +33 -0
  25. package/cjs/services/chain-service/index.js +31 -0
  26. package/cjs/services/chain-service/utils/patch.js +1 -1
  27. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
  28. package/cjs/services/earning-service/handlers/native-staking/dtao.js +2 -2
  29. package/cjs/services/earning-service/handlers/native-staking/mythos.js +42 -8
  30. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
  31. package/cjs/services/earning-service/handlers/native-staking/tao.js +13 -13
  32. package/cjs/services/earning-service/handlers/nomination-pool/index.js +1 -1
  33. package/cjs/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
  34. package/cjs/services/price-service/coingecko.js +22 -3
  35. package/cjs/services/price-service/index.js +75 -2
  36. package/cjs/services/request-service/constants.js +3 -1
  37. package/cjs/services/request-service/handler/AuthRequestHandler.js +38 -5
  38. package/cjs/services/request-service/handler/CardanoRequestHandler.js +45 -3
  39. package/cjs/services/request-service/helper/index.js +419 -1
  40. package/cjs/services/swap-service/handler/asset-hub/handler.js +1 -1
  41. package/cjs/services/swap-service/handler/base-handler.js +81 -21
  42. package/cjs/services/swap-service/handler/hydradx-handler.js +1 -1
  43. package/cjs/services/swap-service/handler/uniswap-handler.js +274 -45
  44. package/cjs/services/swap-service/index.js +33 -11
  45. package/cjs/services/swap-service/utils.js +15 -2
  46. package/cjs/utils/auth.js +2 -1
  47. package/cjs/utils/cardano.js +20 -0
  48. package/cjs/utils/index.js +16 -4
  49. package/cjs/utils/price.js +28 -0
  50. package/constants/environment.d.ts +1 -0
  51. package/constants/environment.js +2 -1
  52. package/constants/index.d.ts +1 -0
  53. package/constants/index.js +1 -0
  54. package/core/logic-validation/request.d.ts +6 -2
  55. package/core/logic-validation/request.js +51 -5
  56. package/koni/api/contract-handler/evm/web3.d.ts +2 -0
  57. package/koni/api/contract-handler/evm/web3.js +19 -0
  58. package/koni/api/staking/bonding/utils.d.ts +2 -1
  59. package/koni/api/staking/bonding/utils.js +23 -3
  60. package/koni/background/handlers/Extension.d.ts +2 -0
  61. package/koni/background/handlers/Extension.js +32 -2
  62. package/koni/background/handlers/State.d.ts +6 -1
  63. package/koni/background/handlers/State.js +228 -6
  64. package/koni/background/handlers/Tabs.d.ts +11 -1
  65. package/koni/background/handlers/Tabs.js +242 -19
  66. package/package.json +67 -42
  67. package/packageInfo.js +1 -1
  68. package/page/cardano/cips/cip30.d.ts +22 -0
  69. package/page/cardano/cips/cip30.js +55 -0
  70. package/page/cardano/cips/index.d.ts +3 -0
  71. package/page/cardano/cips/index.js +7 -0
  72. package/page/cardano/index.d.ts +13 -0
  73. package/page/cardano/index.js +34 -0
  74. package/page/{SubWalleEvmProvider.d.ts → evm/index.d.ts} +3 -2
  75. package/page/{SubWalleEvmProvider.js → evm/index.js} +1 -1
  76. package/page/index.d.ts +3 -2
  77. package/page/index.js +6 -2
  78. package/page/{Accounts.d.ts → substrate/Accounts.d.ts} +1 -1
  79. package/page/{Metadata.d.ts → substrate/Metadata.d.ts} +1 -1
  80. package/page/{PostMessageProvider.d.ts → substrate/PostMessageProvider.d.ts} +1 -1
  81. package/page/{Signer.d.ts → substrate/Signer.d.ts} +1 -1
  82. package/page/{Injected.d.ts → substrate/index.d.ts} +1 -1
  83. package/services/balance-service/helpers/subscribe/cardano/types.d.ts +14 -0
  84. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +4 -0
  85. package/services/balance-service/transfer/xcm/acrossBridge/index.js +4 -1
  86. package/services/balance-service/transfer/xcm/index.js +2 -0
  87. package/services/chain-service/handler/CardanoApi.d.ts +3 -1
  88. package/services/chain-service/handler/CardanoApi.js +33 -0
  89. package/services/chain-service/index.d.ts +5 -1
  90. package/services/chain-service/index.js +32 -1
  91. package/services/chain-service/utils/patch.js +1 -1
  92. package/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
  93. package/services/earning-service/handlers/native-staking/dtao.js +2 -2
  94. package/services/earning-service/handlers/native-staking/mythos.js +42 -8
  95. package/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
  96. package/services/earning-service/handlers/native-staking/tao.js +14 -14
  97. package/services/earning-service/handlers/nomination-pool/index.js +1 -1
  98. package/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
  99. package/services/price-service/coingecko.d.ts +2 -1
  100. package/services/price-service/coingecko.js +19 -1
  101. package/services/price-service/index.d.ts +11 -1
  102. package/services/price-service/index.js +78 -5
  103. package/services/request-service/constants.js +3 -1
  104. package/services/request-service/handler/AuthRequestHandler.js +40 -7
  105. package/services/request-service/handler/CardanoRequestHandler.d.ts +2 -0
  106. package/services/request-service/handler/CardanoRequestHandler.js +45 -3
  107. package/services/request-service/helper/index.d.ts +54 -0
  108. package/services/request-service/helper/index.js +406 -1
  109. package/services/request-service/types.d.ts +3 -1
  110. package/services/swap-service/handler/asset-hub/handler.js +1 -1
  111. package/services/swap-service/handler/base-handler.d.ts +3 -1
  112. package/services/swap-service/handler/base-handler.js +82 -22
  113. package/services/swap-service/handler/hydradx-handler.js +1 -1
  114. package/services/swap-service/handler/uniswap-handler.d.ts +5 -0
  115. package/services/swap-service/handler/uniswap-handler.js +275 -46
  116. package/services/swap-service/index.js +34 -12
  117. package/services/swap-service/utils.d.ts +3 -2
  118. package/services/swap-service/utils.js +13 -1
  119. package/types/swap/index.d.ts +1 -0
  120. package/types/transaction/process.d.ts +2 -0
  121. package/utils/auth.js +3 -2
  122. package/utils/cardano.d.ts +2 -0
  123. package/utils/cardano.js +12 -0
  124. package/utils/index.d.ts +2 -1
  125. package/utils/index.js +2 -1
  126. package/utils/price.d.ts +3 -0
  127. package/utils/price.js +20 -0
  128. package/cjs/utils/canDerive.js +0 -12
  129. package/utils/canDerive.d.ts +0 -2
  130. package/utils/canDerive.js +0 -6
  131. /package/cjs/page/{Accounts.js → substrate/Accounts.js} +0 -0
  132. /package/cjs/page/{Metadata.js → substrate/Metadata.js} +0 -0
  133. /package/cjs/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
  134. /package/cjs/page/{Signer.js → substrate/Signer.js} +0 -0
  135. /package/cjs/page/{Injected.js → substrate/index.js} +0 -0
  136. /package/page/{Accounts.js → substrate/Accounts.js} +0 -0
  137. /package/page/{Metadata.js → substrate/Metadata.js} +0 -0
  138. /package/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
  139. /package/page/{Signer.js → substrate/Signer.js} +0 -0
  140. /package/page/{Injected.js → substrate/index.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs';
4
5
  import { addMetadata } from '@subwallet/extension-chains';
5
6
  import { knownGenesis } from '@polkadot/networks/defaults';
6
7
  export const extractMetadata = store => {
@@ -41,4 +42,408 @@ export const extractMetadata = store => {
41
42
  def
42
43
  }) => addMetadata(def));
43
44
  });
44
- };
45
+ };
46
+ export const convertAssetToValue = amount => {
47
+ const value = CardanoWasm.Value.new(CardanoWasm.BigNum.from_str('0'));
48
+ const multiAsset = CardanoWasm.MultiAsset.new();
49
+ for (const item of amount) {
50
+ if (item.unit === 'lovelace') {
51
+ value.set_coin(CardanoWasm.BigNum.from_str(item.quantity));
52
+ } else {
53
+ const policyIdHex = item.unit.slice(0, 56);
54
+ const assetNameHex = item.unit.slice(56);
55
+ const scriptHash = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyIdHex, 'hex'));
56
+ const assetName = CardanoWasm.AssetName.new(Buffer.from(assetNameHex, 'hex'));
57
+ const quantity = CardanoWasm.BigNum.from_str(item.quantity);
58
+ let assets = multiAsset.get(scriptHash);
59
+ if (!assets) {
60
+ assets = CardanoWasm.Assets.new();
61
+ }
62
+ assets.insert(assetName, quantity);
63
+ multiAsset.insert(scriptHash, assets);
64
+ }
65
+ }
66
+ if (multiAsset.len() > 0) {
67
+ value.set_multiasset(multiAsset);
68
+ }
69
+ return value;
70
+ };
71
+ export const convertValueToAsset = value => {
72
+ var _value$multiasset;
73
+ const assets = [];
74
+ assets.push({
75
+ unit: 'lovelace',
76
+ quantity: value.coin().to_js_value()
77
+ });
78
+ const multiAssets = (_value$multiasset = value.multiasset()) === null || _value$multiasset === void 0 ? void 0 : _value$multiasset.keys();
79
+ if (multiAssets) {
80
+ for (let j = 0; j < multiAssets.len(); j++) {
81
+ var _value$multiasset2;
82
+ const policy = multiAssets.get(j);
83
+ const policyAssets = (_value$multiasset2 = value.multiasset()) === null || _value$multiasset2 === void 0 ? void 0 : _value$multiasset2.get(policy);
84
+ if (!policyAssets) {
85
+ continue;
86
+ }
87
+ const assetNames = policyAssets.keys();
88
+ for (let k = 0; k < assetNames.len(); k++) {
89
+ var _quantity$to_js_value;
90
+ const assetName = assetNames.get(k);
91
+ const quantity = policyAssets.get(assetName);
92
+ const assetUnit = `${policy.to_hex()}${assetName.to_hex()}`;
93
+ assets.push({
94
+ unit: assetUnit,
95
+ quantity: (_quantity$to_js_value = quantity === null || quantity === void 0 ? void 0 : quantity.to_js_value()) !== null && _quantity$to_js_value !== void 0 ? _quantity$to_js_value : '0',
96
+ policy: policy.to_hex(),
97
+ name: Buffer.from(assetName.to_hex(), 'hex').toString(),
98
+ fingerprint: `${policy.to_hex()}${assetName.to_hex()}`
99
+ });
100
+ }
101
+ }
102
+ }
103
+ return assets;
104
+ };
105
+ export const convertUtxoRawToUtxo = utxos => {
106
+ return utxos.map(utxo => {
107
+ const txHash = CardanoWasm.TransactionHash.from_bytes(Buffer.from(utxo.tx_hash, 'hex'));
108
+ const txIndex = utxo.output_index;
109
+ const input = CardanoWasm.TransactionInput.new(txHash, txIndex);
110
+ const value = convertAssetToValue(utxo.amount);
111
+ const txOutput = CardanoWasm.TransactionOutput.new(CardanoWasm.Address.from_bech32(utxo.address), value);
112
+ return CardanoWasm.TransactionUnspentOutput.new(input, txOutput);
113
+ });
114
+ };
115
+ export function getBalanceAddressMap(outputs) {
116
+ const acc = {};
117
+ for (let i = 0; i < outputs.len(); i++) {
118
+ const item = outputs.get(i);
119
+ const address = item.address().to_bech32();
120
+ if (!acc[address]) {
121
+ acc[address] = item.amount();
122
+ } else {
123
+ acc[address] = acc[address].checked_add(item.amount());
124
+ }
125
+ }
126
+ return acc;
127
+ }
128
+
129
+ /**
130
+ * Extracts all required key hashes from a list of certificates.
131
+ * Handles different certificate kinds: stake deregistration, delegation,
132
+ * pool registration, pool retirement, and MIR (move instantaneous rewards).
133
+ *
134
+ * Only processes key hash credentials (ignores script credentials).
135
+ *
136
+ * @param {Certificates} certificates - List of certificate objects from a transaction body.
137
+ * @returns {string[]} - An array of required key hashes in hex format.
138
+ */
139
+
140
+ export function extractKeyHashFromCertificate(certificates) {
141
+ if (!certificates) {
142
+ return [];
143
+ }
144
+ const requiredKeyHashes = [];
145
+
146
+ // Helper: Extract key hash from stake credential (only if it's a public key)
147
+ const extractKeyHash = credential => {
148
+ if (credential.kind() === 0) {
149
+ var _credential$to_keyhas;
150
+ // kind === 0 => StakeCredential is a public key
151
+ return (_credential$to_keyhas = credential.to_keyhash()) === null || _credential$to_keyhas === void 0 ? void 0 : _credential$to_keyhas.to_hex();
152
+ }
153
+ return null;
154
+ };
155
+ for (let i = 0; i < certificates.len(); i++) {
156
+ const cert = certificates.get(i);
157
+ switch (cert.kind()) {
158
+ case 0:
159
+ {
160
+ // Stake Registration Certificate
161
+ // No key hash required here, just registration action
162
+ break;
163
+ }
164
+ case 1:
165
+ {
166
+ var _cert$as_stake_deregi;
167
+ // Stake Deregistration Certificate
168
+ const credential = (_cert$as_stake_deregi = cert.as_stake_deregistration()) === null || _cert$as_stake_deregi === void 0 ? void 0 : _cert$as_stake_deregi.stake_credential();
169
+ if (!credential) {
170
+ break;
171
+ }
172
+ const hash = extractKeyHash(credential);
173
+ if (hash) {
174
+ requiredKeyHashes.push(hash);
175
+ }
176
+ break;
177
+ }
178
+ case 2:
179
+ {
180
+ var _cert$as_stake_delega;
181
+ // Stake Delegation Certificate
182
+ const credential = (_cert$as_stake_delega = cert.as_stake_delegation()) === null || _cert$as_stake_delega === void 0 ? void 0 : _cert$as_stake_delega.stake_credential();
183
+ if (!credential) {
184
+ break;
185
+ }
186
+ const hash = extractKeyHash(credential);
187
+ if (hash) {
188
+ requiredKeyHashes.push(hash);
189
+ }
190
+ break;
191
+ }
192
+ case 3:
193
+ {
194
+ var _cert$as_pool_registr;
195
+ // Pool Registration Certificate
196
+ // Collect all pool owner key hashes
197
+ const owners = (_cert$as_pool_registr = cert.as_pool_registration()) === null || _cert$as_pool_registr === void 0 ? void 0 : _cert$as_pool_registr.pool_params().pool_owners();
198
+ if (!owners) {
199
+ break;
200
+ }
201
+ for (let j = 0; j < owners.len(); j++) {
202
+ const ownerKeyHash = owners.get(j).to_hex();
203
+ requiredKeyHashes.push(ownerKeyHash);
204
+ }
205
+ break;
206
+ }
207
+ case 4:
208
+ {
209
+ var _cert$as_pool_retirem;
210
+ // Pool Retirement Certificate
211
+ // The operator key hash is required to authorize retirement
212
+ const operator = (_cert$as_pool_retirem = cert.as_pool_retirement()) === null || _cert$as_pool_retirem === void 0 ? void 0 : _cert$as_pool_retirem.pool_keyhash().to_hex();
213
+ if (!operator) {
214
+ break;
215
+ }
216
+ requiredKeyHashes.push(operator);
217
+ break;
218
+ }
219
+ case 6:
220
+ {
221
+ var _cert$as_move_instant, _cert$as_move_instant2;
222
+ // Move Instantaneous Rewards Certificate
223
+ // Extract key hashes from reward receivers
224
+ const rewards = (_cert$as_move_instant = cert.as_move_instantaneous_rewards_cert()) === null || _cert$as_move_instant === void 0 ? void 0 : (_cert$as_move_instant2 = _cert$as_move_instant.move_instantaneous_reward().as_to_stake_creds()) === null || _cert$as_move_instant2 === void 0 ? void 0 : _cert$as_move_instant2.keys();
225
+ if (!rewards) {
226
+ break;
227
+ }
228
+ for (let j = 0; j < rewards.len(); j++) {
229
+ const hash = extractKeyHash(rewards.get(j));
230
+ if (hash) {
231
+ requiredKeyHashes.push(hash);
232
+ }
233
+ }
234
+ break;
235
+ }
236
+ default:
237
+ {
238
+ // Unknown or unsupported certificate kind — skip
239
+ break;
240
+ }
241
+ }
242
+ }
243
+ return requiredKeyHashes;
244
+ }
245
+
246
+ /**
247
+ * Extracts required key hashes from withdrawal entries.
248
+ * It processes only credentials of kind 0 (key hash based).
249
+ *
250
+ * @param {Withdrawals} withdrawals - The withdrawal map from a transaction body.
251
+ * @returns {string[]} - An array of required key hashes in hex format.
252
+ */
253
+
254
+ export function extractKeyHashesFromWithdrawals(withdrawals) {
255
+ if (!withdrawals) {
256
+ return [];
257
+ }
258
+ const requiredKeyHashes = [];
259
+ const rewardAccounts = withdrawals.keys();
260
+ for (let i = 0; i < rewardAccounts.len(); i++) {
261
+ const stakeCred = rewardAccounts.get(i).payment_cred();
262
+
263
+ // Check if the credential is a key hash (not a script)
264
+ const keyHash = stakeCred.to_keyhash();
265
+ if (stakeCred.kind() === 0 && keyHash) {
266
+ const hexHash = Buffer.from(keyHash.to_bytes()).toString('hex');
267
+ requiredKeyHashes.push(hexHash);
268
+ }
269
+ }
270
+ return requiredKeyHashes;
271
+ }
272
+
273
+ /**
274
+ * Recursively extract all Ed25519 key hashes from a NativeScripts collection.
275
+ * Only processes `ScriptPubkey` entries (kind = 0), and traverses through nested scripts.
276
+ *
277
+ * @param {NativeScripts} scripts - A collection of native scripts.
278
+ * @returns {string[]} - An array of key hashes (hex-encoded) from all script_pubkey entries.
279
+ */
280
+
281
+ export function extractKeyHashesFromScripts(scripts) {
282
+ if (!scripts) {
283
+ return [];
284
+ }
285
+ const keyHashes = [];
286
+ for (let i = 0; i < scripts.len(); i++) {
287
+ const script = scripts.get(i);
288
+ switch (script.kind()) {
289
+ case 0:
290
+ {
291
+ var _script$as_script_pub;
292
+ // ScriptPubkey
293
+ const pubkeyHash = (_script$as_script_pub = script.as_script_pubkey()) === null || _script$as_script_pub === void 0 ? void 0 : _script$as_script_pub.addr_keyhash();
294
+ if (!pubkeyHash) {
295
+ break;
296
+ }
297
+ const hexHash = pubkeyHash.to_hex();
298
+ keyHashes.push(hexHash);
299
+ break;
300
+ }
301
+ case 1:
302
+ {
303
+ var _script$as_script_all;
304
+ // ScriptAll
305
+ const nestedScripts = (_script$as_script_all = script.as_script_all()) === null || _script$as_script_all === void 0 ? void 0 : _script$as_script_all.native_scripts();
306
+ keyHashes.push(...extractKeyHashesFromScripts(nestedScripts));
307
+ break;
308
+ }
309
+ case 2:
310
+ {
311
+ var _script$as_script_any;
312
+ // ScriptAny
313
+ const nestedScripts = (_script$as_script_any = script.as_script_any()) === null || _script$as_script_any === void 0 ? void 0 : _script$as_script_any.native_scripts();
314
+ keyHashes.push(...extractKeyHashesFromScripts(nestedScripts));
315
+ break;
316
+ }
317
+ case 3:
318
+ {
319
+ var _script$as_script_n_o;
320
+ // ScriptNOfK
321
+ const nestedScripts = (_script$as_script_n_o = script.as_script_n_of_k()) === null || _script$as_script_n_o === void 0 ? void 0 : _script$as_script_n_o.native_scripts();
322
+ keyHashes.push(...extractKeyHashesFromScripts(nestedScripts));
323
+ break;
324
+ }
325
+ default:
326
+ // Unknown kind, skip
327
+ break;
328
+ }
329
+ }
330
+ return keyHashes;
331
+ }
332
+
333
+ /**
334
+ * Extract required key hashes from the RequiredSigners field in the transaction body.
335
+ * Each entry is an Ed25519 key hash that must sign the transaction.
336
+ *
337
+ * @param {Ed25519KeyHashes} requiredSigners - A list of required signer key hashes.
338
+ * @returns {string[]} - Array of hex-encoded Ed25519 key hashes.
339
+ */
340
+ export function extractKeyHashesFromRequiredSigners(requiredSigners) {
341
+ if (!requiredSigners) {
342
+ return [];
343
+ }
344
+ const result = [];
345
+ for (let i = 0; i < requiredSigners.len(); i++) {
346
+ result.push(requiredSigners.get(i).to_hex());
347
+ }
348
+ return result;
349
+ }
350
+
351
+ /**
352
+ * Extract required key hashes from collateral inputs in a linear and readable flow.
353
+ *
354
+ * This function resolves UTXOs of each collateral input,
355
+ * attempts to extract the payment key hash from various supported address types,
356
+ * and returns an array of required signer key hashes in hex format.
357
+ *
358
+ * @param {TransactionInputs} collaterals - Collateral inputs used for script validation
359
+ * @param getSpecificUtxo
360
+ * @returns {Promise<string[]>} - Hex-encoded key hashes required to sign the transaction
361
+ */
362
+ export async function extractKeyHashesFromCollaterals(collaterals, getSpecificUtxo) {
363
+ if (!collaterals || !getSpecificUtxo) {
364
+ return [];
365
+ }
366
+ const keyHashes = [];
367
+ for (let i = 0; i < collaterals.len(); i++) {
368
+ const collateral = collaterals.get(i);
369
+
370
+ // Resolve UTXO from tx_id + index
371
+ const txId = collateral.transaction_id().to_hex();
372
+ const utxo = await getSpecificUtxo(txId, collateral.index());
373
+ if (!utxo) {
374
+ continue;
375
+ }
376
+
377
+ // Load address object from UTXO
378
+ const address = CardanoWasm.Address.from_bech32(utxo.address);
379
+
380
+ // Try extracting payment key hash from different address types
381
+ const types = [CardanoWasm.BaseAddress, CardanoWasm.EnterpriseAddress, CardanoWasm.PointerAddress];
382
+ let extracted = false;
383
+ for (const Type of types) {
384
+ try {
385
+ var _Type$from_address;
386
+ const paymentCred = (_Type$from_address = Type.from_address(address)) === null || _Type$from_address === void 0 ? void 0 : _Type$from_address.payment_cred();
387
+ const keyHash = paymentCred === null || paymentCred === void 0 ? void 0 : paymentCred.to_keyhash();
388
+ if (keyHash) {
389
+ keyHashes.push(keyHash.to_hex());
390
+ extracted = true;
391
+ break;
392
+ }
393
+ } catch (_) {
394
+ // Skip to next type
395
+ }
396
+ }
397
+ if (!extracted) {
398
+ throw new Error('Unsupported collateral address type');
399
+ }
400
+ }
401
+ return keyHashes;
402
+ }
403
+
404
+ /// Check if valueA has sufficient value to cover valueB
405
+ export function hasSufficientCardanoValue(valueA, valueB) {
406
+ const coinA = BigInt(valueA.coin().to_str());
407
+ const coinB = BigInt(valueB.coin().to_str());
408
+
409
+ // Check if ADA amount in valueA is less than required in valueB
410
+ if (coinA < coinB) {
411
+ return false;
412
+ }
413
+ const multiAssetB = valueB.multiasset();
414
+ if (!multiAssetB) {
415
+ return true;
416
+ } // No assets required in valueB
417
+
418
+ const multiAssetA = valueA.multiasset();
419
+ if (!multiAssetA) {
420
+ return false;
421
+ } // valueA has no assets but valueB requires them
422
+
423
+ const policyIds = multiAssetB.keys();
424
+ for (let i = 0; i < policyIds.len(); i++) {
425
+ const policyId = policyIds.get(i);
426
+ const assetsB = multiAssetB.get(policyId);
427
+ const assetsA = multiAssetA.get(policyId);
428
+ if (!assetsB) {
429
+ continue;
430
+ }
431
+ if (!assetsA) {
432
+ return false;
433
+ } // Required policy ID is missing in valueA
434
+
435
+ const assetNames = assetsB.keys();
436
+ for (let j = 0; j < assetNames.len(); j++) {
437
+ var _assetsB$get$to_str, _assetsB$get, _assetsA$get$to_str, _assetsA$get;
438
+ const assetName = assetNames.get(j);
439
+ const quantityB = BigInt((_assetsB$get$to_str = (_assetsB$get = assetsB.get(assetName)) === null || _assetsB$get === void 0 ? void 0 : _assetsB$get.to_str()) !== null && _assetsB$get$to_str !== void 0 ? _assetsB$get$to_str : '0');
440
+ const quantityA = BigInt((_assetsA$get$to_str = (_assetsA$get = assetsA.get(assetName)) === null || _assetsA$get === void 0 ? void 0 : _assetsA$get.to_str()) !== null && _assetsA$get$to_str !== void 0 ? _assetsA$get$to_str : '0');
441
+
442
+ // Check if asset quantity in valueA is less than required
443
+ if (quantityA < quantityB) {
444
+ return false;
445
+ }
446
+ }
447
+ }
448
+ return true;
449
+ }
@@ -19,9 +19,11 @@ export interface AuthUrlInfo {
19
19
  url: string;
20
20
  accountAuthTypes: AccountAuthType[];
21
21
  isAllowedMap: Record<string, boolean>;
22
- currentEvmNetworkKey?: string;
22
+ currentNetworkMap: Partial<Record<AccountAuthType, string>>;
23
+ currentAccount?: string;
23
24
  }
24
25
  export interface AuthUrlInfoNeedMigration extends Omit<AuthUrlInfo, 'accountAuthTypes'> {
25
26
  accountAuthType?: AccountAuthType | 'both';
27
+ currentEvmNetworkKey?: string;
26
28
  }
27
29
  export declare type AuthUrls = Record<string, AuthUrlInfo>;
@@ -159,7 +159,7 @@ export class AssetHubSwapHandler {
159
159
  const type = process.steps[currentStep].type;
160
160
  switch (type) {
161
161
  case CommonStepType.XCM:
162
- return this.swapBaseHandler.handleBridgeStep(params);
162
+ return this.swapBaseHandler.handleBridgeStep(params, 'xcm');
163
163
  case SwapStepType.SWAP:
164
164
  return this.handleSubmitStep(params);
165
165
  default:
@@ -31,7 +31,9 @@ export declare class SwapBaseHandler {
31
31
  constructor({ balanceService, chainService, feeService, providerName, providerSlug }: SwapBaseHandlerInitParams);
32
32
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2, genStepFuncList: GenSwapStepFuncV2[]): Promise<CommonOptimalSwapPath>;
33
33
  getBridgeStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
34
- handleBridgeStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
34
+ handleBridgeStep(params: SwapSubmitParams, type: string): Promise<SwapSubmitStepData>;
35
+ handleBridgeSubstrate(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
36
+ handleBridgeAcross(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
35
37
  validateSetFeeTokenStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
36
38
  private validateBridgeStep;
37
39
  private validateSwapStepV2;
@@ -8,7 +8,8 @@ import { _isAccountActive } from '@subwallet/extension-base/core/substrate/syste
8
8
  import { _isAcrossBridgeXcm, _isSnowBridgeXcm, _isXcmWithinSameConsensus } from '@subwallet/extension-base/core/substrate/xcm-parser';
9
9
  import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
10
10
  import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
11
- import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenSlug, _getTokenMinAmount, _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
11
+ import { _isAcrossChainBridge, AcrossErrorMsg } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
12
+ import { _getAssetDecimals, _getAssetOriginChain, _getAssetSymbol, _getChainNativeTokenSlug, _getTokenMinAmount, _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
12
13
  import { DEFAULT_EXCESS_AMOUNT_WEIGHT, FEE_RATE_MULTIPLIER } from '@subwallet/extension-base/services/swap-service/utils';
13
14
  import { BasicTxErrorType, SwapStepType, TransferTxErrorType } from '@subwallet/extension-base/types';
14
15
  import { CommonStepType, DEFAULT_FIRST_STEP, MOCK_STEP_FEE } from '@subwallet/extension-base/types/service-base';
@@ -18,6 +19,7 @@ import { getId } from '@subwallet/extension-base/utils/getId';
18
19
  import BigN from 'bignumber.js';
19
20
  import { t } from 'i18next';
20
21
  import { isEthereumAddress } from '@polkadot/util-crypto';
22
+ import { createAcrossBridgeExtrinsic } from "../../balance-service/transfer/xcm/index.js";
21
23
  export class SwapBaseHandler {
22
24
  constructor({
23
25
  balanceService,
@@ -51,6 +53,10 @@ export class SwapBaseHandler {
51
53
  }
52
54
  return result;
53
55
  } catch (e) {
56
+ const errorMessage = e.message;
57
+ if (errorMessage.toLowerCase().startsWith(AcrossErrorMsg.AMOUNT_TOO_LOW) || errorMessage.toLowerCase().startsWith(AcrossErrorMsg.AMOUNT_TOO_HIGH)) {
58
+ throw new Error(errorMessage);
59
+ }
54
60
  return result;
55
61
  }
56
62
  }
@@ -184,7 +190,16 @@ export class SwapBaseHandler {
184
190
  return undefined;
185
191
  }
186
192
  }
187
- async handleBridgeStep(params) {
193
+ async handleBridgeStep(params, type) {
194
+ if (type === 'xcm') {
195
+ return this.handleBridgeSubstrate(params);
196
+ }
197
+ if (type === 'across') {
198
+ return this.handleBridgeAcross(params);
199
+ }
200
+ throw Error('Not support this type');
201
+ }
202
+ async handleBridgeSubstrate(params) {
188
203
  const briefXcmStep = params.process.steps[params.currentStep].metadata;
189
204
  if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
190
205
  throw new Error('XCM metadata error');
@@ -229,6 +244,49 @@ export class SwapBaseHandler {
229
244
  txData: xcmData
230
245
  };
231
246
  }
247
+ async handleBridgeAcross(params) {
248
+ const bridgeStep = params.process.steps[params.currentStep].metadata;
249
+ if (!bridgeStep || !bridgeStep.originTokenInfo || !bridgeStep.destinationTokenInfo || !bridgeStep.sendingValue) {
250
+ throw new Error('Bridge metadata error');
251
+ }
252
+ const originTokenInfo = bridgeStep.originTokenInfo;
253
+ const destinationTokenInfo = bridgeStep.destinationTokenInfo;
254
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
255
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
256
+ const evmApi = await this.chainService.getEvmApi(originTokenInfo.originChain).isReady;
257
+ const feeInfo = await this.feeService.subscribeChainFee(getId(), originTokenInfo.originChain, 'evm');
258
+ const sendingValue = bridgeStep.sendingValue;
259
+ const sender = bridgeStep.sender;
260
+ const recipient = bridgeStep.receiver;
261
+ const tx = await createAcrossBridgeExtrinsic({
262
+ originTokenInfo,
263
+ destinationTokenInfo,
264
+ originChain,
265
+ destinationChain,
266
+ evmApi,
267
+ feeInfo,
268
+ sendingValue,
269
+ sender,
270
+ recipient
271
+ });
272
+ const txData = {
273
+ originNetworkKey: originTokenInfo.originChain,
274
+ destinationNetworkKey: destinationTokenInfo.originChain,
275
+ from: sender,
276
+ to: recipient,
277
+ value: sendingValue,
278
+ tokenSlug: originTokenInfo.slug,
279
+ showExtraWarning: true
280
+ };
281
+ return {
282
+ txChain: originTokenInfo.originChain,
283
+ extrinsic: tx,
284
+ transferNativeAmount: _isNativeToken(originTokenInfo) ? bridgeStep.sendingValue : '0',
285
+ extrinsicType: ExtrinsicType.TRANSFER_XCM,
286
+ chainType: ChainType.EVM,
287
+ txData: txData
288
+ };
289
+ }
232
290
  async validateSetFeeTokenStep(params, stepIndex) {
233
291
  if (!params.selectedQuote) {
234
292
  return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
@@ -261,27 +319,29 @@ export class SwapBaseHandler {
261
319
  }
262
320
  }))];
263
321
  }
322
+ const isAcrossBridge = _isAcrossChainBridge(_getAssetOriginChain(fromToken), _getAssetOriginChain(toToken));
323
+ if (!isAcrossBridge) {
324
+ // By here, we know that the user is receiving a valid amount of toToken
325
+ const toChainApi = this.chainService.getSubstrateApi(toToken.originChain);
326
+ const sufficientChain = this.chainService.value.sufficientChains;
327
+ if (!toChainApi) {
328
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
329
+ }
264
330
 
265
- // By here, we know that the user is receiving a valid amount of toToken
266
- const toChainApi = this.chainService.getSubstrateApi(toToken.originChain);
267
- const sufficientChain = this.chainService.value.sufficientChains;
268
- if (!toChainApi) {
269
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
270
- }
271
-
272
- // Only need to check if account is alive with the receiving toToken
273
- const isToTokenSufficient = await _isSufficientToken(toToken, toChainApi, sufficientChain);
274
- if (!isToTokenSufficient && !_isNativeToken(toToken)) {
275
- // sending token cannot keep account alive, must check with native token
276
- const toChainNativeTokenBalance = await this.balanceService.getTotalBalance(receiver, toToken.originChain, toChainNativeToken.slug, ExtrinsicType.TRANSFER_BALANCE);
277
- if (!_isAccountActive(toChainNativeTokenBalance.metadata)) {
278
- return [new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('The recipient account has less than {{amount}} {{nativeSymbol}}, which can lead to your {{localSymbol}} being lost. Change recipient account and try again', {
279
- replace: {
280
- amount: toChainNativeTokenBalance.value,
281
- nativeSymbol: toChainNativeToken.symbol,
282
- localSymbol: toToken.symbol
283
- }
284
- }))];
331
+ // Only need to check if account is alive with the receiving toToken
332
+ const isToTokenSufficient = await _isSufficientToken(toToken, toChainApi, sufficientChain);
333
+ if (!isToTokenSufficient && !_isNativeToken(toToken)) {
334
+ // sending token cannot keep account alive, must check with native token
335
+ const toChainNativeTokenBalance = await this.balanceService.getTotalBalance(receiver, toToken.originChain, toChainNativeToken.slug, ExtrinsicType.TRANSFER_BALANCE);
336
+ if (!_isAccountActive(toChainNativeTokenBalance.metadata)) {
337
+ return [new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('The recipient account has less than {{amount}} {{nativeSymbol}}, which can lead to your {{localSymbol}} being lost. Change recipient account and try again', {
338
+ replace: {
339
+ amount: toChainNativeTokenBalance.value,
340
+ nativeSymbol: toChainNativeToken.symbol,
341
+ localSymbol: toToken.symbol
342
+ }
343
+ }))];
344
+ }
285
345
  }
286
346
  }
287
347
  return [];
@@ -278,7 +278,7 @@ export class HydradxHandler {
278
278
  case CommonStepType.DEFAULT:
279
279
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
280
280
  case CommonStepType.XCM:
281
- return this.swapBaseHandler.handleBridgeStep(params);
281
+ return this.swapBaseHandler.handleBridgeStep(params, 'xcm');
282
282
  case CommonStepType.SET_FEE_TOKEN:
283
283
  return this.handleSetFeeStep(params);
284
284
  case SwapStepType.SWAP:
@@ -23,10 +23,15 @@ export declare class UniswapHandler implements SwapBaseInterface {
23
23
  get providerInfo(): import("@subwallet/extension-base/types").SwapProvider;
24
24
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
25
25
  getApprovalStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
26
+ getApproveSwap(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
27
+ getApproveBridge(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
26
28
  getPermitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
27
29
  getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
30
+ getBridgeStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
28
31
  handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
29
32
  private tokenApproveSpending;
33
+ private approveSpendingSwap;
34
+ private approveSpendingBridge;
30
35
  handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
31
36
  handlePermitStep(params: SwapSubmitParams): {
32
37
  txChain: string;