btc-wallet 0.5.19-beta → 0.5.21-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/index.js +245 -177
- package/dist/index.js.map +3 -3
- package/dist/utils/satoshi.d.ts +35 -0
- package/esm/index.js +245 -177
- package/esm/index.js.map +2 -2
- package/package.json +1 -1
package/dist/utils/satoshi.d.ts
CHANGED
@@ -38,6 +38,23 @@ export declare function getAccountInfo({ csna, env }: {
|
|
38
38
|
csna: string;
|
39
39
|
env: ENV;
|
40
40
|
}): Promise<AccountInfo | undefined>;
|
41
|
+
export declare function getBridgeConfig({ env }: {
|
42
|
+
env: ENV;
|
43
|
+
}): Promise<{
|
44
|
+
min_withdraw_amount: string;
|
45
|
+
withdraw_bridge_fee: {
|
46
|
+
fee_rate: number;
|
47
|
+
fee_min: string;
|
48
|
+
};
|
49
|
+
max_btc_gas_fee: string;
|
50
|
+
change_address: string;
|
51
|
+
min_change_amount: string;
|
52
|
+
deposit_bridge_fee: {
|
53
|
+
fee_rate: number;
|
54
|
+
fee_min: string;
|
55
|
+
};
|
56
|
+
min_deposit_amount: string;
|
57
|
+
}>;
|
41
58
|
export declare function getTokenBalance({ csna, tokenId, env, }: {
|
42
59
|
csna: string;
|
43
60
|
tokenId: string;
|
@@ -69,4 +86,22 @@ export declare function calculateGasStrategy({ csna, transactions, env, }: Calcu
|
|
69
86
|
useNearPayGas: boolean;
|
70
87
|
gasLimit: string;
|
71
88
|
}>;
|
89
|
+
interface CalculateWithdrawParams {
|
90
|
+
amount: string | number;
|
91
|
+
feeRate?: number;
|
92
|
+
csna: string;
|
93
|
+
btcAddress: string;
|
94
|
+
env: ENV;
|
95
|
+
}
|
96
|
+
interface CalculateWithdrawResult {
|
97
|
+
withdrawFee: number;
|
98
|
+
gasFee?: number;
|
99
|
+
inputs?: any[];
|
100
|
+
outputs?: any[];
|
101
|
+
fromAmount?: number;
|
102
|
+
receiveAmount?: string;
|
103
|
+
isError: boolean;
|
104
|
+
errorMsg?: string;
|
105
|
+
}
|
106
|
+
export declare function calculateWithdraw({ amount, feeRate, csna, btcAddress, env, }: CalculateWithdrawParams): Promise<CalculateWithdrawResult>;
|
72
107
|
export {};
|
package/esm/index.js
CHANGED
@@ -19,6 +19,18 @@ var __spreadValues = (a, b) => {
|
|
19
19
|
return a;
|
20
20
|
};
|
21
21
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
22
|
+
var __objRest = (source, exclude) => {
|
23
|
+
var target = {};
|
24
|
+
for (var prop in source)
|
25
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
26
|
+
target[prop] = source[prop];
|
27
|
+
if (source != null && __getOwnPropSymbols)
|
28
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
29
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
30
|
+
target[prop] = source[prop];
|
31
|
+
}
|
32
|
+
return target;
|
33
|
+
};
|
22
34
|
var __accessCheck = (obj, member, msg) => {
|
23
35
|
if (!member.has(obj))
|
24
36
|
throw TypeError("Cannot " + msg);
|
@@ -2963,7 +2975,6 @@ function request(url, options) {
|
|
2963
2975
|
}
|
2964
2976
|
return data;
|
2965
2977
|
} catch (err) {
|
2966
|
-
console.error(err);
|
2967
2978
|
if (retryCount > 0) {
|
2968
2979
|
console.log(`Retrying... attempts left: ${retryCount}`);
|
2969
2980
|
return request(url, __spreadProps(__spreadValues({}, options), { retryCount: retryCount - 1 }));
|
@@ -2977,6 +2988,7 @@ function request(url, options) {
|
|
2977
2988
|
}));
|
2978
2989
|
}
|
2979
2990
|
}
|
2991
|
+
console.error(err);
|
2980
2992
|
return Promise.reject(err);
|
2981
2993
|
}
|
2982
2994
|
});
|
@@ -3149,6 +3161,7 @@ var state_default = {
|
|
3149
3161
|
};
|
3150
3162
|
|
3151
3163
|
// src/utils/satoshi.ts
|
3164
|
+
import coinselect from "coinselect";
|
3152
3165
|
function getNonce(url, accountId) {
|
3153
3166
|
return __async(this, null, function* () {
|
3154
3167
|
const { result_code, result_message, result_data } = yield request(
|
@@ -3226,12 +3239,13 @@ function checkBridgeTransactionStatus(url, txHash) {
|
|
3226
3239
|
maxPollingAttempts: 60,
|
3227
3240
|
shouldStopPolling: (res) => {
|
3228
3241
|
var _a;
|
3229
|
-
|
3242
|
+
const status = ((_a = res.result_data) == null ? void 0 : _a.Status) || 0;
|
3243
|
+
return res.result_code === 0 && (status === 4 || status >= 50);
|
3230
3244
|
}
|
3231
3245
|
});
|
3232
3246
|
console.log("checkTransactionStatus resp:", { result_code, result_message, result_data });
|
3233
3247
|
if ((result_data == null ? void 0 : result_data.Status) !== 4) {
|
3234
|
-
throw new Error(result_message);
|
3248
|
+
throw new Error(result_message || `Transaction failed, status: ${result_data == null ? void 0 : result_data.Status}`);
|
3235
3249
|
}
|
3236
3250
|
return result_data;
|
3237
3251
|
});
|
@@ -3244,12 +3258,13 @@ function checkBtcTransactionStatus(url, sig) {
|
|
3244
3258
|
maxPollingAttempts: 60,
|
3245
3259
|
shouldStopPolling: (res) => {
|
3246
3260
|
var _a;
|
3247
|
-
|
3261
|
+
const status = ((_a = res.result_data) == null ? void 0 : _a.Status) || 0;
|
3262
|
+
return res.result_code === 0 && (status === 3 || status >= 10);
|
3248
3263
|
}
|
3249
3264
|
});
|
3250
3265
|
console.log("checkBtcTransactionStatus resp:", { result_code, result_message, result_data });
|
3251
3266
|
if ((result_data == null ? void 0 : result_data.Status) !== 3) {
|
3252
|
-
throw new Error(result_message);
|
3267
|
+
throw new Error(result_message || `Transaction failed, status: ${result_data == null ? void 0 : result_data.Status}`);
|
3253
3268
|
}
|
3254
3269
|
return result_data;
|
3255
3270
|
});
|
@@ -3276,10 +3291,16 @@ function getAccountInfo(_0) {
|
|
3276
3291
|
).catch((error) => {
|
3277
3292
|
return void 0;
|
3278
3293
|
});
|
3279
|
-
console.log("get_account accountInfo:", accountInfo);
|
3280
3294
|
return accountInfo;
|
3281
3295
|
});
|
3282
3296
|
}
|
3297
|
+
function getBridgeConfig(_0) {
|
3298
|
+
return __async(this, arguments, function* ({ env }) {
|
3299
|
+
const config = getWalletConfig(env);
|
3300
|
+
const bridgeConfig = yield nearCallFunction(config.bridgeContractId, "get_config", {}, { network: config.network });
|
3301
|
+
return bridgeConfig;
|
3302
|
+
});
|
3303
|
+
}
|
3283
3304
|
function getTokenBalance(_0) {
|
3284
3305
|
return __async(this, arguments, function* ({
|
3285
3306
|
csna,
|
@@ -3578,11 +3599,196 @@ function getPredictedGasAmount(_0) {
|
|
3578
3599
|
return gasAmount.toString();
|
3579
3600
|
});
|
3580
3601
|
}
|
3602
|
+
function calculateWithdraw(_0) {
|
3603
|
+
return __async(this, arguments, function* ({
|
3604
|
+
amount,
|
3605
|
+
feeRate,
|
3606
|
+
csna,
|
3607
|
+
btcAddress,
|
3608
|
+
env
|
3609
|
+
}) {
|
3610
|
+
console.log("calculateWithdraw feeRate:", feeRate);
|
3611
|
+
try {
|
3612
|
+
const config = getWalletConfig(env);
|
3613
|
+
const gasLimit = yield calculateGasLimit({
|
3614
|
+
csna,
|
3615
|
+
transactions: [
|
3616
|
+
{
|
3617
|
+
signerId: "",
|
3618
|
+
receiverId: config.btcToken,
|
3619
|
+
actions: [
|
3620
|
+
{
|
3621
|
+
type: "FunctionCall",
|
3622
|
+
params: {
|
3623
|
+
methodName: "ft_transfer_call",
|
3624
|
+
args: {
|
3625
|
+
receiver_id: config.btcToken,
|
3626
|
+
amount: "100",
|
3627
|
+
msg: ""
|
3628
|
+
},
|
3629
|
+
gas: "300000000000000",
|
3630
|
+
deposit: "1"
|
3631
|
+
}
|
3632
|
+
}
|
3633
|
+
]
|
3634
|
+
}
|
3635
|
+
],
|
3636
|
+
env
|
3637
|
+
});
|
3638
|
+
let satoshis = Number(amount);
|
3639
|
+
if (Number(gasLimit) > 0) {
|
3640
|
+
satoshis = new Big(amount).minus(gasLimit).toNumber();
|
3641
|
+
}
|
3642
|
+
const brgConfig = yield getBridgeConfig({ env });
|
3643
|
+
const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
|
3644
|
+
if (brgConfig.min_withdraw_amount) {
|
3645
|
+
if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
|
3646
|
+
return {
|
3647
|
+
withdrawFee: 0,
|
3648
|
+
isError: true,
|
3649
|
+
errorMsg: "Mini withdraw amount is " + (Number(brgConfig.min_withdraw_amount) + Number(gasLimit))
|
3650
|
+
};
|
3651
|
+
}
|
3652
|
+
}
|
3653
|
+
const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
|
3654
|
+
const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
|
3655
|
+
const withdrawChangeAddress = brgConfig.change_address;
|
3656
|
+
const utxos = Object.keys(allUTXO).map((key) => {
|
3657
|
+
const txid = key.split("@");
|
3658
|
+
return {
|
3659
|
+
txid: txid[0],
|
3660
|
+
vout: allUTXO[key].vout,
|
3661
|
+
value: Number(allUTXO[key].balance),
|
3662
|
+
script: allUTXO[key].script
|
3663
|
+
};
|
3664
|
+
}).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
|
3665
|
+
if (!utxos || utxos.length === 0) {
|
3666
|
+
return {
|
3667
|
+
withdrawFee,
|
3668
|
+
isError: true,
|
3669
|
+
errorMsg: "The network is busy, please try again later."
|
3670
|
+
};
|
3671
|
+
}
|
3672
|
+
const userSatoshis = Number(satoshis);
|
3673
|
+
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
3674
|
+
const { inputs, outputs, fee } = coinselect(
|
3675
|
+
utxos,
|
3676
|
+
[{ address: btcAddress, value: userSatoshis }],
|
3677
|
+
Math.ceil(feeRate || 0)
|
3678
|
+
);
|
3679
|
+
const newInputs = inputs;
|
3680
|
+
let newOutputs = outputs;
|
3681
|
+
let newFee = fee;
|
3682
|
+
if (!newOutputs || newOutputs.length === 0) {
|
3683
|
+
return {
|
3684
|
+
withdrawFee,
|
3685
|
+
isError: true,
|
3686
|
+
errorMsg: "The network is busy, please try again later."
|
3687
|
+
};
|
3688
|
+
}
|
3689
|
+
let userOutput, noUserOutput;
|
3690
|
+
for (let i = 0; i < newOutputs.length; i++) {
|
3691
|
+
const output = newOutputs[i];
|
3692
|
+
if (output.value.toString() === userSatoshis.toString()) {
|
3693
|
+
userOutput = output;
|
3694
|
+
} else {
|
3695
|
+
noUserOutput = output;
|
3696
|
+
}
|
3697
|
+
if (!output.address) {
|
3698
|
+
output.address = withdrawChangeAddress;
|
3699
|
+
}
|
3700
|
+
}
|
3701
|
+
let dis = 0;
|
3702
|
+
if (newFee > maxBtcFee) {
|
3703
|
+
dis = newFee - maxBtcFee;
|
3704
|
+
newFee = maxBtcFee;
|
3705
|
+
return {
|
3706
|
+
gasFee: newFee,
|
3707
|
+
withdrawFee,
|
3708
|
+
isError: true,
|
3709
|
+
errorMsg: "Gas exceeds maximum value"
|
3710
|
+
};
|
3711
|
+
}
|
3712
|
+
userOutput.value = new Big(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
|
3713
|
+
if (userOutput.value < 0) {
|
3714
|
+
return {
|
3715
|
+
gasFee: newFee,
|
3716
|
+
withdrawFee,
|
3717
|
+
isError: true,
|
3718
|
+
errorMsg: "Not enough gas"
|
3719
|
+
};
|
3720
|
+
}
|
3721
|
+
if (noUserOutput) {
|
3722
|
+
if (!noUserOutput.address) {
|
3723
|
+
noUserOutput.address = withdrawChangeAddress;
|
3724
|
+
}
|
3725
|
+
noUserOutput.value = new Big(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
|
3726
|
+
} else {
|
3727
|
+
noUserOutput = {
|
3728
|
+
address: withdrawChangeAddress,
|
3729
|
+
value: new Big(newFee).plus(withdrawFee).plus(dis).toNumber()
|
3730
|
+
};
|
3731
|
+
newOutputs.push(noUserOutput);
|
3732
|
+
}
|
3733
|
+
let minValue = Math.min(...newInputs.map((input) => input.value));
|
3734
|
+
let totalNoUserOutputValue = noUserOutput.value;
|
3735
|
+
while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
|
3736
|
+
totalNoUserOutputValue -= minValue;
|
3737
|
+
noUserOutput.value = totalNoUserOutputValue;
|
3738
|
+
const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
|
3739
|
+
if (minValueIndex > -1) {
|
3740
|
+
newInputs.splice(minValueIndex, 1);
|
3741
|
+
}
|
3742
|
+
minValue = Math.min(...newInputs.map((input) => input.value));
|
3743
|
+
}
|
3744
|
+
let gasMore = 0;
|
3745
|
+
if (noUserOutput.value === 0) {
|
3746
|
+
newOutputs = newOutputs.filter((item) => item.value !== 0);
|
3747
|
+
} else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
|
3748
|
+
gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
|
3749
|
+
userOutput.value -= gasMore;
|
3750
|
+
noUserOutput.value = Number(brgConfig.min_change_amount);
|
3751
|
+
}
|
3752
|
+
const insufficientOutput = newOutputs.some((item) => item.value < 0);
|
3753
|
+
if (insufficientOutput) {
|
3754
|
+
return {
|
3755
|
+
gasFee: newFee,
|
3756
|
+
withdrawFee,
|
3757
|
+
isError: true,
|
3758
|
+
errorMsg: "Not enough gas"
|
3759
|
+
};
|
3760
|
+
}
|
3761
|
+
const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3762
|
+
const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3763
|
+
if (newFee + outputSum !== inputSum) {
|
3764
|
+
return {
|
3765
|
+
withdrawFee,
|
3766
|
+
isError: true,
|
3767
|
+
errorMsg: "Service busy, please try again later"
|
3768
|
+
};
|
3769
|
+
}
|
3770
|
+
return {
|
3771
|
+
withdrawFee: new Big(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
|
3772
|
+
gasFee: new Big(newFee).toNumber(),
|
3773
|
+
inputs: newInputs,
|
3774
|
+
outputs: newOutputs,
|
3775
|
+
fromAmount: satoshis,
|
3776
|
+
receiveAmount: userOutput.value,
|
3777
|
+
isError: false
|
3778
|
+
};
|
3779
|
+
} catch (error) {
|
3780
|
+
return {
|
3781
|
+
withdrawFee: 0,
|
3782
|
+
isError: true,
|
3783
|
+
errorMsg: error.message
|
3784
|
+
};
|
3785
|
+
}
|
3786
|
+
});
|
3787
|
+
}
|
3581
3788
|
|
3582
3789
|
// src/core/btcUtils.ts
|
3583
3790
|
import bitcoin from "bitcoinjs-lib";
|
3584
3791
|
import * as ecc from "@bitcoinerlab/secp256k1";
|
3585
|
-
import coinselect from "coinselect";
|
3586
3792
|
bitcoin.initEccLib(ecc);
|
3587
3793
|
var NEAR_STORAGE_DEPOSIT_AMOUNT = "1250000000000000000000";
|
3588
3794
|
var NBTC_STORAGE_DEPOSIT_AMOUNT = "3000";
|
@@ -3706,7 +3912,6 @@ function getDepositAmount(amount, option) {
|
|
3706
3912
|
var _a;
|
3707
3913
|
const env = (option == null ? void 0 : option.env) || "mainnet";
|
3708
3914
|
const _newAccountMinDepositAmount = (_a = option == null ? void 0 : option.newAccountMinDepositAmount) != null ? _a : true;
|
3709
|
-
const config = getWalletConfig(env);
|
3710
3915
|
const csna = yield getCsnaAccountId(env);
|
3711
3916
|
const accountInfo = yield getAccountInfo({ csna, env });
|
3712
3917
|
const debtAction = yield checkGasTokenDebt(csna, env, false);
|
@@ -3714,7 +3919,7 @@ function getDepositAmount(amount, option) {
|
|
3714
3919
|
const {
|
3715
3920
|
deposit_bridge_fee: { fee_min, fee_rate },
|
3716
3921
|
min_deposit_amount
|
3717
|
-
} = yield
|
3922
|
+
} = yield getBridgeConfig({ env });
|
3718
3923
|
const depositAmount = Math.max(Number(min_deposit_amount), Number(amount));
|
3719
3924
|
const protocolFee = Math.max(Number(fee_min), Number(depositAmount) * fee_rate);
|
3720
3925
|
const newAccountMinDepositAmount = !(accountInfo == null ? void 0 : accountInfo.nonce) && _newAccountMinDepositAmount ? NEW_ACCOUNT_MIN_DEPOSIT_AMOUNT : 0;
|
@@ -3906,190 +4111,52 @@ function getWithdrawTransaction(_0) {
|
|
3906
4111
|
feeRate,
|
3907
4112
|
env = "mainnet"
|
3908
4113
|
}) {
|
3909
|
-
|
4114
|
+
const config = getWalletConfig(env);
|
3910
4115
|
const provider = getBtcProvider();
|
3911
4116
|
const btcAddress = provider.account;
|
3912
|
-
const config = getWalletConfig(env);
|
3913
4117
|
const csna = yield getCsnaAccountId(env);
|
3914
|
-
const
|
3915
|
-
|
3916
|
-
|
3917
|
-
|
3918
|
-
}
|
3919
|
-
}
|
3920
|
-
const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(amount);
|
3921
|
-
const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
|
3922
|
-
console.log("Withdrawal Fee:", {
|
3923
|
-
feePercent,
|
3924
|
-
withdrawFee,
|
3925
|
-
minFee: brgConfig.withdraw_bridge_fee.fee_min
|
3926
|
-
});
|
3927
|
-
const gasLimit = yield calculateGasLimit({
|
4118
|
+
const _feeRate = feeRate || (yield getBtcGasPrice());
|
4119
|
+
const _a = yield calculateWithdraw({
|
4120
|
+
amount,
|
4121
|
+
feeRate: _feeRate,
|
3928
4122
|
csna,
|
3929
|
-
|
3930
|
-
{
|
3931
|
-
signerId: "",
|
3932
|
-
receiverId: config.btcToken,
|
3933
|
-
actions: [
|
3934
|
-
{
|
3935
|
-
type: "FunctionCall",
|
3936
|
-
params: {
|
3937
|
-
methodName: "ft_transfer_call",
|
3938
|
-
args: {
|
3939
|
-
receiver_id: config.btcToken,
|
3940
|
-
amount: "100",
|
3941
|
-
msg: ""
|
3942
|
-
},
|
3943
|
-
gas: "300000000000000",
|
3944
|
-
deposit: "1"
|
3945
|
-
}
|
3946
|
-
}
|
3947
|
-
]
|
3948
|
-
}
|
3949
|
-
],
|
4123
|
+
btcAddress,
|
3950
4124
|
env
|
3951
|
-
});
|
3952
|
-
|
3953
|
-
|
3954
|
-
console.log("All UTXOs:", allUTXO);
|
3955
|
-
if (!allUTXO || Object.keys(allUTXO).length === 0) {
|
3956
|
-
throw new Error("The network is busy, please try again later.");
|
4125
|
+
}), { inputs, outputs, isError, errorMsg } = _a, rest = __objRest(_a, ["inputs", "outputs", "isError", "errorMsg"]);
|
4126
|
+
if (isError || !inputs || !outputs) {
|
4127
|
+
throw new Error(errorMsg);
|
3957
4128
|
}
|
3958
|
-
|
3959
|
-
|
3960
|
-
|
3961
|
-
|
3962
|
-
|
3963
|
-
value: Number(allUTXO[key].balance),
|
3964
|
-
script: allUTXO[key].script
|
3965
|
-
};
|
3966
|
-
});
|
3967
|
-
console.log("Formatted UTXOs:", utxos);
|
3968
|
-
const _feeRate = feeRate || (yield getBtcGasPrice());
|
3969
|
-
console.log("Fee Rate:", _feeRate);
|
3970
|
-
const coinSelectResult = coinselect(
|
3971
|
-
utxos,
|
3972
|
-
[{ address: btcAddress, value: Number(finalAmount) }],
|
3973
|
-
Math.ceil(_feeRate)
|
4129
|
+
console.log("inputs:", JSON.stringify(inputs));
|
4130
|
+
console.log("outputs:", JSON.stringify(outputs));
|
4131
|
+
console.log("inputs - outputs = gas");
|
4132
|
+
console.log(
|
4133
|
+
`(${inputs.map((item) => item.value).join(" + ")}) - (${outputs.map((item) => item.value).join(" + ")}) = ${rest.gasFee}`
|
3974
4134
|
);
|
3975
|
-
console.log("Coinselect Result:", coinSelectResult);
|
3976
|
-
const { inputs, outputs, fee } = coinSelectResult;
|
3977
|
-
if (!outputs || !inputs) {
|
3978
|
-
throw new Error("The network is busy, please try again later.");
|
3979
|
-
}
|
3980
|
-
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
3981
|
-
const transactionFee = fee;
|
3982
|
-
console.log("Transaction Fee:", { transactionFee, maxBtcFee });
|
3983
|
-
if (transactionFee > maxBtcFee) {
|
3984
|
-
throw new Error("Gas exceeds maximum value");
|
3985
|
-
}
|
3986
|
-
let recipientOutput, changeOutput;
|
3987
|
-
for (let i = 0; i < outputs.length; i++) {
|
3988
|
-
const output = outputs[i];
|
3989
|
-
if (output.value.toString() === finalAmount.toString()) {
|
3990
|
-
recipientOutput = output;
|
3991
|
-
} else {
|
3992
|
-
changeOutput = output;
|
3993
|
-
}
|
3994
|
-
if (!output.address) {
|
3995
|
-
output.address = brgConfig.change_address;
|
3996
|
-
}
|
3997
|
-
}
|
3998
|
-
console.log("Initial Outputs:", { recipientOutput, changeOutput });
|
3999
|
-
recipientOutput.value = new Big2(recipientOutput.value).minus(transactionFee).minus(withdrawFee).toNumber();
|
4000
|
-
if (changeOutput) {
|
4001
|
-
changeOutput.value = new Big2(changeOutput.value).plus(transactionFee).plus(withdrawFee).toNumber();
|
4002
|
-
const remainingInputs = [...inputs];
|
4003
|
-
let smallestInput = Math.min.apply(
|
4004
|
-
null,
|
4005
|
-
remainingInputs.map((input) => input.value)
|
4006
|
-
);
|
4007
|
-
let remainingChangeAmount = changeOutput.value;
|
4008
|
-
console.log("Initial Change Processing:", { smallestInput, remainingChangeAmount });
|
4009
|
-
while (remainingChangeAmount >= smallestInput && smallestInput > 0 && remainingInputs.length > 0) {
|
4010
|
-
remainingChangeAmount -= smallestInput;
|
4011
|
-
changeOutput.value = remainingChangeAmount;
|
4012
|
-
const smallestInputIndex = remainingInputs.findIndex(
|
4013
|
-
(input) => input.value === smallestInput
|
4014
|
-
);
|
4015
|
-
if (smallestInputIndex > -1) {
|
4016
|
-
remainingInputs.splice(smallestInputIndex, 1);
|
4017
|
-
}
|
4018
|
-
smallestInput = Math.min.apply(
|
4019
|
-
null,
|
4020
|
-
remainingInputs.map((input) => input.value)
|
4021
|
-
);
|
4022
|
-
console.log("Change Processing Loop:", {
|
4023
|
-
remainingChangeAmount,
|
4024
|
-
smallestInput,
|
4025
|
-
remainingInputsCount: remainingInputs.length
|
4026
|
-
});
|
4027
|
-
}
|
4028
|
-
const minChangeAmount = Number(brgConfig.min_change_amount);
|
4029
|
-
let additionalFee = 0;
|
4030
|
-
console.log("Checking minimum change amount:", {
|
4031
|
-
changeValue: changeOutput.value,
|
4032
|
-
minChangeAmount
|
4033
|
-
});
|
4034
|
-
let finalOutputs = [...outputs];
|
4035
|
-
if (changeOutput.value === 0) {
|
4036
|
-
finalOutputs = finalOutputs.filter((output) => output.value !== 0);
|
4037
|
-
console.log("Removed zero-value change output", finalOutputs);
|
4038
|
-
} else if (changeOutput.value < minChangeAmount) {
|
4039
|
-
additionalFee = minChangeAmount - changeOutput.value;
|
4040
|
-
recipientOutput.value -= additionalFee;
|
4041
|
-
changeOutput.value = minChangeAmount;
|
4042
|
-
console.log("Adjusted for minimum change amount:", {
|
4043
|
-
additionalFee,
|
4044
|
-
newRecipientValue: recipientOutput.value,
|
4045
|
-
newChangeValue: changeOutput.value
|
4046
|
-
});
|
4047
|
-
}
|
4048
|
-
} else {
|
4049
|
-
changeOutput = {
|
4050
|
-
address: brgConfig.change_address,
|
4051
|
-
value: new Big2(transactionFee).plus(withdrawFee).toNumber()
|
4052
|
-
};
|
4053
|
-
outputs.push(changeOutput);
|
4054
|
-
console.log("Created new change output:", changeOutput);
|
4055
|
-
}
|
4056
|
-
const insufficientOutput = outputs.some((item) => item.value < 0);
|
4057
|
-
if (insufficientOutput) {
|
4058
|
-
console.error("Negative output value detected");
|
4059
|
-
throw new Error("Not enough gas");
|
4060
|
-
}
|
4061
|
-
const inputSum = inputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
4062
|
-
const outputSum = outputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
4063
|
-
console.log("Balance verification:", { inputSum, outputSum, transactionFee });
|
4064
|
-
if (transactionFee + outputSum !== inputSum) {
|
4065
|
-
console.error("Balance mismatch:", { inputSum, outputSum, transactionFee });
|
4066
|
-
throw new Error("compute error");
|
4067
|
-
}
|
4068
4135
|
const network = yield getNetwork();
|
4069
4136
|
const btcNetwork = network === "mainnet" ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
|
4070
4137
|
const psbt = new bitcoin.Psbt({ network: btcNetwork });
|
4071
4138
|
const btcRpcUrl = yield getBtcRpcUrl();
|
4072
|
-
|
4073
|
-
|
4074
|
-
|
4075
|
-
|
4076
|
-
|
4077
|
-
|
4078
|
-
|
4079
|
-
|
4080
|
-
|
4081
|
-
|
4082
|
-
|
4083
|
-
|
4084
|
-
|
4085
|
-
|
4139
|
+
Promise.all(
|
4140
|
+
inputs.map((input) => __async(this, null, function* () {
|
4141
|
+
const txData = yield fetch(`${btcRpcUrl}/tx/${input.txid}`).then((res) => res.json());
|
4142
|
+
const inputOptions = {
|
4143
|
+
hash: input.txid,
|
4144
|
+
index: input.vout,
|
4145
|
+
sequence: 4294967293,
|
4146
|
+
witnessUtxo: {
|
4147
|
+
script: Buffer.from(txData.vout[input.vout].scriptpubkey, "hex"),
|
4148
|
+
value: input.value
|
4149
|
+
}
|
4150
|
+
};
|
4151
|
+
psbt.addInput(inputOptions);
|
4152
|
+
}))
|
4153
|
+
);
|
4086
4154
|
outputs.forEach((output) => {
|
4087
4155
|
psbt.addOutput({
|
4088
4156
|
address: output.address,
|
4089
4157
|
value: output.value
|
4090
4158
|
});
|
4091
4159
|
});
|
4092
|
-
console.log("outputs:", JSON.stringify(outputs));
|
4093
4160
|
const _inputs = inputs.map((item) => {
|
4094
4161
|
return `${item.txid}:${item.vout}`;
|
4095
4162
|
});
|
@@ -4573,6 +4640,7 @@ var BTCWallet = (_0) => __async(void 0, [_0], function* ({
|
|
4573
4640
|
const btcContext = window.btcContext;
|
4574
4641
|
const csna = state_default.getAccount();
|
4575
4642
|
const accountInfo = yield getAccountInfo({ csna, env });
|
4643
|
+
yield checkGasTokenDebt(csna, env, true);
|
4576
4644
|
const trans = [...params.transactions];
|
4577
4645
|
console.log("signAndSendTransactions raw trans:", trans);
|
4578
4646
|
const { transferGasTransaction, useNearPayGas, gasLimit } = yield calculateGasStrategy({
|
@@ -4673,7 +4741,7 @@ function setupBTCWallet({
|
|
4673
4741
|
|
4674
4742
|
// src/index.ts
|
4675
4743
|
var getVersion = () => {
|
4676
|
-
return "0.5.
|
4744
|
+
return "0.5.21-beta";
|
4677
4745
|
};
|
4678
4746
|
if (typeof window !== "undefined") {
|
4679
4747
|
window.__BTC_WALLET_VERSION = getVersion();
|