btc-wallet 0.5.42-beta → 0.5.44-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/core/btcUtils.d.ts +20 -2
- package/dist/index.js +198 -190
- package/dist/index.js.map +3 -3
- package/dist/utils/satoshi.d.ts +0 -18
- package/esm/index.js +198 -190
- package/esm/index.js.map +3 -3
- package/package.json +2 -1
package/dist/utils/satoshi.d.ts
CHANGED
@@ -86,22 +86,4 @@ export declare function calculateGasStrategy({ csna, transactions, env, }: Calcu
|
|
86
86
|
useNearPayGas: boolean;
|
87
87
|
gasLimit: string;
|
88
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>;
|
107
89
|
export {};
|
package/esm/index.js
CHANGED
@@ -3142,7 +3142,6 @@ var state_default = {
|
|
3142
3142
|
};
|
3143
3143
|
|
3144
3144
|
// src/utils/satoshi.ts
|
3145
|
-
import coinselect from "coinselect";
|
3146
3145
|
function getNonce(url, accountId) {
|
3147
3146
|
return __async(this, null, function* () {
|
3148
3147
|
const { result_code, result_message, result_data } = yield request(
|
@@ -3584,196 +3583,10 @@ function getPredictedGasAmount(_0) {
|
|
3584
3583
|
return gasAmount.toString();
|
3585
3584
|
});
|
3586
3585
|
}
|
3587
|
-
function calculateWithdraw(_0) {
|
3588
|
-
return __async(this, arguments, function* ({
|
3589
|
-
amount,
|
3590
|
-
feeRate,
|
3591
|
-
csna,
|
3592
|
-
btcAddress,
|
3593
|
-
env
|
3594
|
-
}) {
|
3595
|
-
try {
|
3596
|
-
const config = getWalletConfig(env);
|
3597
|
-
const _feeRate = feeRate || (yield getBtcGasPrice());
|
3598
|
-
const gasLimit = yield calculateGasLimit({
|
3599
|
-
csna,
|
3600
|
-
transactions: [
|
3601
|
-
{
|
3602
|
-
signerId: "",
|
3603
|
-
receiverId: config.btcToken,
|
3604
|
-
actions: [
|
3605
|
-
{
|
3606
|
-
type: "FunctionCall",
|
3607
|
-
params: {
|
3608
|
-
methodName: "ft_transfer_call",
|
3609
|
-
args: {
|
3610
|
-
receiver_id: config.btcToken,
|
3611
|
-
amount: "100",
|
3612
|
-
msg: ""
|
3613
|
-
},
|
3614
|
-
gas: "300000000000000",
|
3615
|
-
deposit: "1"
|
3616
|
-
}
|
3617
|
-
}
|
3618
|
-
]
|
3619
|
-
}
|
3620
|
-
],
|
3621
|
-
env
|
3622
|
-
});
|
3623
|
-
let satoshis = Number(amount);
|
3624
|
-
if (Number(gasLimit) > 0) {
|
3625
|
-
satoshis = new Big(amount).minus(gasLimit).toNumber();
|
3626
|
-
}
|
3627
|
-
const brgConfig = yield getBridgeConfig({ env });
|
3628
|
-
const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
|
3629
|
-
if (brgConfig.min_withdraw_amount) {
|
3630
|
-
if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
|
3631
|
-
return {
|
3632
|
-
withdrawFee: 0,
|
3633
|
-
isError: true,
|
3634
|
-
errorMsg: `Mini withdraw amount is ${Number(brgConfig.min_withdraw_amount) + Number(gasLimit)} sats`
|
3635
|
-
};
|
3636
|
-
}
|
3637
|
-
}
|
3638
|
-
const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
|
3639
|
-
const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
|
3640
|
-
const withdrawChangeAddress = brgConfig.change_address;
|
3641
|
-
const utxos = Object.keys(allUTXO).map((key) => {
|
3642
|
-
const txid = key.split("@");
|
3643
|
-
return {
|
3644
|
-
txid: txid[0],
|
3645
|
-
vout: allUTXO[key].vout,
|
3646
|
-
value: Number(allUTXO[key].balance),
|
3647
|
-
script: allUTXO[key].script
|
3648
|
-
};
|
3649
|
-
}).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
|
3650
|
-
if (!utxos || utxos.length === 0) {
|
3651
|
-
return {
|
3652
|
-
withdrawFee,
|
3653
|
-
isError: true,
|
3654
|
-
errorMsg: "The network is busy, please try again later."
|
3655
|
-
};
|
3656
|
-
}
|
3657
|
-
const userSatoshis = Number(satoshis);
|
3658
|
-
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
3659
|
-
const { inputs, outputs, fee } = coinselect(
|
3660
|
-
utxos,
|
3661
|
-
[{ address: btcAddress, value: userSatoshis }],
|
3662
|
-
Math.ceil(_feeRate)
|
3663
|
-
);
|
3664
|
-
const newInputs = inputs;
|
3665
|
-
let newOutputs = outputs;
|
3666
|
-
let newFee = fee;
|
3667
|
-
if (!newOutputs || newOutputs.length === 0) {
|
3668
|
-
return {
|
3669
|
-
withdrawFee,
|
3670
|
-
isError: true,
|
3671
|
-
errorMsg: "The network is busy, please try again later."
|
3672
|
-
};
|
3673
|
-
}
|
3674
|
-
let userOutput, noUserOutput;
|
3675
|
-
for (let i = 0; i < newOutputs.length; i++) {
|
3676
|
-
const output = newOutputs[i];
|
3677
|
-
if (output.value.toString() === userSatoshis.toString()) {
|
3678
|
-
userOutput = output;
|
3679
|
-
} else {
|
3680
|
-
noUserOutput = output;
|
3681
|
-
}
|
3682
|
-
if (!output.address) {
|
3683
|
-
output.address = withdrawChangeAddress;
|
3684
|
-
}
|
3685
|
-
}
|
3686
|
-
let dis = 0;
|
3687
|
-
if (newFee > maxBtcFee) {
|
3688
|
-
dis = newFee - maxBtcFee;
|
3689
|
-
newFee = maxBtcFee;
|
3690
|
-
return {
|
3691
|
-
gasFee: newFee,
|
3692
|
-
withdrawFee,
|
3693
|
-
isError: true,
|
3694
|
-
errorMsg: "Gas exceeds maximum value"
|
3695
|
-
};
|
3696
|
-
}
|
3697
|
-
userOutput.value = new Big(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
|
3698
|
-
if (userOutput.value < 0) {
|
3699
|
-
return {
|
3700
|
-
gasFee: newFee,
|
3701
|
-
withdrawFee,
|
3702
|
-
isError: true,
|
3703
|
-
errorMsg: "Not enough gas"
|
3704
|
-
};
|
3705
|
-
}
|
3706
|
-
if (noUserOutput) {
|
3707
|
-
if (!noUserOutput.address) {
|
3708
|
-
noUserOutput.address = withdrawChangeAddress;
|
3709
|
-
}
|
3710
|
-
noUserOutput.value = new Big(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
|
3711
|
-
} else {
|
3712
|
-
noUserOutput = {
|
3713
|
-
address: withdrawChangeAddress,
|
3714
|
-
value: new Big(newFee).plus(withdrawFee).plus(dis).toNumber()
|
3715
|
-
};
|
3716
|
-
newOutputs.push(noUserOutput);
|
3717
|
-
}
|
3718
|
-
let minValue = Math.min(...newInputs.map((input) => input.value));
|
3719
|
-
let totalNoUserOutputValue = noUserOutput.value;
|
3720
|
-
while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
|
3721
|
-
totalNoUserOutputValue -= minValue;
|
3722
|
-
noUserOutput.value = totalNoUserOutputValue;
|
3723
|
-
const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
|
3724
|
-
if (minValueIndex > -1) {
|
3725
|
-
newInputs.splice(minValueIndex, 1);
|
3726
|
-
}
|
3727
|
-
minValue = Math.min(...newInputs.map((input) => input.value));
|
3728
|
-
}
|
3729
|
-
let gasMore = 0;
|
3730
|
-
if (noUserOutput.value === 0) {
|
3731
|
-
newOutputs = newOutputs.filter((item) => item.value !== 0);
|
3732
|
-
} else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
|
3733
|
-
gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
|
3734
|
-
userOutput.value -= gasMore;
|
3735
|
-
noUserOutput.value = Number(brgConfig.min_change_amount);
|
3736
|
-
}
|
3737
|
-
const insufficientOutput = newOutputs.some((item) => item.value < 0);
|
3738
|
-
if (insufficientOutput) {
|
3739
|
-
return {
|
3740
|
-
gasFee: newFee,
|
3741
|
-
withdrawFee,
|
3742
|
-
isError: true,
|
3743
|
-
errorMsg: "Not enough gas"
|
3744
|
-
};
|
3745
|
-
}
|
3746
|
-
const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3747
|
-
const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
3748
|
-
if (newFee + outputSum !== inputSum) {
|
3749
|
-
return {
|
3750
|
-
withdrawFee,
|
3751
|
-
isError: true,
|
3752
|
-
errorMsg: "Service busy, please try again later"
|
3753
|
-
};
|
3754
|
-
}
|
3755
|
-
return {
|
3756
|
-
withdrawFee: new Big(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
|
3757
|
-
gasFee: new Big(newFee).toNumber(),
|
3758
|
-
inputs: newInputs,
|
3759
|
-
outputs: newOutputs,
|
3760
|
-
fromAmount: satoshis,
|
3761
|
-
receiveAmount: userOutput.value,
|
3762
|
-
isError: false
|
3763
|
-
};
|
3764
|
-
} catch (error) {
|
3765
|
-
return {
|
3766
|
-
withdrawFee: 0,
|
3767
|
-
isError: true,
|
3768
|
-
errorMsg: error.message
|
3769
|
-
};
|
3770
|
-
}
|
3771
|
-
});
|
3772
|
-
}
|
3773
3586
|
|
3774
3587
|
// src/core/btcUtils.ts
|
3775
3588
|
import * as bitcoin from "bitcoinjs-lib";
|
3776
|
-
import
|
3589
|
+
import coinselect from "coinselect";
|
3777
3590
|
import * as ecc from "@bitcoinerlab/secp256k1";
|
3778
3591
|
bitcoin.initEccLib(ecc);
|
3779
3592
|
var NEAR_STORAGE_DEPOSIT_AMOUNT = "1250000000000000000000";
|
@@ -3869,7 +3682,7 @@ function calculateGasFee(account, amount, feeRate) {
|
|
3869
3682
|
return __async(this, null, function* () {
|
3870
3683
|
const _feeRate = feeRate || (yield getBtcGasPrice());
|
3871
3684
|
const utxos = yield getBtcUtxos(account);
|
3872
|
-
const { fee } =
|
3685
|
+
const { fee } = coinselect(utxos, [{ address: account, value: amount }], Math.ceil(_feeRate));
|
3873
3686
|
console.log("calculateGasFee fee:", fee);
|
3874
3687
|
return fee;
|
3875
3688
|
});
|
@@ -4209,6 +4022,201 @@ function getWithdrawTransaction(_0) {
|
|
4209
4022
|
return transaction;
|
4210
4023
|
});
|
4211
4024
|
}
|
4025
|
+
function calculateWithdraw(_0) {
|
4026
|
+
return __async(this, arguments, function* ({
|
4027
|
+
amount,
|
4028
|
+
feeRate: _feeRate,
|
4029
|
+
csna: _csna,
|
4030
|
+
btcAddress: _btcAddress,
|
4031
|
+
env
|
4032
|
+
}) {
|
4033
|
+
try {
|
4034
|
+
const config = getWalletConfig(env);
|
4035
|
+
let btcAddress = _btcAddress || getBtcProvider().account;
|
4036
|
+
if (!btcAddress) {
|
4037
|
+
yield getBtcProvider().autoConnect();
|
4038
|
+
btcAddress = getBtcProvider().account;
|
4039
|
+
if (!btcAddress) {
|
4040
|
+
throw new Error("BTC Account is not available.");
|
4041
|
+
}
|
4042
|
+
}
|
4043
|
+
const csna = _csna || (yield getCsnaAccountId(env));
|
4044
|
+
const feeRate = _feeRate || (yield getBtcGasPrice());
|
4045
|
+
const gasLimit = yield calculateGasLimit({
|
4046
|
+
csna,
|
4047
|
+
transactions: [
|
4048
|
+
{
|
4049
|
+
signerId: "",
|
4050
|
+
receiverId: config.btcToken,
|
4051
|
+
actions: [
|
4052
|
+
{
|
4053
|
+
type: "FunctionCall",
|
4054
|
+
params: {
|
4055
|
+
methodName: "ft_transfer_call",
|
4056
|
+
args: {
|
4057
|
+
receiver_id: config.btcToken,
|
4058
|
+
amount: "100",
|
4059
|
+
msg: ""
|
4060
|
+
},
|
4061
|
+
gas: "300000000000000",
|
4062
|
+
deposit: "1"
|
4063
|
+
}
|
4064
|
+
}
|
4065
|
+
]
|
4066
|
+
}
|
4067
|
+
],
|
4068
|
+
env
|
4069
|
+
});
|
4070
|
+
let satoshis = Number(amount);
|
4071
|
+
if (Number(gasLimit) > 0) {
|
4072
|
+
satoshis = new Big2(amount).minus(gasLimit).toNumber();
|
4073
|
+
}
|
4074
|
+
const brgConfig = yield getBridgeConfig({ env });
|
4075
|
+
const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
|
4076
|
+
if (brgConfig.min_withdraw_amount) {
|
4077
|
+
if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
|
4078
|
+
return {
|
4079
|
+
withdrawFee: 0,
|
4080
|
+
isError: true,
|
4081
|
+
errorMsg: `Mini withdraw amount is ${Number(brgConfig.min_withdraw_amount) + Number(gasLimit)} sats`
|
4082
|
+
};
|
4083
|
+
}
|
4084
|
+
}
|
4085
|
+
const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
|
4086
|
+
const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
|
4087
|
+
const withdrawChangeAddress = brgConfig.change_address;
|
4088
|
+
const utxos = Object.keys(allUTXO).map((key) => {
|
4089
|
+
const txid = key.split("@");
|
4090
|
+
return {
|
4091
|
+
txid: txid[0],
|
4092
|
+
vout: allUTXO[key].vout,
|
4093
|
+
value: Number(allUTXO[key].balance),
|
4094
|
+
script: allUTXO[key].script
|
4095
|
+
};
|
4096
|
+
}).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
|
4097
|
+
if (!utxos || utxos.length === 0) {
|
4098
|
+
return {
|
4099
|
+
withdrawFee,
|
4100
|
+
isError: true,
|
4101
|
+
errorMsg: "The network is busy, please try again later."
|
4102
|
+
};
|
4103
|
+
}
|
4104
|
+
const userSatoshis = Number(satoshis);
|
4105
|
+
const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
|
4106
|
+
const { inputs, outputs, fee } = coinselect(
|
4107
|
+
utxos,
|
4108
|
+
[{ address: btcAddress, value: userSatoshis }],
|
4109
|
+
Math.ceil(feeRate)
|
4110
|
+
);
|
4111
|
+
const newInputs = inputs;
|
4112
|
+
let newOutputs = outputs;
|
4113
|
+
let newFee = fee;
|
4114
|
+
if (!newOutputs || newOutputs.length === 0) {
|
4115
|
+
return {
|
4116
|
+
withdrawFee,
|
4117
|
+
isError: true,
|
4118
|
+
errorMsg: "The network is busy, please try again later."
|
4119
|
+
};
|
4120
|
+
}
|
4121
|
+
let userOutput, noUserOutput;
|
4122
|
+
for (let i = 0; i < newOutputs.length; i++) {
|
4123
|
+
const output = newOutputs[i];
|
4124
|
+
if (output.value.toString() === userSatoshis.toString()) {
|
4125
|
+
userOutput = output;
|
4126
|
+
} else {
|
4127
|
+
noUserOutput = output;
|
4128
|
+
}
|
4129
|
+
if (!output.address) {
|
4130
|
+
output.address = withdrawChangeAddress;
|
4131
|
+
}
|
4132
|
+
}
|
4133
|
+
let dis = 0;
|
4134
|
+
if (newFee > maxBtcFee) {
|
4135
|
+
dis = newFee - maxBtcFee;
|
4136
|
+
newFee = maxBtcFee;
|
4137
|
+
return {
|
4138
|
+
gasFee: newFee,
|
4139
|
+
withdrawFee,
|
4140
|
+
isError: true,
|
4141
|
+
errorMsg: "Gas exceeds maximum value"
|
4142
|
+
};
|
4143
|
+
}
|
4144
|
+
userOutput.value = new Big2(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
|
4145
|
+
if (userOutput.value < 0) {
|
4146
|
+
return {
|
4147
|
+
gasFee: newFee,
|
4148
|
+
withdrawFee,
|
4149
|
+
isError: true,
|
4150
|
+
errorMsg: "Not enough gas"
|
4151
|
+
};
|
4152
|
+
}
|
4153
|
+
if (noUserOutput) {
|
4154
|
+
if (!noUserOutput.address) {
|
4155
|
+
noUserOutput.address = withdrawChangeAddress;
|
4156
|
+
}
|
4157
|
+
noUserOutput.value = new Big2(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
|
4158
|
+
} else {
|
4159
|
+
noUserOutput = {
|
4160
|
+
address: withdrawChangeAddress,
|
4161
|
+
value: new Big2(newFee).plus(withdrawFee).plus(dis).toNumber()
|
4162
|
+
};
|
4163
|
+
newOutputs.push(noUserOutput);
|
4164
|
+
}
|
4165
|
+
let minValue = Math.min(...newInputs.map((input) => input.value));
|
4166
|
+
let totalNoUserOutputValue = noUserOutput.value;
|
4167
|
+
while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
|
4168
|
+
totalNoUserOutputValue -= minValue;
|
4169
|
+
noUserOutput.value = totalNoUserOutputValue;
|
4170
|
+
const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
|
4171
|
+
if (minValueIndex > -1) {
|
4172
|
+
newInputs.splice(minValueIndex, 1);
|
4173
|
+
}
|
4174
|
+
minValue = Math.min(...newInputs.map((input) => input.value));
|
4175
|
+
}
|
4176
|
+
let gasMore = 0;
|
4177
|
+
if (noUserOutput.value === 0) {
|
4178
|
+
newOutputs = newOutputs.filter((item) => item.value !== 0);
|
4179
|
+
} else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
|
4180
|
+
gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
|
4181
|
+
userOutput.value -= gasMore;
|
4182
|
+
noUserOutput.value = Number(brgConfig.min_change_amount);
|
4183
|
+
}
|
4184
|
+
const insufficientOutput = newOutputs.some((item) => item.value < 0);
|
4185
|
+
if (insufficientOutput) {
|
4186
|
+
return {
|
4187
|
+
gasFee: newFee,
|
4188
|
+
withdrawFee,
|
4189
|
+
isError: true,
|
4190
|
+
errorMsg: "Not enough gas"
|
4191
|
+
};
|
4192
|
+
}
|
4193
|
+
const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
4194
|
+
const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
|
4195
|
+
if (newFee + outputSum !== inputSum) {
|
4196
|
+
return {
|
4197
|
+
withdrawFee,
|
4198
|
+
isError: true,
|
4199
|
+
errorMsg: "Service busy, please try again later"
|
4200
|
+
};
|
4201
|
+
}
|
4202
|
+
return {
|
4203
|
+
withdrawFee: new Big2(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
|
4204
|
+
gasFee: new Big2(newFee).toNumber(),
|
4205
|
+
inputs: newInputs,
|
4206
|
+
outputs: newOutputs,
|
4207
|
+
fromAmount: satoshis,
|
4208
|
+
receiveAmount: userOutput.value,
|
4209
|
+
isError: false
|
4210
|
+
};
|
4211
|
+
} catch (error) {
|
4212
|
+
return {
|
4213
|
+
withdrawFee: 0,
|
4214
|
+
isError: true,
|
4215
|
+
errorMsg: error.message
|
4216
|
+
};
|
4217
|
+
}
|
4218
|
+
});
|
4219
|
+
}
|
4212
4220
|
function uint8ArrayToHex(uint8Array) {
|
4213
4221
|
return Array.from(uint8Array).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
4214
4222
|
}
|
@@ -4850,7 +4858,7 @@ function getGroup(state) {
|
|
4850
4858
|
|
4851
4859
|
// src/index.ts
|
4852
4860
|
var getVersion = () => {
|
4853
|
-
return "0.5.
|
4861
|
+
return "0.5.44-beta";
|
4854
4862
|
};
|
4855
4863
|
if (typeof window !== "undefined") {
|
4856
4864
|
window.__BTC_WALLET_VERSION = getVersion();
|