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.
@@ -1,7 +1,7 @@
1
1
  import type { ENV } from '../config';
2
- import { calculateWithdraw, calculateGasLimit } from '../utils/satoshi';
2
+ import { calculateGasLimit } from '../utils/satoshi';
3
3
  import type { FinalExecutionOutcome, Transaction } from '@near-wallet-selector/core';
4
- export { calculateGasLimit, calculateWithdraw };
4
+ export { calculateGasLimit };
5
5
  type CheckGasTokenDebtReturnType<T extends boolean> = T extends true ? void : {
6
6
  receiver_id: string;
7
7
  amount: string;
@@ -69,3 +69,21 @@ interface WithdrawParams {
69
69
  env?: ENV;
70
70
  }
71
71
  export declare function getWithdrawTransaction({ amount, feeRate, csna, btcAddress, env, }: WithdrawParams): Promise<Transaction>;
72
+ interface CalculateWithdrawParams {
73
+ amount: string | number;
74
+ feeRate?: number;
75
+ csna?: string;
76
+ btcAddress?: string;
77
+ env: ENV;
78
+ }
79
+ interface CalculateWithdrawResult {
80
+ withdrawFee: number;
81
+ gasFee?: number;
82
+ inputs?: any[];
83
+ outputs?: any[];
84
+ fromAmount?: number;
85
+ receiveAmount?: string;
86
+ isError: boolean;
87
+ errorMsg?: string;
88
+ }
89
+ export declare function calculateWithdraw({ amount, feeRate: _feeRate, csna: _csna, btcAddress: _btcAddress, env, }: CalculateWithdrawParams): Promise<CalculateWithdrawResult>;
package/dist/index.js CHANGED
@@ -3211,7 +3211,6 @@ var state_default = {
3211
3211
  };
3212
3212
 
3213
3213
  // src/utils/satoshi.ts
3214
- var import_coinselect = __toESM(require("coinselect"), 1);
3215
3214
  function getNonce(url, accountId) {
3216
3215
  return __async(this, null, function* () {
3217
3216
  const { result_code, result_message, result_data } = yield request(
@@ -3653,196 +3652,10 @@ function getPredictedGasAmount(_0) {
3653
3652
  return gasAmount.toString();
3654
3653
  });
3655
3654
  }
3656
- function calculateWithdraw(_0) {
3657
- return __async(this, arguments, function* ({
3658
- amount,
3659
- feeRate,
3660
- csna,
3661
- btcAddress,
3662
- env
3663
- }) {
3664
- try {
3665
- const config = getWalletConfig(env);
3666
- const _feeRate = feeRate || (yield getBtcGasPrice());
3667
- const gasLimit = yield calculateGasLimit({
3668
- csna,
3669
- transactions: [
3670
- {
3671
- signerId: "",
3672
- receiverId: config.btcToken,
3673
- actions: [
3674
- {
3675
- type: "FunctionCall",
3676
- params: {
3677
- methodName: "ft_transfer_call",
3678
- args: {
3679
- receiver_id: config.btcToken,
3680
- amount: "100",
3681
- msg: ""
3682
- },
3683
- gas: "300000000000000",
3684
- deposit: "1"
3685
- }
3686
- }
3687
- ]
3688
- }
3689
- ],
3690
- env
3691
- });
3692
- let satoshis = Number(amount);
3693
- if (Number(gasLimit) > 0) {
3694
- satoshis = new import_big.default(amount).minus(gasLimit).toNumber();
3695
- }
3696
- const brgConfig = yield getBridgeConfig({ env });
3697
- const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
3698
- if (brgConfig.min_withdraw_amount) {
3699
- if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
3700
- return {
3701
- withdrawFee: 0,
3702
- isError: true,
3703
- errorMsg: `Mini withdraw amount is ${Number(brgConfig.min_withdraw_amount) + Number(gasLimit)} sats`
3704
- };
3705
- }
3706
- }
3707
- const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
3708
- const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
3709
- const withdrawChangeAddress = brgConfig.change_address;
3710
- const utxos = Object.keys(allUTXO).map((key) => {
3711
- const txid = key.split("@");
3712
- return {
3713
- txid: txid[0],
3714
- vout: allUTXO[key].vout,
3715
- value: Number(allUTXO[key].balance),
3716
- script: allUTXO[key].script
3717
- };
3718
- }).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
3719
- if (!utxos || utxos.length === 0) {
3720
- return {
3721
- withdrawFee,
3722
- isError: true,
3723
- errorMsg: "The network is busy, please try again later."
3724
- };
3725
- }
3726
- const userSatoshis = Number(satoshis);
3727
- const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
3728
- const { inputs, outputs, fee } = (0, import_coinselect.default)(
3729
- utxos,
3730
- [{ address: btcAddress, value: userSatoshis }],
3731
- Math.ceil(_feeRate)
3732
- );
3733
- const newInputs = inputs;
3734
- let newOutputs = outputs;
3735
- let newFee = fee;
3736
- if (!newOutputs || newOutputs.length === 0) {
3737
- return {
3738
- withdrawFee,
3739
- isError: true,
3740
- errorMsg: "The network is busy, please try again later."
3741
- };
3742
- }
3743
- let userOutput, noUserOutput;
3744
- for (let i = 0; i < newOutputs.length; i++) {
3745
- const output = newOutputs[i];
3746
- if (output.value.toString() === userSatoshis.toString()) {
3747
- userOutput = output;
3748
- } else {
3749
- noUserOutput = output;
3750
- }
3751
- if (!output.address) {
3752
- output.address = withdrawChangeAddress;
3753
- }
3754
- }
3755
- let dis = 0;
3756
- if (newFee > maxBtcFee) {
3757
- dis = newFee - maxBtcFee;
3758
- newFee = maxBtcFee;
3759
- return {
3760
- gasFee: newFee,
3761
- withdrawFee,
3762
- isError: true,
3763
- errorMsg: "Gas exceeds maximum value"
3764
- };
3765
- }
3766
- userOutput.value = new import_big.default(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
3767
- if (userOutput.value < 0) {
3768
- return {
3769
- gasFee: newFee,
3770
- withdrawFee,
3771
- isError: true,
3772
- errorMsg: "Not enough gas"
3773
- };
3774
- }
3775
- if (noUserOutput) {
3776
- if (!noUserOutput.address) {
3777
- noUserOutput.address = withdrawChangeAddress;
3778
- }
3779
- noUserOutput.value = new import_big.default(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
3780
- } else {
3781
- noUserOutput = {
3782
- address: withdrawChangeAddress,
3783
- value: new import_big.default(newFee).plus(withdrawFee).plus(dis).toNumber()
3784
- };
3785
- newOutputs.push(noUserOutput);
3786
- }
3787
- let minValue = Math.min(...newInputs.map((input) => input.value));
3788
- let totalNoUserOutputValue = noUserOutput.value;
3789
- while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
3790
- totalNoUserOutputValue -= minValue;
3791
- noUserOutput.value = totalNoUserOutputValue;
3792
- const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
3793
- if (minValueIndex > -1) {
3794
- newInputs.splice(minValueIndex, 1);
3795
- }
3796
- minValue = Math.min(...newInputs.map((input) => input.value));
3797
- }
3798
- let gasMore = 0;
3799
- if (noUserOutput.value === 0) {
3800
- newOutputs = newOutputs.filter((item) => item.value !== 0);
3801
- } else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
3802
- gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
3803
- userOutput.value -= gasMore;
3804
- noUserOutput.value = Number(brgConfig.min_change_amount);
3805
- }
3806
- const insufficientOutput = newOutputs.some((item) => item.value < 0);
3807
- if (insufficientOutput) {
3808
- return {
3809
- gasFee: newFee,
3810
- withdrawFee,
3811
- isError: true,
3812
- errorMsg: "Not enough gas"
3813
- };
3814
- }
3815
- const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3816
- const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3817
- if (newFee + outputSum !== inputSum) {
3818
- return {
3819
- withdrawFee,
3820
- isError: true,
3821
- errorMsg: "Service busy, please try again later"
3822
- };
3823
- }
3824
- return {
3825
- withdrawFee: new import_big.default(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
3826
- gasFee: new import_big.default(newFee).toNumber(),
3827
- inputs: newInputs,
3828
- outputs: newOutputs,
3829
- fromAmount: satoshis,
3830
- receiveAmount: userOutput.value,
3831
- isError: false
3832
- };
3833
- } catch (error) {
3834
- return {
3835
- withdrawFee: 0,
3836
- isError: true,
3837
- errorMsg: error.message
3838
- };
3839
- }
3840
- });
3841
- }
3842
3655
 
3843
3656
  // src/core/btcUtils.ts
3844
3657
  var bitcoin = __toESM(require("bitcoinjs-lib"), 1);
3845
- var import_coinselect2 = __toESM(require("coinselect"), 1);
3658
+ var import_coinselect = __toESM(require("coinselect"), 1);
3846
3659
  var ecc = __toESM(require("@bitcoinerlab/secp256k1"), 1);
3847
3660
  bitcoin.initEccLib(ecc);
3848
3661
  var NEAR_STORAGE_DEPOSIT_AMOUNT = "1250000000000000000000";
@@ -3938,7 +3751,7 @@ function calculateGasFee(account, amount, feeRate) {
3938
3751
  return __async(this, null, function* () {
3939
3752
  const _feeRate = feeRate || (yield getBtcGasPrice());
3940
3753
  const utxos = yield getBtcUtxos(account);
3941
- const { fee } = (0, import_coinselect2.default)(utxos, [{ address: account, value: amount }], Math.ceil(_feeRate));
3754
+ const { fee } = (0, import_coinselect.default)(utxos, [{ address: account, value: amount }], Math.ceil(_feeRate));
3942
3755
  console.log("calculateGasFee fee:", fee);
3943
3756
  return fee;
3944
3757
  });
@@ -4278,6 +4091,201 @@ function getWithdrawTransaction(_0) {
4278
4091
  return transaction;
4279
4092
  });
4280
4093
  }
4094
+ function calculateWithdraw(_0) {
4095
+ return __async(this, arguments, function* ({
4096
+ amount,
4097
+ feeRate: _feeRate,
4098
+ csna: _csna,
4099
+ btcAddress: _btcAddress,
4100
+ env
4101
+ }) {
4102
+ try {
4103
+ const config = getWalletConfig(env);
4104
+ let btcAddress = _btcAddress || getBtcProvider().account;
4105
+ if (!btcAddress) {
4106
+ yield getBtcProvider().autoConnect();
4107
+ btcAddress = getBtcProvider().account;
4108
+ if (!btcAddress) {
4109
+ throw new Error("BTC Account is not available.");
4110
+ }
4111
+ }
4112
+ const csna = _csna || (yield getCsnaAccountId(env));
4113
+ const feeRate = _feeRate || (yield getBtcGasPrice());
4114
+ const gasLimit = yield calculateGasLimit({
4115
+ csna,
4116
+ transactions: [
4117
+ {
4118
+ signerId: "",
4119
+ receiverId: config.btcToken,
4120
+ actions: [
4121
+ {
4122
+ type: "FunctionCall",
4123
+ params: {
4124
+ methodName: "ft_transfer_call",
4125
+ args: {
4126
+ receiver_id: config.btcToken,
4127
+ amount: "100",
4128
+ msg: ""
4129
+ },
4130
+ gas: "300000000000000",
4131
+ deposit: "1"
4132
+ }
4133
+ }
4134
+ ]
4135
+ }
4136
+ ],
4137
+ env
4138
+ });
4139
+ let satoshis = Number(amount);
4140
+ if (Number(gasLimit) > 0) {
4141
+ satoshis = new import_big2.default(amount).minus(gasLimit).toNumber();
4142
+ }
4143
+ const brgConfig = yield getBridgeConfig({ env });
4144
+ const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
4145
+ if (brgConfig.min_withdraw_amount) {
4146
+ if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
4147
+ return {
4148
+ withdrawFee: 0,
4149
+ isError: true,
4150
+ errorMsg: `Mini withdraw amount is ${Number(brgConfig.min_withdraw_amount) + Number(gasLimit)} sats`
4151
+ };
4152
+ }
4153
+ }
4154
+ const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
4155
+ const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
4156
+ const withdrawChangeAddress = brgConfig.change_address;
4157
+ const utxos = Object.keys(allUTXO).map((key) => {
4158
+ const txid = key.split("@");
4159
+ return {
4160
+ txid: txid[0],
4161
+ vout: allUTXO[key].vout,
4162
+ value: Number(allUTXO[key].balance),
4163
+ script: allUTXO[key].script
4164
+ };
4165
+ }).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
4166
+ if (!utxos || utxos.length === 0) {
4167
+ return {
4168
+ withdrawFee,
4169
+ isError: true,
4170
+ errorMsg: "The network is busy, please try again later."
4171
+ };
4172
+ }
4173
+ const userSatoshis = Number(satoshis);
4174
+ const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
4175
+ const { inputs, outputs, fee } = (0, import_coinselect.default)(
4176
+ utxos,
4177
+ [{ address: btcAddress, value: userSatoshis }],
4178
+ Math.ceil(feeRate)
4179
+ );
4180
+ const newInputs = inputs;
4181
+ let newOutputs = outputs;
4182
+ let newFee = fee;
4183
+ if (!newOutputs || newOutputs.length === 0) {
4184
+ return {
4185
+ withdrawFee,
4186
+ isError: true,
4187
+ errorMsg: "The network is busy, please try again later."
4188
+ };
4189
+ }
4190
+ let userOutput, noUserOutput;
4191
+ for (let i = 0; i < newOutputs.length; i++) {
4192
+ const output = newOutputs[i];
4193
+ if (output.value.toString() === userSatoshis.toString()) {
4194
+ userOutput = output;
4195
+ } else {
4196
+ noUserOutput = output;
4197
+ }
4198
+ if (!output.address) {
4199
+ output.address = withdrawChangeAddress;
4200
+ }
4201
+ }
4202
+ let dis = 0;
4203
+ if (newFee > maxBtcFee) {
4204
+ dis = newFee - maxBtcFee;
4205
+ newFee = maxBtcFee;
4206
+ return {
4207
+ gasFee: newFee,
4208
+ withdrawFee,
4209
+ isError: true,
4210
+ errorMsg: "Gas exceeds maximum value"
4211
+ };
4212
+ }
4213
+ userOutput.value = new import_big2.default(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
4214
+ if (userOutput.value < 0) {
4215
+ return {
4216
+ gasFee: newFee,
4217
+ withdrawFee,
4218
+ isError: true,
4219
+ errorMsg: "Not enough gas"
4220
+ };
4221
+ }
4222
+ if (noUserOutput) {
4223
+ if (!noUserOutput.address) {
4224
+ noUserOutput.address = withdrawChangeAddress;
4225
+ }
4226
+ noUserOutput.value = new import_big2.default(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
4227
+ } else {
4228
+ noUserOutput = {
4229
+ address: withdrawChangeAddress,
4230
+ value: new import_big2.default(newFee).plus(withdrawFee).plus(dis).toNumber()
4231
+ };
4232
+ newOutputs.push(noUserOutput);
4233
+ }
4234
+ let minValue = Math.min(...newInputs.map((input) => input.value));
4235
+ let totalNoUserOutputValue = noUserOutput.value;
4236
+ while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
4237
+ totalNoUserOutputValue -= minValue;
4238
+ noUserOutput.value = totalNoUserOutputValue;
4239
+ const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
4240
+ if (minValueIndex > -1) {
4241
+ newInputs.splice(minValueIndex, 1);
4242
+ }
4243
+ minValue = Math.min(...newInputs.map((input) => input.value));
4244
+ }
4245
+ let gasMore = 0;
4246
+ if (noUserOutput.value === 0) {
4247
+ newOutputs = newOutputs.filter((item) => item.value !== 0);
4248
+ } else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
4249
+ gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
4250
+ userOutput.value -= gasMore;
4251
+ noUserOutput.value = Number(brgConfig.min_change_amount);
4252
+ }
4253
+ const insufficientOutput = newOutputs.some((item) => item.value < 0);
4254
+ if (insufficientOutput) {
4255
+ return {
4256
+ gasFee: newFee,
4257
+ withdrawFee,
4258
+ isError: true,
4259
+ errorMsg: "Not enough gas"
4260
+ };
4261
+ }
4262
+ const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
4263
+ const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
4264
+ if (newFee + outputSum !== inputSum) {
4265
+ return {
4266
+ withdrawFee,
4267
+ isError: true,
4268
+ errorMsg: "Service busy, please try again later"
4269
+ };
4270
+ }
4271
+ return {
4272
+ withdrawFee: new import_big2.default(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
4273
+ gasFee: new import_big2.default(newFee).toNumber(),
4274
+ inputs: newInputs,
4275
+ outputs: newOutputs,
4276
+ fromAmount: satoshis,
4277
+ receiveAmount: userOutput.value,
4278
+ isError: false
4279
+ };
4280
+ } catch (error) {
4281
+ return {
4282
+ withdrawFee: 0,
4283
+ isError: true,
4284
+ errorMsg: error.message
4285
+ };
4286
+ }
4287
+ });
4288
+ }
4281
4289
  function uint8ArrayToHex(uint8Array) {
4282
4290
  return Array.from(uint8Array).map((byte) => byte.toString(16).padStart(2, "0")).join("");
4283
4291
  }
@@ -4917,7 +4925,7 @@ function getGroup(state) {
4917
4925
 
4918
4926
  // src/index.ts
4919
4927
  var getVersion = () => {
4920
- return "0.5.42-beta";
4928
+ return "0.5.44-beta";
4921
4929
  };
4922
4930
  if (typeof window !== "undefined") {
4923
4931
  window.__BTC_WALLET_VERSION = getVersion();