btc-wallet 0.5.11-beta → 0.5.13-beta
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/config.d.ts +4 -1
- package/dist/core/btcUtils.d.ts +17 -9
- package/dist/index.js +270 -146
- package/dist/index.js.map +2 -2
- package/dist/utils/nearUtils.d.ts +7 -1
- package/dist/utils/request.d.ts +1 -0
- package/esm/index.js +270 -146
- package/esm/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -102,7 +102,7 @@ __export(src_exports, {
|
|
102
102
|
getConfig: () => getConfig,
|
103
103
|
getCsnaAccountId: () => getCsnaAccountId,
|
104
104
|
getDepositAmount: () => getDepositAmount,
|
105
|
-
|
105
|
+
getTokenBalance: () => getTokenBalance,
|
106
106
|
getVersion: () => getVersion,
|
107
107
|
getWithdrawTransaction: () => getWithdrawTransaction,
|
108
108
|
sendBitcoin: () => sendBitcoin,
|
@@ -432,11 +432,11 @@ var MobileWalletConnect = class {
|
|
432
432
|
}
|
433
433
|
static redirectToWallet(walletId) {
|
434
434
|
return __async(this, null, function* () {
|
435
|
-
var _a;
|
436
435
|
if (isMobile()) {
|
437
436
|
const currentUrl = window.location.href;
|
438
437
|
const universalLink = this.getUniversalLink(walletId, currentUrl);
|
439
|
-
|
438
|
+
const showGuideDialog = () => __async(this, null, function* () {
|
439
|
+
var _a;
|
440
440
|
try {
|
441
441
|
yield (_a = navigator.clipboard) == null ? void 0 : _a.writeText(currentUrl);
|
442
442
|
} catch (error) {
|
@@ -454,9 +454,23 @@ var MobileWalletConnect = class {
|
|
454
454
|
`,
|
455
455
|
dangerouslyUseHTML: true
|
456
456
|
});
|
457
|
+
});
|
458
|
+
if (!universalLink) {
|
459
|
+
yield showGuideDialog();
|
457
460
|
return false;
|
458
461
|
}
|
462
|
+
const openWallet = () => {
|
463
|
+
const iframe = document.createElement("iframe");
|
464
|
+
iframe.style.display = "none";
|
465
|
+
iframe.src = universalLink;
|
466
|
+
document.body.appendChild(iframe);
|
467
|
+
setTimeout(() => __async(this, null, function* () {
|
468
|
+
document.body.removeChild(iframe);
|
469
|
+
yield showGuideDialog();
|
470
|
+
}), 2e3);
|
471
|
+
};
|
459
472
|
window.location.href = universalLink;
|
473
|
+
setTimeout(openWallet, 100);
|
460
474
|
return true;
|
461
475
|
}
|
462
476
|
return false;
|
@@ -2870,7 +2884,10 @@ var import_js_sha256 = require("js-sha256");
|
|
2870
2884
|
var walletConfig = {
|
2871
2885
|
dev: {
|
2872
2886
|
base_url: "https://api.dev.satoshibridge.top",
|
2873
|
-
|
2887
|
+
btcToken: "nbtc-dev.testnet",
|
2888
|
+
btcTokenDecimals: 8,
|
2889
|
+
nearToken: "wrap.testnet",
|
2890
|
+
nearTokenDecimals: 24,
|
2874
2891
|
accountContractId: "acc-dev.testnet",
|
2875
2892
|
bridgeContractId: "brg-dev.testnet",
|
2876
2893
|
walletUrl: "https://wallet-dev.satoshibridge.top",
|
@@ -2878,7 +2895,10 @@ var walletConfig = {
|
|
2878
2895
|
},
|
2879
2896
|
testnet: {
|
2880
2897
|
base_url: "https://api.testnet.satoshibridge.top",
|
2881
|
-
|
2898
|
+
btcToken: "nbtc2-nsp.testnet",
|
2899
|
+
btcTokenDecimals: 8,
|
2900
|
+
nearToken: "wrap.testnet",
|
2901
|
+
nearTokenDecimals: 24,
|
2882
2902
|
accountContractId: "acc2-nsp.testnet",
|
2883
2903
|
bridgeContractId: "brg2-nsp.testnet",
|
2884
2904
|
walletUrl: "https://wallet-test.satoshibridge.top",
|
@@ -2886,7 +2906,10 @@ var walletConfig = {
|
|
2886
2906
|
},
|
2887
2907
|
private_mainnet: {
|
2888
2908
|
base_url: "https://api.stg.satoshibridge.top",
|
2889
|
-
|
2909
|
+
btcToken: "nbtc.toalice.near",
|
2910
|
+
btcTokenDecimals: 8,
|
2911
|
+
nearToken: "wrap.near",
|
2912
|
+
nearTokenDecimals: 24,
|
2890
2913
|
accountContractId: "acc.toalice.near",
|
2891
2914
|
bridgeContractId: "brg.toalice.near",
|
2892
2915
|
walletUrl: "https://wallet-stg.satoshibridge.top",
|
@@ -2894,7 +2917,10 @@ var walletConfig = {
|
|
2894
2917
|
},
|
2895
2918
|
mainnet: {
|
2896
2919
|
base_url: "https://api.satos.network",
|
2897
|
-
|
2920
|
+
btcToken: "nbtc.bridge.near",
|
2921
|
+
btcTokenDecimals: 8,
|
2922
|
+
nearToken: "wrap.near",
|
2923
|
+
nearTokenDecimals: 24,
|
2898
2924
|
accountContractId: "acc.ref-labs.near",
|
2899
2925
|
bridgeContractId: "btc-connector.bridge.near",
|
2900
2926
|
walletUrl: "https://wallet.satoshibridge.top",
|
@@ -2920,69 +2946,24 @@ var import_big = __toESM(require("big.js"), 1);
|
|
2920
2946
|
|
2921
2947
|
// src/utils/nearUtils.ts
|
2922
2948
|
var import_near_api_js = require("near-api-js");
|
2923
|
-
function nearCallFunction(contractId, methodName, args, options) {
|
2924
|
-
return __async(this, null, function* () {
|
2925
|
-
const nearProvider = (options == null ? void 0 : options.provider) || new import_near_api_js.providers.FailoverRpcProvider(
|
2926
|
-
nearRpcUrls[options == null ? void 0 : options.network].map(
|
2927
|
-
(url) => new import_near_api_js.providers.JsonRpcProvider({ url })
|
2928
|
-
)
|
2929
|
-
);
|
2930
|
-
const res = yield nearProvider.query({
|
2931
|
-
request_type: "call_function",
|
2932
|
-
account_id: contractId,
|
2933
|
-
method_name: methodName,
|
2934
|
-
args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
|
2935
|
-
finality: "final"
|
2936
|
-
});
|
2937
|
-
return JSON.parse(Buffer.from(res.result).toString());
|
2938
|
-
});
|
2939
|
-
}
|
2940
|
-
function pollTransactionStatuses(network, hashes) {
|
2941
|
-
return __async(this, null, function* () {
|
2942
|
-
const provider = new import_near_api_js.providers.FailoverRpcProvider(
|
2943
|
-
Object.values(nearRpcUrls[network]).map(
|
2944
|
-
(url) => new import_near_api_js.providers.JsonRpcProvider({ url })
|
2945
|
-
)
|
2946
|
-
);
|
2947
|
-
const maxAttempts = 30;
|
2948
|
-
let currentAttempt = 0;
|
2949
|
-
const pendingHashes = new Set(hashes);
|
2950
|
-
const results = /* @__PURE__ */ new Map();
|
2951
|
-
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
2952
|
-
currentAttempt++;
|
2953
|
-
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
2954
|
-
try {
|
2955
|
-
const result2 = yield provider.txStatus(hash, "unused", "FINAL");
|
2956
|
-
if (result2 && result2.status) {
|
2957
|
-
console.log(`Transaction ${hash} result:`, result2);
|
2958
|
-
results.set(hash, result2);
|
2959
|
-
pendingHashes.delete(hash);
|
2960
|
-
}
|
2961
|
-
} catch (error) {
|
2962
|
-
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
2963
|
-
}
|
2964
|
-
}));
|
2965
|
-
yield Promise.all(promises);
|
2966
|
-
if (pendingHashes.size > 0) {
|
2967
|
-
if (currentAttempt === maxAttempts) {
|
2968
|
-
throw new Error(
|
2969
|
-
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
2970
|
-
);
|
2971
|
-
}
|
2972
|
-
console.log(
|
2973
|
-
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
2974
|
-
);
|
2975
|
-
yield delay(1e4);
|
2976
|
-
}
|
2977
|
-
}
|
2978
|
-
const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
|
2979
|
-
return result;
|
2980
|
-
});
|
2981
|
-
}
|
2982
2949
|
|
2983
2950
|
// src/utils/request.ts
|
2984
2951
|
var cache = /* @__PURE__ */ new Map();
|
2985
2952
|
var defaultCacheTimeout = 3e3;
|
2953
|
+
function withCache(key, fetcher, timeout = defaultCacheTimeout) {
|
2954
|
+
const cached = cache.get(key);
|
2955
|
+
const isCacheValid = cached && Date.now() - cached.timestamp < timeout;
|
2956
|
+
if (isCacheValid) {
|
2957
|
+
return Promise.resolve(cached.data);
|
2958
|
+
}
|
2959
|
+
return fetcher().then((data) => {
|
2960
|
+
cache.set(key, { timestamp: Date.now(), data });
|
2961
|
+
setTimeout(() => {
|
2962
|
+
cache.delete(key);
|
2963
|
+
}, timeout);
|
2964
|
+
return data;
|
2965
|
+
});
|
2966
|
+
}
|
2986
2967
|
function request(url, options) {
|
2987
2968
|
return __async(this, null, function* () {
|
2988
2969
|
var _a;
|
@@ -3024,13 +3005,7 @@ function request(url, options) {
|
|
3024
3005
|
if (options.shouldStopPolling(data)) {
|
3025
3006
|
return data;
|
3026
3007
|
}
|
3027
|
-
|
3028
|
-
yield new Promise((resolve) => setTimeout(resolve, options.pollingInterval));
|
3029
|
-
return request(url, __spreadProps(__spreadValues({}, options), {
|
3030
|
-
maxPollingAttempts: options.maxPollingAttempts - 1
|
3031
|
-
}));
|
3032
|
-
}
|
3033
|
-
throw new Error("Polling failed: maximum attempts reached without meeting the condition");
|
3008
|
+
throw new Error("Polling should continue");
|
3034
3009
|
}
|
3035
3010
|
if (cacheKey) {
|
3036
3011
|
cache.set(cacheKey, { timestamp: Date.now(), data });
|
@@ -3040,6 +3015,7 @@ function request(url, options) {
|
|
3040
3015
|
}
|
3041
3016
|
return data;
|
3042
3017
|
} catch (err) {
|
3018
|
+
console.error(err);
|
3043
3019
|
if (retryCount > 0) {
|
3044
3020
|
console.log(`Retrying... attempts left: ${retryCount}`);
|
3045
3021
|
return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
|
@@ -3053,8 +3029,85 @@ function request(url, options) {
|
|
3053
3029
|
}));
|
3054
3030
|
}
|
3055
3031
|
}
|
3056
|
-
|
3032
|
+
return Promise.reject(err);
|
3033
|
+
}
|
3034
|
+
});
|
3035
|
+
}
|
3036
|
+
|
3037
|
+
// src/utils/nearUtils.ts
|
3038
|
+
function getNearProvider(option) {
|
3039
|
+
return option.provider || new import_near_api_js.providers.FailoverRpcProvider(
|
3040
|
+
nearRpcUrls[option == null ? void 0 : option.network].map(
|
3041
|
+
(url) => new import_near_api_js.providers.JsonRpcProvider({ url })
|
3042
|
+
)
|
3043
|
+
);
|
3044
|
+
}
|
3045
|
+
function nearCallFunction(_0, _1, _2) {
|
3046
|
+
return __async(this, arguments, function* (contractId, methodName, args, options = {}) {
|
3047
|
+
if (!options.skipCache) {
|
3048
|
+
const cacheKey = `near:${contractId}:${methodName}:${args ? JSON.stringify(args) : ""}`;
|
3049
|
+
return withCache(
|
3050
|
+
cacheKey,
|
3051
|
+
() => executeNearCall(contractId, methodName, args, options),
|
3052
|
+
options.cacheTimeout
|
3053
|
+
);
|
3054
|
+
}
|
3055
|
+
return executeNearCall(contractId, methodName, args, options);
|
3056
|
+
});
|
3057
|
+
}
|
3058
|
+
function executeNearCall(contractId, methodName, args, options) {
|
3059
|
+
return __async(this, null, function* () {
|
3060
|
+
const nearProvider = getNearProvider(options);
|
3061
|
+
const res = yield nearProvider.query({
|
3062
|
+
request_type: "call_function",
|
3063
|
+
account_id: contractId,
|
3064
|
+
method_name: methodName,
|
3065
|
+
args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
|
3066
|
+
finality: "final"
|
3067
|
+
});
|
3068
|
+
return JSON.parse(Buffer.from(res.result).toString());
|
3069
|
+
});
|
3070
|
+
}
|
3071
|
+
function pollTransactionStatuses(network, hashes) {
|
3072
|
+
return __async(this, null, function* () {
|
3073
|
+
const provider = new import_near_api_js.providers.FailoverRpcProvider(
|
3074
|
+
Object.values(nearRpcUrls[network]).map(
|
3075
|
+
(url) => new import_near_api_js.providers.JsonRpcProvider({ url })
|
3076
|
+
)
|
3077
|
+
);
|
3078
|
+
const maxAttempts = 30;
|
3079
|
+
let currentAttempt = 0;
|
3080
|
+
const pendingHashes = new Set(hashes);
|
3081
|
+
const results = /* @__PURE__ */ new Map();
|
3082
|
+
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
3083
|
+
currentAttempt++;
|
3084
|
+
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
3085
|
+
try {
|
3086
|
+
const result2 = yield provider.txStatus(hash, "unused", "FINAL");
|
3087
|
+
if (result2 && result2.status) {
|
3088
|
+
console.log(`Transaction ${hash} result:`, result2);
|
3089
|
+
results.set(hash, result2);
|
3090
|
+
pendingHashes.delete(hash);
|
3091
|
+
}
|
3092
|
+
} catch (error) {
|
3093
|
+
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
3094
|
+
}
|
3095
|
+
}));
|
3096
|
+
yield Promise.all(promises);
|
3097
|
+
if (pendingHashes.size > 0) {
|
3098
|
+
if (currentAttempt === maxAttempts) {
|
3099
|
+
throw new Error(
|
3100
|
+
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
3101
|
+
);
|
3102
|
+
}
|
3103
|
+
console.log(
|
3104
|
+
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
3105
|
+
);
|
3106
|
+
yield delay(1e4);
|
3107
|
+
}
|
3057
3108
|
}
|
3109
|
+
const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
|
3110
|
+
return result;
|
3058
3111
|
});
|
3059
3112
|
}
|
3060
3113
|
|
@@ -3211,9 +3264,10 @@ function nearCall(contractId, methodName, args) {
|
|
3211
3264
|
return nearCallFunction(contractId, methodName, args, { network });
|
3212
3265
|
});
|
3213
3266
|
}
|
3214
|
-
function getAccountInfo(
|
3215
|
-
return __async(this,
|
3216
|
-
const
|
3267
|
+
function getAccountInfo(_0) {
|
3268
|
+
return __async(this, arguments, function* ({ csna, env }) {
|
3269
|
+
const config = yield getConfig(env);
|
3270
|
+
const accountInfo = yield nearCall(config.accountContractId, "get_account", {
|
3217
3271
|
account_id: csna
|
3218
3272
|
}).catch((error) => {
|
3219
3273
|
return void 0;
|
@@ -3222,16 +3276,46 @@ function getAccountInfo(csna, accountContractId) {
|
|
3222
3276
|
return accountInfo;
|
3223
3277
|
});
|
3224
3278
|
}
|
3225
|
-
function
|
3279
|
+
function getTokenBalance(_0) {
|
3280
|
+
return __async(this, arguments, function* ({
|
3281
|
+
csna,
|
3282
|
+
tokenId,
|
3283
|
+
env
|
3284
|
+
}) {
|
3285
|
+
const network = yield getNetwork();
|
3286
|
+
const config = yield getConfig(env);
|
3287
|
+
const nearProvider = getNearProvider({ network });
|
3288
|
+
try {
|
3289
|
+
if (tokenId === config.nearToken) {
|
3290
|
+
const nearAccount = yield nearProvider.query({
|
3291
|
+
request_type: "view_account",
|
3292
|
+
account_id: csna,
|
3293
|
+
finality: "final"
|
3294
|
+
});
|
3295
|
+
const balance = parseFloat(nearAccount.amount) / __pow(10, config.nearTokenDecimals);
|
3296
|
+
return { balance, rawBalance: nearAccount.amount };
|
3297
|
+
} else {
|
3298
|
+
const res = yield nearCall(tokenId, "ft_balance_of", { account_id: csna });
|
3299
|
+
const decimals = tokenId === config.btcToken ? config.btcTokenDecimals : (yield nearCall(tokenId, "ft_metadata", {})).decimals;
|
3300
|
+
const balance = parseFloat(res) / __pow(10, decimals);
|
3301
|
+
return { balance, rawBalance: res };
|
3302
|
+
}
|
3303
|
+
} catch (error) {
|
3304
|
+
console.error("getTokenBalance error:", error);
|
3305
|
+
return { balance: 0, rawBalance: "0" };
|
3306
|
+
}
|
3307
|
+
});
|
3308
|
+
}
|
3309
|
+
function checkGasTokenBalance(csna, minAmount, env) {
|
3226
3310
|
return __async(this, null, function* () {
|
3227
|
-
const
|
3228
|
-
|
3229
|
-
|
3311
|
+
const config = yield getConfig(env);
|
3312
|
+
const { rawBalance } = yield getTokenBalance({ csna, tokenId: config.btcToken, env });
|
3313
|
+
console.log("gas token balance:", rawBalance);
|
3314
|
+
if (new import_big.default(rawBalance).lt(minAmount)) {
|
3230
3315
|
yield Dialog.confirm({
|
3231
3316
|
title: "Gas token balance is insufficient",
|
3232
3317
|
message: "Please deposit gas token to continue, will open bridge website."
|
3233
3318
|
});
|
3234
|
-
const config = yield getConfig(env);
|
3235
3319
|
window.open(config.bridgeUrl, "_blank");
|
3236
3320
|
throw new Error("Gas token balance is insufficient");
|
3237
3321
|
}
|
@@ -3312,18 +3396,6 @@ function getBtcBalance() {
|
|
3312
3396
|
};
|
3313
3397
|
});
|
3314
3398
|
}
|
3315
|
-
function getNBTCBalance(address, env) {
|
3316
|
-
return __async(this, null, function* () {
|
3317
|
-
const config = yield getConfig(env || "mainnet");
|
3318
|
-
const rawBalance = yield nearCall(config.token, "ft_balance_of", {
|
3319
|
-
account_id: address
|
3320
|
-
});
|
3321
|
-
const balance = new import_big.default(rawBalance).div(__pow(10, 8)).round(8, import_big.default.roundDown).toNumber();
|
3322
|
-
const rawAvailableBalance = new import_big.default(rawBalance).minus(1e3).toNumber();
|
3323
|
-
const availableBalance = new import_big.default(rawAvailableBalance).div(__pow(10, 8)).round(8, import_big.default.roundDown).toNumber();
|
3324
|
-
return { balance, availableBalance, rawBalance, rawAvailableBalance };
|
3325
|
-
});
|
3326
|
-
}
|
3327
3399
|
function sendBitcoin(address, amount, feeRate) {
|
3328
3400
|
return __async(this, null, function* () {
|
3329
3401
|
const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
|
@@ -3343,7 +3415,7 @@ function getDepositAmount(amount, option) {
|
|
3343
3415
|
const _newAccountMinDepositAmount = (_a = option == null ? void 0 : option.newAccountMinDepositAmount) != null ? _a : true;
|
3344
3416
|
const config = yield getConfig(env);
|
3345
3417
|
const csna = yield getCsnaAccountId(env);
|
3346
|
-
const accountInfo = yield getAccountInfo(csna,
|
3418
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
3347
3419
|
const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
|
3348
3420
|
const repayAmount = (debtAction == null ? void 0 : debtAction.amount) || 0;
|
3349
3421
|
const {
|
@@ -3422,7 +3494,7 @@ function executeBTCDepositAndAction(_0) {
|
|
3422
3494
|
env,
|
3423
3495
|
newAccountMinDepositAmount
|
3424
3496
|
});
|
3425
|
-
const accountInfo = yield getAccountInfo(csna,
|
3497
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
3426
3498
|
const newActions = [];
|
3427
3499
|
const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
|
3428
3500
|
if (debtAction) {
|
@@ -3436,12 +3508,12 @@ function executeBTCDepositAndAction(_0) {
|
|
3436
3508
|
}));
|
3437
3509
|
}
|
3438
3510
|
const storageDepositMsg = {};
|
3439
|
-
const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.
|
3511
|
+
const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.btcToken, "storage_balance_of", {
|
3440
3512
|
account_id: csna
|
3441
3513
|
});
|
3442
3514
|
if (!(registerRes == null ? void 0 : registerRes.available)) {
|
3443
3515
|
storageDepositMsg.storage_deposit_msg = {
|
3444
|
-
contract_id: (action == null ? void 0 : action.receiver_id) || config.
|
3516
|
+
contract_id: (action == null ? void 0 : action.receiver_id) || config.btcToken,
|
3445
3517
|
deposit: registerDeposit || NEAR_STORAGE_DEPOSIT_AMOUNT,
|
3446
3518
|
registration_only: true
|
3447
3519
|
};
|
@@ -3536,7 +3608,7 @@ function getWithdrawTransaction(_0) {
|
|
3536
3608
|
env = "mainnet"
|
3537
3609
|
}) {
|
3538
3610
|
const provider = getBtcProvider();
|
3539
|
-
const btcAddress =
|
3611
|
+
const btcAddress = provider.account;
|
3540
3612
|
const config = yield getConfig(env);
|
3541
3613
|
const brgConfig = yield nearCall(config.bridgeContractId, "get_config", {});
|
3542
3614
|
if (brgConfig.min_withdraw_amount) {
|
@@ -3560,7 +3632,7 @@ function getWithdrawTransaction(_0) {
|
|
3560
3632
|
};
|
3561
3633
|
});
|
3562
3634
|
const _feeRate = feeRate || (yield getBtcGasPrice());
|
3563
|
-
|
3635
|
+
let { inputs, outputs, fee } = (0, import_coinselect.default)(
|
3564
3636
|
utxos,
|
3565
3637
|
[{ address: btcAddress, value: Number(amount) }],
|
3566
3638
|
Math.ceil(_feeRate)
|
@@ -3569,32 +3641,61 @@ function getWithdrawTransaction(_0) {
|
|
3569
3641
|
throw new Error("The network is busy, please try again later.");
|
3570
3642
|
}
|
3571
3643
|
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
3572
|
-
const
|
3573
|
-
const
|
3574
|
-
if (
|
3644
|
+
const transactionFee = fee;
|
3645
|
+
const changeAddress = brgConfig.change_address;
|
3646
|
+
if (transactionFee > maxBtcFee) {
|
3575
3647
|
throw new Error("Gas exceeds maximum value");
|
3576
3648
|
}
|
3577
|
-
let
|
3649
|
+
let recipientOutput, changeOutput;
|
3578
3650
|
for (let i = 0; i < outputs.length; i++) {
|
3579
3651
|
const output = outputs[i];
|
3580
3652
|
if (output.value.toString() === amount.toString()) {
|
3581
|
-
|
3653
|
+
recipientOutput = output;
|
3582
3654
|
} else {
|
3583
|
-
|
3655
|
+
changeOutput = output;
|
3584
3656
|
}
|
3585
3657
|
if (!output.address) {
|
3586
|
-
output.address =
|
3658
|
+
output.address = changeAddress;
|
3587
3659
|
}
|
3588
3660
|
}
|
3589
|
-
|
3590
|
-
if (
|
3591
|
-
|
3661
|
+
recipientOutput.value = new import_big.default(recipientOutput.value).minus(transactionFee).minus(withdrawFee).toNumber();
|
3662
|
+
if (changeOutput) {
|
3663
|
+
changeOutput.value = new import_big.default(changeOutput.value).plus(transactionFee).plus(withdrawFee).toNumber();
|
3664
|
+
const remainingInputs = [...inputs];
|
3665
|
+
let smallestInput = Math.min.apply(
|
3666
|
+
null,
|
3667
|
+
remainingInputs.map((input) => input.value)
|
3668
|
+
);
|
3669
|
+
let remainingChangeAmount = changeOutput.value;
|
3670
|
+
while (remainingChangeAmount >= smallestInput && smallestInput > 0 && remainingInputs.length > 0) {
|
3671
|
+
remainingChangeAmount -= smallestInput;
|
3672
|
+
changeOutput.value = remainingChangeAmount;
|
3673
|
+
const smallestInputIndex = remainingInputs.findIndex(
|
3674
|
+
(input) => input.value === smallestInput
|
3675
|
+
);
|
3676
|
+
if (smallestInputIndex > -1) {
|
3677
|
+
remainingInputs.splice(smallestInputIndex, 1);
|
3678
|
+
}
|
3679
|
+
smallestInput = Math.min.apply(
|
3680
|
+
null,
|
3681
|
+
remainingInputs.map((input) => input.value)
|
3682
|
+
);
|
3683
|
+
}
|
3684
|
+
const minChangeAmount = Number(brgConfig.min_change_amount);
|
3685
|
+
let additionalFee = 0;
|
3686
|
+
if (changeOutput.value === 0) {
|
3687
|
+
outputs = outputs.filter((item) => item.value !== 0);
|
3688
|
+
} else if (changeOutput.value < minChangeAmount) {
|
3689
|
+
additionalFee = minChangeAmount - changeOutput.value;
|
3690
|
+
recipientOutput.value -= additionalFee;
|
3691
|
+
changeOutput.value = minChangeAmount;
|
3692
|
+
}
|
3592
3693
|
} else {
|
3593
|
-
|
3594
|
-
address:
|
3595
|
-
value: new import_big.default(
|
3694
|
+
changeOutput = {
|
3695
|
+
address: changeAddress,
|
3696
|
+
value: new import_big.default(transactionFee).plus(withdrawFee).toNumber()
|
3596
3697
|
};
|
3597
|
-
outputs.push(
|
3698
|
+
outputs.push(changeOutput);
|
3598
3699
|
}
|
3599
3700
|
const insufficientOutput = outputs.some((item) => item.value < 0);
|
3600
3701
|
if (insufficientOutput) {
|
@@ -3602,7 +3703,7 @@ function getWithdrawTransaction(_0) {
|
|
3602
3703
|
}
|
3603
3704
|
const inputSum = inputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3604
3705
|
const outputSum = outputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3605
|
-
if (
|
3706
|
+
if (transactionFee + outputSum !== inputSum) {
|
3606
3707
|
throw new Error("compute error");
|
3607
3708
|
}
|
3608
3709
|
const network = yield getNetwork();
|
@@ -3647,7 +3748,7 @@ function getWithdrawTransaction(_0) {
|
|
3647
3748
|
};
|
3648
3749
|
const csna = yield getCsnaAccountId(env);
|
3649
3750
|
const transaction = {
|
3650
|
-
receiverId: config.
|
3751
|
+
receiverId: config.btcToken,
|
3651
3752
|
signerId: csna,
|
3652
3753
|
actions: [
|
3653
3754
|
{
|
@@ -4191,20 +4292,16 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4191
4292
|
throw new Error("Wallet state is invalid, please reconnect your wallet.");
|
4192
4293
|
}
|
4193
4294
|
const btcContext = window.btcContext;
|
4194
|
-
const
|
4195
|
-
const accountInfo = yield getAccountInfo(
|
4295
|
+
const csna = state.getAccount();
|
4296
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
4196
4297
|
yield checkGasTokenDebt(accountInfo, env, true);
|
4197
4298
|
const trans = [...params.transactions];
|
4198
4299
|
console.log("signAndSendTransactions raw trans:", trans);
|
4199
|
-
const
|
4200
|
-
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(
|
4201
|
-
gasTokenBalance,
|
4202
|
-
trans
|
4203
|
-
);
|
4300
|
+
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
|
4204
4301
|
console.log("transferGasTransaction:", transferGasTransaction);
|
4205
4302
|
console.log("useNearPayGas:", useNearPayGas);
|
4206
4303
|
console.log("gasLimit:", gasLimit);
|
4207
|
-
yield checkGasTokenBalance(
|
4304
|
+
yield checkGasTokenBalance(csna, gasLimit, env);
|
4208
4305
|
if (transferGasTransaction) {
|
4209
4306
|
trans.unshift(transferGasTransaction);
|
4210
4307
|
}
|
@@ -4212,14 +4309,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4212
4309
|
const newTrans = yield Promise.all(
|
4213
4310
|
trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
4214
4311
|
);
|
4215
|
-
const nonceFromApi = yield getNonce(currentConfig.base_url,
|
4312
|
+
const nonceFromApi = yield getNonce(currentConfig.base_url, csna);
|
4216
4313
|
const nonceFromContract = (accountInfo == null ? void 0 : accountInfo.nonce) || 0;
|
4217
4314
|
const nonce = Number(nonceFromApi) > Number(nonceFromContract) ? String(nonceFromApi) : String(nonceFromContract);
|
4218
4315
|
const intention = {
|
4219
4316
|
chain_id: "397",
|
4220
|
-
csna
|
4317
|
+
csna,
|
4221
4318
|
near_transactions: newTrans.map((t) => t.txHex),
|
4222
|
-
gas_token: currentConfig.
|
4319
|
+
gas_token: currentConfig.btcToken,
|
4223
4320
|
gas_limit: gasLimit,
|
4224
4321
|
use_near_pay_gas: useNearPayGas,
|
4225
4322
|
nonce
|
@@ -4232,7 +4329,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4232
4329
|
data: toHex(strIntention)
|
4233
4330
|
});
|
4234
4331
|
yield checkBtcTransactionStatus(currentConfig.base_url, signature);
|
4235
|
-
const hash = newTrans.map((t) => t.hash);
|
4332
|
+
const hash = newTrans.slice(1).map((t) => t.hash);
|
4236
4333
|
console.log("txHash:", hash);
|
4237
4334
|
const result = yield pollTransactionStatuses(options.network.networkId, hash);
|
4238
4335
|
return result;
|
@@ -4240,12 +4337,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4240
4337
|
}
|
4241
4338
|
function calculateGasLimit(params) {
|
4242
4339
|
return __async(this, null, function* () {
|
4243
|
-
const accountId = state.getAccount();
|
4244
|
-
const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
|
4245
4340
|
const trans = [...params.transactions];
|
4246
4341
|
console.log("raw trans:", trans);
|
4247
|
-
const
|
4248
|
-
const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
|
4342
|
+
const { gasLimit } = yield calculateGasStrategy(trans);
|
4249
4343
|
return gasLimit;
|
4250
4344
|
});
|
4251
4345
|
}
|
@@ -4253,7 +4347,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4253
4347
|
return __async(this, null, function* () {
|
4254
4348
|
return {
|
4255
4349
|
signerId: accountId,
|
4256
|
-
receiverId: currentConfig.
|
4350
|
+
receiverId: currentConfig.btcToken,
|
4257
4351
|
actions: [
|
4258
4352
|
{
|
4259
4353
|
type: "FunctionCall",
|
@@ -4281,7 +4375,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4281
4375
|
} else {
|
4282
4376
|
newGasLimit = yield getPredictedGasAmount(
|
4283
4377
|
currentConfig.accountContractId,
|
4284
|
-
currentConfig.
|
4378
|
+
currentConfig.btcToken,
|
4285
4379
|
[transferTxHex, ...transactions2.map((t) => t.txHex)]
|
4286
4380
|
);
|
4287
4381
|
}
|
@@ -4302,31 +4396,61 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4302
4396
|
return gasAmount.toString();
|
4303
4397
|
});
|
4304
4398
|
}
|
4305
|
-
function calculateGasStrategy(
|
4399
|
+
function calculateGasStrategy(transactions2) {
|
4306
4400
|
return __async(this, null, function* () {
|
4307
4401
|
var _a;
|
4308
4402
|
const accountId = state.getAccount();
|
4309
|
-
const
|
4310
|
-
|
4311
|
-
|
4312
|
-
|
4403
|
+
const accountInfo = yield getAccountInfo({ csna: accountId, env });
|
4404
|
+
const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.btcToken]) || "0";
|
4405
|
+
const { balance: nearBalance } = yield getTokenBalance({
|
4406
|
+
csna: accountId,
|
4407
|
+
tokenId: currentConfig.nearToken,
|
4408
|
+
env
|
4313
4409
|
});
|
4314
|
-
const
|
4315
|
-
|
4410
|
+
const { balance: btcBalance } = yield getTokenBalance({
|
4411
|
+
csna: accountId,
|
4412
|
+
tokenId: currentConfig.btcToken,
|
4413
|
+
env
|
4414
|
+
});
|
4415
|
+
const transferAmount = transactions2.reduce(
|
4416
|
+
(acc, tx) => {
|
4417
|
+
tx.actions.forEach((action) => {
|
4418
|
+
if (action.params.deposit) {
|
4419
|
+
const amount = Number(action.params.deposit) / __pow(10, currentConfig.nearTokenDecimals);
|
4420
|
+
console.log("near deposit amount:", amount);
|
4421
|
+
acc.near = acc.near.plus(amount);
|
4422
|
+
}
|
4423
|
+
if (tx.receiverId === currentConfig.btcToken && ["ft_transfer_call", "ft_transfer"].includes(action.params.methodName)) {
|
4424
|
+
const amount = Number(action.params.args.amount) / __pow(10, currentConfig.btcTokenDecimals);
|
4425
|
+
console.log("btc transfer amount:", amount);
|
4426
|
+
acc.btc = acc.btc.plus(amount);
|
4427
|
+
}
|
4428
|
+
});
|
4429
|
+
return acc;
|
4430
|
+
},
|
4431
|
+
{ near: new import_big2.default(0), btc: new import_big2.default(0) }
|
4432
|
+
);
|
4433
|
+
const nearAvailableBalance = new import_big2.default(nearBalance).minus(transferAmount.near).toNumber();
|
4434
|
+
const btcAvailableBalance = new import_big2.default(btcBalance).minus(transferAmount.btc).toNumber();
|
4435
|
+
if (btcAvailableBalance < 8e-6) {
|
4436
|
+
throw new Error("BTC balance is not enough, please deposit more BTC.");
|
4437
|
+
}
|
4438
|
+
console.log("available near balance:", nearAvailableBalance);
|
4439
|
+
console.log("available btc balance:", btcAvailableBalance);
|
4316
4440
|
console.log("available gas token balance:", gasTokenBalance);
|
4317
4441
|
const convertTx = yield Promise.all(
|
4318
4442
|
transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
4319
4443
|
);
|
4320
|
-
if (
|
4444
|
+
if (nearAvailableBalance > 0.5) {
|
4321
4445
|
console.log("near balance is enough, get the protocol fee of each transaction");
|
4322
4446
|
const gasTokens = yield nearCall2(
|
4323
4447
|
currentConfig.accountContractId,
|
4324
4448
|
"list_gas_token",
|
4325
|
-
{ token_ids: [currentConfig.
|
4449
|
+
{ token_ids: [currentConfig.btcToken] }
|
4326
4450
|
);
|
4327
4451
|
console.log("list_gas_token gas tokens:", gasTokens);
|
4328
4452
|
const perTxFee = Math.max(
|
4329
|
-
Number(((_a = gasTokens[currentConfig.
|
4453
|
+
Number(((_a = gasTokens[currentConfig.btcToken]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
|
4330
4454
|
100
|
4331
4455
|
);
|
4332
4456
|
console.log("perTxFee:", perTxFee);
|
@@ -4344,7 +4468,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4344
4468
|
console.log("near balance is not enough, predict the gas token amount required");
|
4345
4469
|
const adjustedGas = yield getPredictedGasAmount(
|
4346
4470
|
currentConfig.accountContractId,
|
4347
|
-
currentConfig.
|
4471
|
+
currentConfig.btcToken,
|
4348
4472
|
convertTx.map((t) => t.txHex)
|
4349
4473
|
);
|
4350
4474
|
if (new import_big2.default(gasTokenBalance).gte(adjustedGas)) {
|
@@ -4460,7 +4584,7 @@ function setupBTCWallet({
|
|
4460
4584
|
|
4461
4585
|
// src/index.ts
|
4462
4586
|
var getVersion = () => {
|
4463
|
-
return "0.5.
|
4587
|
+
return "0.5.13-beta";
|
4464
4588
|
};
|
4465
4589
|
if (typeof window !== "undefined") {
|
4466
4590
|
window.__BTC_WALLET_VERSION = getVersion();
|