@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.
- package/background/KoniTypes.d.ts +94 -3
- package/background/KoniTypes.js +14 -0
- package/background/errors/CardanoProviderError.d.ts +6 -0
- package/background/errors/CardanoProviderError.js +61 -0
- package/background/types.d.ts +2 -2
- package/cjs/background/KoniTypes.js +16 -1
- package/cjs/background/errors/CardanoProviderError.js +67 -0
- package/cjs/constants/environment.js +4 -2
- package/cjs/constants/index.js +4 -1
- package/cjs/core/logic-validation/request.js +50 -3
- package/cjs/koni/api/contract-handler/evm/web3.js +21 -0
- package/cjs/koni/api/staking/bonding/utils.js +24 -3
- package/cjs/koni/background/handlers/Extension.js +141 -107
- package/cjs/koni/background/handlers/State.js +232 -6
- package/cjs/koni/background/handlers/Tabs.js +277 -55
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/cardano/cips/cip30.js +63 -0
- package/cjs/page/cardano/cips/index.js +20 -0
- package/cjs/page/cardano/index.js +41 -0
- package/cjs/page/{SubWalleEvmProvider.js → evm/index.js} +2 -2
- package/cjs/page/index.js +9 -4
- package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +6 -2
- package/cjs/services/balance-service/transfer/xcm/index.js +2 -0
- package/cjs/services/chain-service/handler/CardanoApi.js +33 -0
- package/cjs/services/chain-service/index.js +31 -0
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +2 -2
- package/cjs/services/earning-service/handlers/native-staking/mythos.js +42 -8
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
- package/cjs/services/earning-service/handlers/native-staking/tao.js +13 -13
- package/cjs/services/earning-service/handlers/nomination-pool/index.js +1 -1
- package/cjs/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
- package/cjs/services/price-service/coingecko.js +22 -3
- package/cjs/services/price-service/index.js +75 -2
- package/cjs/services/request-service/constants.js +3 -1
- package/cjs/services/request-service/handler/AuthRequestHandler.js +38 -5
- package/cjs/services/request-service/handler/CardanoRequestHandler.js +45 -3
- package/cjs/services/request-service/helper/index.js +419 -1
- package/cjs/services/swap-service/handler/asset-hub/handler.js +1 -1
- package/cjs/services/swap-service/handler/base-handler.js +81 -21
- package/cjs/services/swap-service/handler/hydradx-handler.js +1 -1
- package/cjs/services/swap-service/handler/uniswap-handler.js +274 -45
- package/cjs/services/swap-service/index.js +33 -11
- package/cjs/services/swap-service/utils.js +15 -2
- package/cjs/utils/auth.js +2 -1
- package/cjs/utils/cardano.js +20 -0
- package/cjs/utils/index.js +16 -4
- package/cjs/utils/price.js +28 -0
- package/constants/environment.d.ts +1 -0
- package/constants/environment.js +2 -1
- package/constants/index.d.ts +1 -0
- package/constants/index.js +1 -0
- package/core/logic-validation/request.d.ts +6 -2
- package/core/logic-validation/request.js +51 -5
- package/koni/api/contract-handler/evm/web3.d.ts +2 -0
- package/koni/api/contract-handler/evm/web3.js +19 -0
- package/koni/api/staking/bonding/utils.d.ts +2 -1
- package/koni/api/staking/bonding/utils.js +23 -3
- package/koni/background/handlers/Extension.d.ts +2 -0
- package/koni/background/handlers/Extension.js +32 -2
- package/koni/background/handlers/State.d.ts +6 -1
- package/koni/background/handlers/State.js +228 -6
- package/koni/background/handlers/Tabs.d.ts +11 -1
- package/koni/background/handlers/Tabs.js +242 -19
- package/package.json +67 -42
- package/packageInfo.js +1 -1
- package/page/cardano/cips/cip30.d.ts +22 -0
- package/page/cardano/cips/cip30.js +55 -0
- package/page/cardano/cips/index.d.ts +3 -0
- package/page/cardano/cips/index.js +7 -0
- package/page/cardano/index.d.ts +13 -0
- package/page/cardano/index.js +34 -0
- package/page/{SubWalleEvmProvider.d.ts → evm/index.d.ts} +3 -2
- package/page/{SubWalleEvmProvider.js → evm/index.js} +1 -1
- package/page/index.d.ts +3 -2
- package/page/index.js +6 -2
- package/page/{Accounts.d.ts → substrate/Accounts.d.ts} +1 -1
- package/page/{Metadata.d.ts → substrate/Metadata.d.ts} +1 -1
- package/page/{PostMessageProvider.d.ts → substrate/PostMessageProvider.d.ts} +1 -1
- package/page/{Signer.d.ts → substrate/Signer.d.ts} +1 -1
- package/page/{Injected.d.ts → substrate/index.d.ts} +1 -1
- package/services/balance-service/helpers/subscribe/cardano/types.d.ts +14 -0
- package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +4 -0
- package/services/balance-service/transfer/xcm/acrossBridge/index.js +4 -1
- package/services/balance-service/transfer/xcm/index.js +2 -0
- package/services/chain-service/handler/CardanoApi.d.ts +3 -1
- package/services/chain-service/handler/CardanoApi.js +33 -0
- package/services/chain-service/index.d.ts +5 -1
- package/services/chain-service/index.js +32 -1
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
- package/services/earning-service/handlers/native-staking/dtao.js +2 -2
- package/services/earning-service/handlers/native-staking/mythos.js +42 -8
- package/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
- package/services/earning-service/handlers/native-staking/tao.js +14 -14
- package/services/earning-service/handlers/nomination-pool/index.js +1 -1
- package/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
- package/services/price-service/coingecko.d.ts +2 -1
- package/services/price-service/coingecko.js +19 -1
- package/services/price-service/index.d.ts +11 -1
- package/services/price-service/index.js +78 -5
- package/services/request-service/constants.js +3 -1
- package/services/request-service/handler/AuthRequestHandler.js +40 -7
- package/services/request-service/handler/CardanoRequestHandler.d.ts +2 -0
- package/services/request-service/handler/CardanoRequestHandler.js +45 -3
- package/services/request-service/helper/index.d.ts +54 -0
- package/services/request-service/helper/index.js +406 -1
- package/services/request-service/types.d.ts +3 -1
- package/services/swap-service/handler/asset-hub/handler.js +1 -1
- package/services/swap-service/handler/base-handler.d.ts +3 -1
- package/services/swap-service/handler/base-handler.js +82 -22
- package/services/swap-service/handler/hydradx-handler.js +1 -1
- package/services/swap-service/handler/uniswap-handler.d.ts +5 -0
- package/services/swap-service/handler/uniswap-handler.js +275 -46
- package/services/swap-service/index.js +34 -12
- package/services/swap-service/utils.d.ts +3 -2
- package/services/swap-service/utils.js +13 -1
- package/types/swap/index.d.ts +1 -0
- package/types/transaction/process.d.ts +2 -0
- package/utils/auth.js +3 -2
- package/utils/cardano.d.ts +2 -0
- package/utils/cardano.js +12 -0
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/price.d.ts +3 -0
- package/utils/price.js +20 -0
- package/cjs/utils/canDerive.js +0 -12
- package/utils/canDerive.d.ts +0 -2
- package/utils/canDerive.js +0 -6
- /package/cjs/page/{Accounts.js → substrate/Accounts.js} +0 -0
- /package/cjs/page/{Metadata.js → substrate/Metadata.js} +0 -0
- /package/cjs/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
- /package/cjs/page/{Signer.js → substrate/Signer.js} +0 -0
- /package/cjs/page/{Injected.js → substrate/index.js} +0 -0
- /package/page/{Accounts.js → substrate/Accounts.js} +0 -0
- /package/page/{Metadata.js → substrate/Metadata.js} +0 -0
- /package/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
- /package/page/{Signer.js → substrate/Signer.js} +0 -0
- /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
|
-
|
|
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 {
|
|
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
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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;
|