btc-wallet 0.5.11-beta → 0.5.13-beta
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/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/esm/index.js
CHANGED
@@ -368,11 +368,11 @@ var MobileWalletConnect = class {
|
|
368
368
|
}
|
369
369
|
static redirectToWallet(walletId) {
|
370
370
|
return __async(this, null, function* () {
|
371
|
-
var _a;
|
372
371
|
if (isMobile()) {
|
373
372
|
const currentUrl = window.location.href;
|
374
373
|
const universalLink = this.getUniversalLink(walletId, currentUrl);
|
375
|
-
|
374
|
+
const showGuideDialog = () => __async(this, null, function* () {
|
375
|
+
var _a;
|
376
376
|
try {
|
377
377
|
yield (_a = navigator.clipboard) == null ? void 0 : _a.writeText(currentUrl);
|
378
378
|
} catch (error) {
|
@@ -390,9 +390,23 @@ var MobileWalletConnect = class {
|
|
390
390
|
`,
|
391
391
|
dangerouslyUseHTML: true
|
392
392
|
});
|
393
|
+
});
|
394
|
+
if (!universalLink) {
|
395
|
+
yield showGuideDialog();
|
393
396
|
return false;
|
394
397
|
}
|
398
|
+
const openWallet = () => {
|
399
|
+
const iframe = document.createElement("iframe");
|
400
|
+
iframe.style.display = "none";
|
401
|
+
iframe.src = universalLink;
|
402
|
+
document.body.appendChild(iframe);
|
403
|
+
setTimeout(() => __async(this, null, function* () {
|
404
|
+
document.body.removeChild(iframe);
|
405
|
+
yield showGuideDialog();
|
406
|
+
}), 2e3);
|
407
|
+
};
|
395
408
|
window.location.href = universalLink;
|
409
|
+
setTimeout(openWallet, 100);
|
396
410
|
return true;
|
397
411
|
}
|
398
412
|
return false;
|
@@ -2820,7 +2834,10 @@ import { sha256 } from "js-sha256";
|
|
2820
2834
|
var walletConfig = {
|
2821
2835
|
dev: {
|
2822
2836
|
base_url: "https://api.dev.satoshibridge.top",
|
2823
|
-
|
2837
|
+
btcToken: "nbtc-dev.testnet",
|
2838
|
+
btcTokenDecimals: 8,
|
2839
|
+
nearToken: "wrap.testnet",
|
2840
|
+
nearTokenDecimals: 24,
|
2824
2841
|
accountContractId: "acc-dev.testnet",
|
2825
2842
|
bridgeContractId: "brg-dev.testnet",
|
2826
2843
|
walletUrl: "https://wallet-dev.satoshibridge.top",
|
@@ -2828,7 +2845,10 @@ var walletConfig = {
|
|
2828
2845
|
},
|
2829
2846
|
testnet: {
|
2830
2847
|
base_url: "https://api.testnet.satoshibridge.top",
|
2831
|
-
|
2848
|
+
btcToken: "nbtc2-nsp.testnet",
|
2849
|
+
btcTokenDecimals: 8,
|
2850
|
+
nearToken: "wrap.testnet",
|
2851
|
+
nearTokenDecimals: 24,
|
2832
2852
|
accountContractId: "acc2-nsp.testnet",
|
2833
2853
|
bridgeContractId: "brg2-nsp.testnet",
|
2834
2854
|
walletUrl: "https://wallet-test.satoshibridge.top",
|
@@ -2836,7 +2856,10 @@ var walletConfig = {
|
|
2836
2856
|
},
|
2837
2857
|
private_mainnet: {
|
2838
2858
|
base_url: "https://api.stg.satoshibridge.top",
|
2839
|
-
|
2859
|
+
btcToken: "nbtc.toalice.near",
|
2860
|
+
btcTokenDecimals: 8,
|
2861
|
+
nearToken: "wrap.near",
|
2862
|
+
nearTokenDecimals: 24,
|
2840
2863
|
accountContractId: "acc.toalice.near",
|
2841
2864
|
bridgeContractId: "brg.toalice.near",
|
2842
2865
|
walletUrl: "https://wallet-stg.satoshibridge.top",
|
@@ -2844,7 +2867,10 @@ var walletConfig = {
|
|
2844
2867
|
},
|
2845
2868
|
mainnet: {
|
2846
2869
|
base_url: "https://api.satos.network",
|
2847
|
-
|
2870
|
+
btcToken: "nbtc.bridge.near",
|
2871
|
+
btcTokenDecimals: 8,
|
2872
|
+
nearToken: "wrap.near",
|
2873
|
+
nearTokenDecimals: 24,
|
2848
2874
|
accountContractId: "acc.ref-labs.near",
|
2849
2875
|
bridgeContractId: "btc-connector.bridge.near",
|
2850
2876
|
walletUrl: "https://wallet.satoshibridge.top",
|
@@ -2870,69 +2896,24 @@ import Big from "big.js";
|
|
2870
2896
|
|
2871
2897
|
// src/utils/nearUtils.ts
|
2872
2898
|
import { providers } from "near-api-js";
|
2873
|
-
function nearCallFunction(contractId, methodName, args, options) {
|
2874
|
-
return __async(this, null, function* () {
|
2875
|
-
const nearProvider = (options == null ? void 0 : options.provider) || new providers.FailoverRpcProvider(
|
2876
|
-
nearRpcUrls[options == null ? void 0 : options.network].map(
|
2877
|
-
(url) => new providers.JsonRpcProvider({ url })
|
2878
|
-
)
|
2879
|
-
);
|
2880
|
-
const res = yield nearProvider.query({
|
2881
|
-
request_type: "call_function",
|
2882
|
-
account_id: contractId,
|
2883
|
-
method_name: methodName,
|
2884
|
-
args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
|
2885
|
-
finality: "final"
|
2886
|
-
});
|
2887
|
-
return JSON.parse(Buffer.from(res.result).toString());
|
2888
|
-
});
|
2889
|
-
}
|
2890
|
-
function pollTransactionStatuses(network, hashes) {
|
2891
|
-
return __async(this, null, function* () {
|
2892
|
-
const provider = new providers.FailoverRpcProvider(
|
2893
|
-
Object.values(nearRpcUrls[network]).map(
|
2894
|
-
(url) => new providers.JsonRpcProvider({ url })
|
2895
|
-
)
|
2896
|
-
);
|
2897
|
-
const maxAttempts = 30;
|
2898
|
-
let currentAttempt = 0;
|
2899
|
-
const pendingHashes = new Set(hashes);
|
2900
|
-
const results = /* @__PURE__ */ new Map();
|
2901
|
-
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
2902
|
-
currentAttempt++;
|
2903
|
-
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
2904
|
-
try {
|
2905
|
-
const result2 = yield provider.txStatus(hash, "unused", "FINAL");
|
2906
|
-
if (result2 && result2.status) {
|
2907
|
-
console.log(`Transaction ${hash} result:`, result2);
|
2908
|
-
results.set(hash, result2);
|
2909
|
-
pendingHashes.delete(hash);
|
2910
|
-
}
|
2911
|
-
} catch (error) {
|
2912
|
-
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
2913
|
-
}
|
2914
|
-
}));
|
2915
|
-
yield Promise.all(promises);
|
2916
|
-
if (pendingHashes.size > 0) {
|
2917
|
-
if (currentAttempt === maxAttempts) {
|
2918
|
-
throw new Error(
|
2919
|
-
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
2920
|
-
);
|
2921
|
-
}
|
2922
|
-
console.log(
|
2923
|
-
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
2924
|
-
);
|
2925
|
-
yield delay(1e4);
|
2926
|
-
}
|
2927
|
-
}
|
2928
|
-
const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
|
2929
|
-
return result;
|
2930
|
-
});
|
2931
|
-
}
|
2932
2899
|
|
2933
2900
|
// src/utils/request.ts
|
2934
2901
|
var cache = /* @__PURE__ */ new Map();
|
2935
2902
|
var defaultCacheTimeout = 3e3;
|
2903
|
+
function withCache(key, fetcher, timeout = defaultCacheTimeout) {
|
2904
|
+
const cached = cache.get(key);
|
2905
|
+
const isCacheValid = cached && Date.now() - cached.timestamp < timeout;
|
2906
|
+
if (isCacheValid) {
|
2907
|
+
return Promise.resolve(cached.data);
|
2908
|
+
}
|
2909
|
+
return fetcher().then((data) => {
|
2910
|
+
cache.set(key, { timestamp: Date.now(), data });
|
2911
|
+
setTimeout(() => {
|
2912
|
+
cache.delete(key);
|
2913
|
+
}, timeout);
|
2914
|
+
return data;
|
2915
|
+
});
|
2916
|
+
}
|
2936
2917
|
function request(url, options) {
|
2937
2918
|
return __async(this, null, function* () {
|
2938
2919
|
var _a;
|
@@ -2974,13 +2955,7 @@ function request(url, options) {
|
|
2974
2955
|
if (options.shouldStopPolling(data)) {
|
2975
2956
|
return data;
|
2976
2957
|
}
|
2977
|
-
|
2978
|
-
yield new Promise((resolve) => setTimeout(resolve, options.pollingInterval));
|
2979
|
-
return request(url, __spreadProps(__spreadValues({}, options), {
|
2980
|
-
maxPollingAttempts: options.maxPollingAttempts - 1
|
2981
|
-
}));
|
2982
|
-
}
|
2983
|
-
throw new Error("Polling failed: maximum attempts reached without meeting the condition");
|
2958
|
+
throw new Error("Polling should continue");
|
2984
2959
|
}
|
2985
2960
|
if (cacheKey) {
|
2986
2961
|
cache.set(cacheKey, { timestamp: Date.now(), data });
|
@@ -2990,6 +2965,7 @@ function request(url, options) {
|
|
2990
2965
|
}
|
2991
2966
|
return data;
|
2992
2967
|
} catch (err) {
|
2968
|
+
console.error(err);
|
2993
2969
|
if (retryCount > 0) {
|
2994
2970
|
console.log(`Retrying... attempts left: ${retryCount}`);
|
2995
2971
|
return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
|
@@ -3003,8 +2979,85 @@ function request(url, options) {
|
|
3003
2979
|
}));
|
3004
2980
|
}
|
3005
2981
|
}
|
3006
|
-
|
2982
|
+
return Promise.reject(err);
|
2983
|
+
}
|
2984
|
+
});
|
2985
|
+
}
|
2986
|
+
|
2987
|
+
// src/utils/nearUtils.ts
|
2988
|
+
function getNearProvider(option) {
|
2989
|
+
return option.provider || new providers.FailoverRpcProvider(
|
2990
|
+
nearRpcUrls[option == null ? void 0 : option.network].map(
|
2991
|
+
(url) => new providers.JsonRpcProvider({ url })
|
2992
|
+
)
|
2993
|
+
);
|
2994
|
+
}
|
2995
|
+
function nearCallFunction(_0, _1, _2) {
|
2996
|
+
return __async(this, arguments, function* (contractId, methodName, args, options = {}) {
|
2997
|
+
if (!options.skipCache) {
|
2998
|
+
const cacheKey = `near:${contractId}:${methodName}:${args ? JSON.stringify(args) : ""}`;
|
2999
|
+
return withCache(
|
3000
|
+
cacheKey,
|
3001
|
+
() => executeNearCall(contractId, methodName, args, options),
|
3002
|
+
options.cacheTimeout
|
3003
|
+
);
|
3004
|
+
}
|
3005
|
+
return executeNearCall(contractId, methodName, args, options);
|
3006
|
+
});
|
3007
|
+
}
|
3008
|
+
function executeNearCall(contractId, methodName, args, options) {
|
3009
|
+
return __async(this, null, function* () {
|
3010
|
+
const nearProvider = getNearProvider(options);
|
3011
|
+
const res = yield nearProvider.query({
|
3012
|
+
request_type: "call_function",
|
3013
|
+
account_id: contractId,
|
3014
|
+
method_name: methodName,
|
3015
|
+
args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
|
3016
|
+
finality: "final"
|
3017
|
+
});
|
3018
|
+
return JSON.parse(Buffer.from(res.result).toString());
|
3019
|
+
});
|
3020
|
+
}
|
3021
|
+
function pollTransactionStatuses(network, hashes) {
|
3022
|
+
return __async(this, null, function* () {
|
3023
|
+
const provider = new providers.FailoverRpcProvider(
|
3024
|
+
Object.values(nearRpcUrls[network]).map(
|
3025
|
+
(url) => new providers.JsonRpcProvider({ url })
|
3026
|
+
)
|
3027
|
+
);
|
3028
|
+
const maxAttempts = 30;
|
3029
|
+
let currentAttempt = 0;
|
3030
|
+
const pendingHashes = new Set(hashes);
|
3031
|
+
const results = /* @__PURE__ */ new Map();
|
3032
|
+
while (pendingHashes.size > 0 && currentAttempt < maxAttempts) {
|
3033
|
+
currentAttempt++;
|
3034
|
+
const promises = Array.from(pendingHashes).map((hash) => __async(this, null, function* () {
|
3035
|
+
try {
|
3036
|
+
const result2 = yield provider.txStatus(hash, "unused", "FINAL");
|
3037
|
+
if (result2 && result2.status) {
|
3038
|
+
console.log(`Transaction ${hash} result:`, result2);
|
3039
|
+
results.set(hash, result2);
|
3040
|
+
pendingHashes.delete(hash);
|
3041
|
+
}
|
3042
|
+
} catch (error) {
|
3043
|
+
console.error(`Failed to fetch transaction status for ${hash}: ${error.message}`);
|
3044
|
+
}
|
3045
|
+
}));
|
3046
|
+
yield Promise.all(promises);
|
3047
|
+
if (pendingHashes.size > 0) {
|
3048
|
+
if (currentAttempt === maxAttempts) {
|
3049
|
+
throw new Error(
|
3050
|
+
`Transactions not found after max attempts: ${Array.from(pendingHashes).join(", ")}`
|
3051
|
+
);
|
3052
|
+
}
|
3053
|
+
console.log(
|
3054
|
+
`Waiting for ${pendingHashes.size} transactions, retrying ${maxAttempts - currentAttempt} more times`
|
3055
|
+
);
|
3056
|
+
yield delay(1e4);
|
3057
|
+
}
|
3007
3058
|
}
|
3059
|
+
const result = hashes.map((hash) => results.get(hash)).filter(Boolean);
|
3060
|
+
return result;
|
3008
3061
|
});
|
3009
3062
|
}
|
3010
3063
|
|
@@ -3161,9 +3214,10 @@ function nearCall(contractId, methodName, args) {
|
|
3161
3214
|
return nearCallFunction(contractId, methodName, args, { network });
|
3162
3215
|
});
|
3163
3216
|
}
|
3164
|
-
function getAccountInfo(
|
3165
|
-
return __async(this,
|
3166
|
-
const
|
3217
|
+
function getAccountInfo(_0) {
|
3218
|
+
return __async(this, arguments, function* ({ csna, env }) {
|
3219
|
+
const config = yield getConfig(env);
|
3220
|
+
const accountInfo = yield nearCall(config.accountContractId, "get_account", {
|
3167
3221
|
account_id: csna
|
3168
3222
|
}).catch((error) => {
|
3169
3223
|
return void 0;
|
@@ -3172,16 +3226,46 @@ function getAccountInfo(csna, accountContractId) {
|
|
3172
3226
|
return accountInfo;
|
3173
3227
|
});
|
3174
3228
|
}
|
3175
|
-
function
|
3229
|
+
function getTokenBalance(_0) {
|
3230
|
+
return __async(this, arguments, function* ({
|
3231
|
+
csna,
|
3232
|
+
tokenId,
|
3233
|
+
env
|
3234
|
+
}) {
|
3235
|
+
const network = yield getNetwork();
|
3236
|
+
const config = yield getConfig(env);
|
3237
|
+
const nearProvider = getNearProvider({ network });
|
3238
|
+
try {
|
3239
|
+
if (tokenId === config.nearToken) {
|
3240
|
+
const nearAccount = yield nearProvider.query({
|
3241
|
+
request_type: "view_account",
|
3242
|
+
account_id: csna,
|
3243
|
+
finality: "final"
|
3244
|
+
});
|
3245
|
+
const balance = parseFloat(nearAccount.amount) / __pow(10, config.nearTokenDecimals);
|
3246
|
+
return { balance, rawBalance: nearAccount.amount };
|
3247
|
+
} else {
|
3248
|
+
const res = yield nearCall(tokenId, "ft_balance_of", { account_id: csna });
|
3249
|
+
const decimals = tokenId === config.btcToken ? config.btcTokenDecimals : (yield nearCall(tokenId, "ft_metadata", {})).decimals;
|
3250
|
+
const balance = parseFloat(res) / __pow(10, decimals);
|
3251
|
+
return { balance, rawBalance: res };
|
3252
|
+
}
|
3253
|
+
} catch (error) {
|
3254
|
+
console.error("getTokenBalance error:", error);
|
3255
|
+
return { balance: 0, rawBalance: "0" };
|
3256
|
+
}
|
3257
|
+
});
|
3258
|
+
}
|
3259
|
+
function checkGasTokenBalance(csna, minAmount, env) {
|
3176
3260
|
return __async(this, null, function* () {
|
3177
|
-
const
|
3178
|
-
|
3179
|
-
|
3261
|
+
const config = yield getConfig(env);
|
3262
|
+
const { rawBalance } = yield getTokenBalance({ csna, tokenId: config.btcToken, env });
|
3263
|
+
console.log("gas token balance:", rawBalance);
|
3264
|
+
if (new Big(rawBalance).lt(minAmount)) {
|
3180
3265
|
yield Dialog.confirm({
|
3181
3266
|
title: "Gas token balance is insufficient",
|
3182
3267
|
message: "Please deposit gas token to continue, will open bridge website."
|
3183
3268
|
});
|
3184
|
-
const config = yield getConfig(env);
|
3185
3269
|
window.open(config.bridgeUrl, "_blank");
|
3186
3270
|
throw new Error("Gas token balance is insufficient");
|
3187
3271
|
}
|
@@ -3262,18 +3346,6 @@ function getBtcBalance() {
|
|
3262
3346
|
};
|
3263
3347
|
});
|
3264
3348
|
}
|
3265
|
-
function getNBTCBalance(address, env) {
|
3266
|
-
return __async(this, null, function* () {
|
3267
|
-
const config = yield getConfig(env || "mainnet");
|
3268
|
-
const rawBalance = yield nearCall(config.token, "ft_balance_of", {
|
3269
|
-
account_id: address
|
3270
|
-
});
|
3271
|
-
const balance = new Big(rawBalance).div(__pow(10, 8)).round(8, Big.roundDown).toNumber();
|
3272
|
-
const rawAvailableBalance = new Big(rawBalance).minus(1e3).toNumber();
|
3273
|
-
const availableBalance = new Big(rawAvailableBalance).div(__pow(10, 8)).round(8, Big.roundDown).toNumber();
|
3274
|
-
return { balance, availableBalance, rawBalance, rawAvailableBalance };
|
3275
|
-
});
|
3276
|
-
}
|
3277
3349
|
function sendBitcoin(address, amount, feeRate) {
|
3278
3350
|
return __async(this, null, function* () {
|
3279
3351
|
const { sendBitcoin: sendBitcoin2 } = getBtcProvider();
|
@@ -3293,7 +3365,7 @@ function getDepositAmount(amount, option) {
|
|
3293
3365
|
const _newAccountMinDepositAmount = (_a = option == null ? void 0 : option.newAccountMinDepositAmount) != null ? _a : true;
|
3294
3366
|
const config = yield getConfig(env);
|
3295
3367
|
const csna = yield getCsnaAccountId(env);
|
3296
|
-
const accountInfo = yield getAccountInfo(csna,
|
3368
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
3297
3369
|
const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
|
3298
3370
|
const repayAmount = (debtAction == null ? void 0 : debtAction.amount) || 0;
|
3299
3371
|
const {
|
@@ -3372,7 +3444,7 @@ function executeBTCDepositAndAction(_0) {
|
|
3372
3444
|
env,
|
3373
3445
|
newAccountMinDepositAmount
|
3374
3446
|
});
|
3375
|
-
const accountInfo = yield getAccountInfo(csna,
|
3447
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
3376
3448
|
const newActions = [];
|
3377
3449
|
const debtAction = yield checkGasTokenDebt(accountInfo, env, false);
|
3378
3450
|
if (debtAction) {
|
@@ -3386,12 +3458,12 @@ function executeBTCDepositAndAction(_0) {
|
|
3386
3458
|
}));
|
3387
3459
|
}
|
3388
3460
|
const storageDepositMsg = {};
|
3389
|
-
const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.
|
3461
|
+
const registerRes = yield nearCall((action == null ? void 0 : action.receiver_id) || config.btcToken, "storage_balance_of", {
|
3390
3462
|
account_id: csna
|
3391
3463
|
});
|
3392
3464
|
if (!(registerRes == null ? void 0 : registerRes.available)) {
|
3393
3465
|
storageDepositMsg.storage_deposit_msg = {
|
3394
|
-
contract_id: (action == null ? void 0 : action.receiver_id) || config.
|
3466
|
+
contract_id: (action == null ? void 0 : action.receiver_id) || config.btcToken,
|
3395
3467
|
deposit: registerDeposit || NEAR_STORAGE_DEPOSIT_AMOUNT,
|
3396
3468
|
registration_only: true
|
3397
3469
|
};
|
@@ -3486,7 +3558,7 @@ function getWithdrawTransaction(_0) {
|
|
3486
3558
|
env = "mainnet"
|
3487
3559
|
}) {
|
3488
3560
|
const provider = getBtcProvider();
|
3489
|
-
const btcAddress =
|
3561
|
+
const btcAddress = provider.account;
|
3490
3562
|
const config = yield getConfig(env);
|
3491
3563
|
const brgConfig = yield nearCall(config.bridgeContractId, "get_config", {});
|
3492
3564
|
if (brgConfig.min_withdraw_amount) {
|
@@ -3510,7 +3582,7 @@ function getWithdrawTransaction(_0) {
|
|
3510
3582
|
};
|
3511
3583
|
});
|
3512
3584
|
const _feeRate = feeRate || (yield getBtcGasPrice());
|
3513
|
-
|
3585
|
+
let { inputs, outputs, fee } = coinselect(
|
3514
3586
|
utxos,
|
3515
3587
|
[{ address: btcAddress, value: Number(amount) }],
|
3516
3588
|
Math.ceil(_feeRate)
|
@@ -3519,32 +3591,61 @@ function getWithdrawTransaction(_0) {
|
|
3519
3591
|
throw new Error("The network is busy, please try again later.");
|
3520
3592
|
}
|
3521
3593
|
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
3522
|
-
const
|
3523
|
-
const
|
3524
|
-
if (
|
3594
|
+
const transactionFee = fee;
|
3595
|
+
const changeAddress = brgConfig.change_address;
|
3596
|
+
if (transactionFee > maxBtcFee) {
|
3525
3597
|
throw new Error("Gas exceeds maximum value");
|
3526
3598
|
}
|
3527
|
-
let
|
3599
|
+
let recipientOutput, changeOutput;
|
3528
3600
|
for (let i = 0; i < outputs.length; i++) {
|
3529
3601
|
const output = outputs[i];
|
3530
3602
|
if (output.value.toString() === amount.toString()) {
|
3531
|
-
|
3603
|
+
recipientOutput = output;
|
3532
3604
|
} else {
|
3533
|
-
|
3605
|
+
changeOutput = output;
|
3534
3606
|
}
|
3535
3607
|
if (!output.address) {
|
3536
|
-
output.address =
|
3608
|
+
output.address = changeAddress;
|
3537
3609
|
}
|
3538
3610
|
}
|
3539
|
-
|
3540
|
-
if (
|
3541
|
-
|
3611
|
+
recipientOutput.value = new Big(recipientOutput.value).minus(transactionFee).minus(withdrawFee).toNumber();
|
3612
|
+
if (changeOutput) {
|
3613
|
+
changeOutput.value = new Big(changeOutput.value).plus(transactionFee).plus(withdrawFee).toNumber();
|
3614
|
+
const remainingInputs = [...inputs];
|
3615
|
+
let smallestInput = Math.min.apply(
|
3616
|
+
null,
|
3617
|
+
remainingInputs.map((input) => input.value)
|
3618
|
+
);
|
3619
|
+
let remainingChangeAmount = changeOutput.value;
|
3620
|
+
while (remainingChangeAmount >= smallestInput && smallestInput > 0 && remainingInputs.length > 0) {
|
3621
|
+
remainingChangeAmount -= smallestInput;
|
3622
|
+
changeOutput.value = remainingChangeAmount;
|
3623
|
+
const smallestInputIndex = remainingInputs.findIndex(
|
3624
|
+
(input) => input.value === smallestInput
|
3625
|
+
);
|
3626
|
+
if (smallestInputIndex > -1) {
|
3627
|
+
remainingInputs.splice(smallestInputIndex, 1);
|
3628
|
+
}
|
3629
|
+
smallestInput = Math.min.apply(
|
3630
|
+
null,
|
3631
|
+
remainingInputs.map((input) => input.value)
|
3632
|
+
);
|
3633
|
+
}
|
3634
|
+
const minChangeAmount = Number(brgConfig.min_change_amount);
|
3635
|
+
let additionalFee = 0;
|
3636
|
+
if (changeOutput.value === 0) {
|
3637
|
+
outputs = outputs.filter((item) => item.value !== 0);
|
3638
|
+
} else if (changeOutput.value < minChangeAmount) {
|
3639
|
+
additionalFee = minChangeAmount - changeOutput.value;
|
3640
|
+
recipientOutput.value -= additionalFee;
|
3641
|
+
changeOutput.value = minChangeAmount;
|
3642
|
+
}
|
3542
3643
|
} else {
|
3543
|
-
|
3544
|
-
address:
|
3545
|
-
value: new Big(
|
3644
|
+
changeOutput = {
|
3645
|
+
address: changeAddress,
|
3646
|
+
value: new Big(transactionFee).plus(withdrawFee).toNumber()
|
3546
3647
|
};
|
3547
|
-
outputs.push(
|
3648
|
+
outputs.push(changeOutput);
|
3548
3649
|
}
|
3549
3650
|
const insufficientOutput = outputs.some((item) => item.value < 0);
|
3550
3651
|
if (insufficientOutput) {
|
@@ -3552,7 +3653,7 @@ function getWithdrawTransaction(_0) {
|
|
3552
3653
|
}
|
3553
3654
|
const inputSum = inputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3554
3655
|
const outputSum = outputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3555
|
-
if (
|
3656
|
+
if (transactionFee + outputSum !== inputSum) {
|
3556
3657
|
throw new Error("compute error");
|
3557
3658
|
}
|
3558
3659
|
const network = yield getNetwork();
|
@@ -3597,7 +3698,7 @@ function getWithdrawTransaction(_0) {
|
|
3597
3698
|
};
|
3598
3699
|
const csna = yield getCsnaAccountId(env);
|
3599
3700
|
const transaction = {
|
3600
|
-
receiverId: config.
|
3701
|
+
receiverId: config.btcToken,
|
3601
3702
|
signerId: csna,
|
3602
3703
|
actions: [
|
3603
3704
|
{
|
@@ -4141,20 +4242,16 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4141
4242
|
throw new Error("Wallet state is invalid, please reconnect your wallet.");
|
4142
4243
|
}
|
4143
4244
|
const btcContext = window.btcContext;
|
4144
|
-
const
|
4145
|
-
const accountInfo = yield getAccountInfo(
|
4245
|
+
const csna = state.getAccount();
|
4246
|
+
const accountInfo = yield getAccountInfo({ csna, env });
|
4146
4247
|
yield checkGasTokenDebt(accountInfo, env, true);
|
4147
4248
|
const trans = [...params.transactions];
|
4148
4249
|
console.log("signAndSendTransactions raw trans:", trans);
|
4149
|
-
const
|
4150
|
-
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(
|
4151
|
-
gasTokenBalance,
|
4152
|
-
trans
|
4153
|
-
);
|
4250
|
+
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy(trans);
|
4154
4251
|
console.log("transferGasTransaction:", transferGasTransaction);
|
4155
4252
|
console.log("useNearPayGas:", useNearPayGas);
|
4156
4253
|
console.log("gasLimit:", gasLimit);
|
4157
|
-
yield checkGasTokenBalance(
|
4254
|
+
yield checkGasTokenBalance(csna, gasLimit, env);
|
4158
4255
|
if (transferGasTransaction) {
|
4159
4256
|
trans.unshift(transferGasTransaction);
|
4160
4257
|
}
|
@@ -4162,14 +4259,14 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4162
4259
|
const newTrans = yield Promise.all(
|
4163
4260
|
trans.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
4164
4261
|
);
|
4165
|
-
const nonceFromApi = yield getNonce(currentConfig.base_url,
|
4262
|
+
const nonceFromApi = yield getNonce(currentConfig.base_url, csna);
|
4166
4263
|
const nonceFromContract = (accountInfo == null ? void 0 : accountInfo.nonce) || 0;
|
4167
4264
|
const nonce = Number(nonceFromApi) > Number(nonceFromContract) ? String(nonceFromApi) : String(nonceFromContract);
|
4168
4265
|
const intention = {
|
4169
4266
|
chain_id: "397",
|
4170
|
-
csna
|
4267
|
+
csna,
|
4171
4268
|
near_transactions: newTrans.map((t) => t.txHex),
|
4172
|
-
gas_token: currentConfig.
|
4269
|
+
gas_token: currentConfig.btcToken,
|
4173
4270
|
gas_limit: gasLimit,
|
4174
4271
|
use_near_pay_gas: useNearPayGas,
|
4175
4272
|
nonce
|
@@ -4182,7 +4279,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4182
4279
|
data: toHex(strIntention)
|
4183
4280
|
});
|
4184
4281
|
yield checkBtcTransactionStatus(currentConfig.base_url, signature);
|
4185
|
-
const hash = newTrans.map((t) => t.hash);
|
4282
|
+
const hash = newTrans.slice(1).map((t) => t.hash);
|
4186
4283
|
console.log("txHash:", hash);
|
4187
4284
|
const result = yield pollTransactionStatuses(options.network.networkId, hash);
|
4188
4285
|
return result;
|
@@ -4190,12 +4287,9 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4190
4287
|
}
|
4191
4288
|
function calculateGasLimit(params) {
|
4192
4289
|
return __async(this, null, function* () {
|
4193
|
-
const accountId = state.getAccount();
|
4194
|
-
const accountInfo = yield getAccountInfo(accountId, currentConfig.accountContractId);
|
4195
4290
|
const trans = [...params.transactions];
|
4196
4291
|
console.log("raw trans:", trans);
|
4197
|
-
const
|
4198
|
-
const { gasLimit } = yield calculateGasStrategy(gasTokenBalance, trans);
|
4292
|
+
const { gasLimit } = yield calculateGasStrategy(trans);
|
4199
4293
|
return gasLimit;
|
4200
4294
|
});
|
4201
4295
|
}
|
@@ -4203,7 +4297,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4203
4297
|
return __async(this, null, function* () {
|
4204
4298
|
return {
|
4205
4299
|
signerId: accountId,
|
4206
|
-
receiverId: currentConfig.
|
4300
|
+
receiverId: currentConfig.btcToken,
|
4207
4301
|
actions: [
|
4208
4302
|
{
|
4209
4303
|
type: "FunctionCall",
|
@@ -4231,7 +4325,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4231
4325
|
} else {
|
4232
4326
|
newGasLimit = yield getPredictedGasAmount(
|
4233
4327
|
currentConfig.accountContractId,
|
4234
|
-
currentConfig.
|
4328
|
+
currentConfig.btcToken,
|
4235
4329
|
[transferTxHex, ...transactions2.map((t) => t.txHex)]
|
4236
4330
|
);
|
4237
4331
|
}
|
@@ -4252,31 +4346,61 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4252
4346
|
return gasAmount.toString();
|
4253
4347
|
});
|
4254
4348
|
}
|
4255
|
-
function calculateGasStrategy(
|
4349
|
+
function calculateGasStrategy(transactions2) {
|
4256
4350
|
return __async(this, null, function* () {
|
4257
4351
|
var _a;
|
4258
4352
|
const accountId = state.getAccount();
|
4259
|
-
const
|
4260
|
-
|
4261
|
-
|
4262
|
-
|
4353
|
+
const accountInfo = yield getAccountInfo({ csna: accountId, env });
|
4354
|
+
const gasTokenBalance = (accountInfo == null ? void 0 : accountInfo.gas_token[currentConfig.btcToken]) || "0";
|
4355
|
+
const { balance: nearBalance } = yield getTokenBalance({
|
4356
|
+
csna: accountId,
|
4357
|
+
tokenId: currentConfig.nearToken,
|
4358
|
+
env
|
4263
4359
|
});
|
4264
|
-
const
|
4265
|
-
|
4360
|
+
const { balance: btcBalance } = yield getTokenBalance({
|
4361
|
+
csna: accountId,
|
4362
|
+
tokenId: currentConfig.btcToken,
|
4363
|
+
env
|
4364
|
+
});
|
4365
|
+
const transferAmount = transactions2.reduce(
|
4366
|
+
(acc, tx) => {
|
4367
|
+
tx.actions.forEach((action) => {
|
4368
|
+
if (action.params.deposit) {
|
4369
|
+
const amount = Number(action.params.deposit) / __pow(10, currentConfig.nearTokenDecimals);
|
4370
|
+
console.log("near deposit amount:", amount);
|
4371
|
+
acc.near = acc.near.plus(amount);
|
4372
|
+
}
|
4373
|
+
if (tx.receiverId === currentConfig.btcToken && ["ft_transfer_call", "ft_transfer"].includes(action.params.methodName)) {
|
4374
|
+
const amount = Number(action.params.args.amount) / __pow(10, currentConfig.btcTokenDecimals);
|
4375
|
+
console.log("btc transfer amount:", amount);
|
4376
|
+
acc.btc = acc.btc.plus(amount);
|
4377
|
+
}
|
4378
|
+
});
|
4379
|
+
return acc;
|
4380
|
+
},
|
4381
|
+
{ near: new Big2(0), btc: new Big2(0) }
|
4382
|
+
);
|
4383
|
+
const nearAvailableBalance = new Big2(nearBalance).minus(transferAmount.near).toNumber();
|
4384
|
+
const btcAvailableBalance = new Big2(btcBalance).minus(transferAmount.btc).toNumber();
|
4385
|
+
if (btcAvailableBalance < 8e-6) {
|
4386
|
+
throw new Error("BTC balance is not enough, please deposit more BTC.");
|
4387
|
+
}
|
4388
|
+
console.log("available near balance:", nearAvailableBalance);
|
4389
|
+
console.log("available btc balance:", btcAvailableBalance);
|
4266
4390
|
console.log("available gas token balance:", gasTokenBalance);
|
4267
4391
|
const convertTx = yield Promise.all(
|
4268
4392
|
transactions2.map((transaction, index) => convertTransactionToTxHex(transaction, index))
|
4269
4393
|
);
|
4270
|
-
if (
|
4394
|
+
if (nearAvailableBalance > 0.5) {
|
4271
4395
|
console.log("near balance is enough, get the protocol fee of each transaction");
|
4272
4396
|
const gasTokens = yield nearCall2(
|
4273
4397
|
currentConfig.accountContractId,
|
4274
4398
|
"list_gas_token",
|
4275
|
-
{ token_ids: [currentConfig.
|
4399
|
+
{ token_ids: [currentConfig.btcToken] }
|
4276
4400
|
);
|
4277
4401
|
console.log("list_gas_token gas tokens:", gasTokens);
|
4278
4402
|
const perTxFee = Math.max(
|
4279
|
-
Number(((_a = gasTokens[currentConfig.
|
4403
|
+
Number(((_a = gasTokens[currentConfig.btcToken]) == null ? void 0 : _a.per_tx_protocol_fee) || 0),
|
4280
4404
|
100
|
4281
4405
|
);
|
4282
4406
|
console.log("perTxFee:", perTxFee);
|
@@ -4294,7 +4418,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4294
4418
|
console.log("near balance is not enough, predict the gas token amount required");
|
4295
4419
|
const adjustedGas = yield getPredictedGasAmount(
|
4296
4420
|
currentConfig.accountContractId,
|
4297
|
-
currentConfig.
|
4421
|
+
currentConfig.btcToken,
|
4298
4422
|
convertTx.map((t) => t.txHex)
|
4299
4423
|
);
|
4300
4424
|
if (new Big2(gasTokenBalance).gte(adjustedGas)) {
|
@@ -4410,7 +4534,7 @@ function setupBTCWallet({
|
|
4410
4534
|
|
4411
4535
|
// src/index.ts
|
4412
4536
|
var getVersion = () => {
|
4413
|
-
return "0.5.
|
4537
|
+
return "0.5.13-beta";
|
4414
4538
|
};
|
4415
4539
|
if (typeof window !== "undefined") {
|
4416
4540
|
window.__BTC_WALLET_VERSION = getVersion();
|
@@ -4440,7 +4564,7 @@ export {
|
|
4440
4564
|
getConfig,
|
4441
4565
|
getCsnaAccountId,
|
4442
4566
|
getDepositAmount,
|
4443
|
-
|
4567
|
+
getTokenBalance,
|
4444
4568
|
getVersion,
|
4445
4569
|
getWithdrawTransaction,
|
4446
4570
|
sendBitcoin,
|