btc-wallet 0.5.43-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.d.ts CHANGED
@@ -6,5 +6,4 @@ export * from './core/setupBTCWallet/index';
6
6
  export * from './core/btcUtils';
7
7
  export * from './config';
8
8
  export * from './core/setupModal';
9
- export * from './utils/satoshi';
10
9
  export declare const getVersion: () => string;
package/dist/index.js CHANGED
@@ -94,35 +94,20 @@ __export(src_exports, {
94
94
  btcRpcUrls: () => btcRpcUrls,
95
95
  calculateGasFee: () => calculateGasFee,
96
96
  calculateGasLimit: () => calculateGasLimit,
97
- calculateGasStrategy: () => calculateGasStrategy,
98
97
  calculateWithdraw: () => calculateWithdraw,
99
- checkBridgeTransactionStatus: () => checkBridgeTransactionStatus,
100
- checkBtcTransactionStatus: () => checkBtcTransactionStatus,
101
- checkGasTokenBalance: () => checkGasTokenBalance,
102
98
  checkGasTokenDebt: () => checkGasTokenDebt,
103
99
  checkSatoshiWhitelist: () => checkSatoshiWhitelist,
104
- convertTransactionToTxHex: () => convertTransactionToTxHex,
105
100
  estimateDepositAmount: () => estimateDepositAmount,
106
101
  executeBTCDepositAndAction: () => executeBTCDepositAndAction,
107
- getAccountInfo: () => getAccountInfo,
108
- getBridgeConfig: () => getBridgeConfig,
109
102
  getBtcBalance: () => getBtcBalance,
110
103
  getBtcGasPrice: () => getBtcGasPrice,
111
104
  getBtcUtxos: () => getBtcUtxos,
112
105
  getCsnaAccountId: () => getCsnaAccountId,
113
106
  getDepositAmount: () => getDepositAmount,
114
- getNearNonce: () => getNearNonce,
115
- getNonce: () => getNonce,
116
- getTokenBalance: () => getTokenBalance,
117
107
  getVersion: () => getVersion,
118
108
  getWalletConfig: () => getWalletConfig,
119
- getWhitelist: () => getWhitelist,
120
109
  getWithdrawTransaction: () => getWithdrawTransaction,
121
110
  nearRpcUrls: () => nearRpcUrls,
122
- preReceiveDepositMsg: () => preReceiveDepositMsg,
123
- receiveDepositMsg: () => receiveDepositMsg,
124
- receiveTransaction: () => receiveTransaction,
125
- receiveWithdrawMsg: () => receiveWithdrawMsg,
126
111
  sendBitcoin: () => sendBitcoin,
127
112
  setupBTCWallet: () => setupBTCWallet,
128
113
  setupWalletSelectorModal: () => setupWalletSelectorModal,
@@ -3226,7 +3211,6 @@ var state_default = {
3226
3211
  };
3227
3212
 
3228
3213
  // src/utils/satoshi.ts
3229
- var import_coinselect = __toESM(require("coinselect"), 1);
3230
3214
  function getNonce(url, accountId) {
3231
3215
  return __async(this, null, function* () {
3232
3216
  const { result_code, result_message, result_data } = yield request(
@@ -3343,22 +3327,6 @@ function getWhitelist(url) {
3343
3327
  return data;
3344
3328
  });
3345
3329
  }
3346
- function receiveWithdrawMsg(url, txHash) {
3347
- return __async(this, null, function* () {
3348
- const { result_code, result_message, result_data } = yield request(
3349
- `${url}/v1/receiveWithdrawMsg`,
3350
- {
3351
- method: "POST",
3352
- body: { txHash }
3353
- }
3354
- );
3355
- console.log("receiveWithdrawMsg resp:", { result_code, result_message, result_data });
3356
- if (result_code !== 0) {
3357
- throw new Error(result_message);
3358
- }
3359
- return result_data;
3360
- });
3361
- }
3362
3330
  function getAccountInfo(_0) {
3363
3331
  return __async(this, arguments, function* ({ csna, env }) {
3364
3332
  const config = getWalletConfig(env);
@@ -3684,196 +3652,10 @@ function getPredictedGasAmount(_0) {
3684
3652
  return gasAmount.toString();
3685
3653
  });
3686
3654
  }
3687
- function calculateWithdraw(_0) {
3688
- return __async(this, arguments, function* ({
3689
- amount,
3690
- feeRate,
3691
- csna,
3692
- btcAddress,
3693
- env
3694
- }) {
3695
- try {
3696
- const config = getWalletConfig(env);
3697
- const _feeRate = feeRate || (yield getBtcGasPrice());
3698
- const gasLimit = yield calculateGasLimit({
3699
- csna,
3700
- transactions: [
3701
- {
3702
- signerId: "",
3703
- receiverId: config.btcToken,
3704
- actions: [
3705
- {
3706
- type: "FunctionCall",
3707
- params: {
3708
- methodName: "ft_transfer_call",
3709
- args: {
3710
- receiver_id: config.btcToken,
3711
- amount: "100",
3712
- msg: ""
3713
- },
3714
- gas: "300000000000000",
3715
- deposit: "1"
3716
- }
3717
- }
3718
- ]
3719
- }
3720
- ],
3721
- env
3722
- });
3723
- let satoshis = Number(amount);
3724
- if (Number(gasLimit) > 0) {
3725
- satoshis = new import_big.default(amount).minus(gasLimit).toNumber();
3726
- }
3727
- const brgConfig = yield getBridgeConfig({ env });
3728
- const allUTXO = yield nearCallFunction(config.bridgeContractId, "get_utxos_paged", {}, { network: config.network });
3729
- if (brgConfig.min_withdraw_amount) {
3730
- if (Number(satoshis) < Number(brgConfig.min_withdraw_amount)) {
3731
- return {
3732
- withdrawFee: 0,
3733
- isError: true,
3734
- errorMsg: `Mini withdraw amount is ${Number(brgConfig.min_withdraw_amount) + Number(gasLimit)} sats`
3735
- };
3736
- }
3737
- }
3738
- const feePercent = Number(brgConfig.withdraw_bridge_fee.fee_rate) * Number(satoshis);
3739
- const withdrawFee = feePercent > Number(brgConfig.withdraw_bridge_fee.fee_min) ? feePercent : Number(brgConfig.withdraw_bridge_fee.fee_min);
3740
- const withdrawChangeAddress = brgConfig.change_address;
3741
- const utxos = Object.keys(allUTXO).map((key) => {
3742
- const txid = key.split("@");
3743
- return {
3744
- txid: txid[0],
3745
- vout: allUTXO[key].vout,
3746
- value: Number(allUTXO[key].balance),
3747
- script: allUTXO[key].script
3748
- };
3749
- }).filter((utxo) => utxo.value > Number(brgConfig.min_change_amount));
3750
- if (!utxos || utxos.length === 0) {
3751
- return {
3752
- withdrawFee,
3753
- isError: true,
3754
- errorMsg: "The network is busy, please try again later."
3755
- };
3756
- }
3757
- const userSatoshis = Number(satoshis);
3758
- const maxBtcFee = Number(brgConfig.max_btc_gas_fee);
3759
- const { inputs, outputs, fee } = (0, import_coinselect.default)(
3760
- utxos,
3761
- [{ address: btcAddress, value: userSatoshis }],
3762
- Math.ceil(_feeRate)
3763
- );
3764
- const newInputs = inputs;
3765
- let newOutputs = outputs;
3766
- let newFee = fee;
3767
- if (!newOutputs || newOutputs.length === 0) {
3768
- return {
3769
- withdrawFee,
3770
- isError: true,
3771
- errorMsg: "The network is busy, please try again later."
3772
- };
3773
- }
3774
- let userOutput, noUserOutput;
3775
- for (let i = 0; i < newOutputs.length; i++) {
3776
- const output = newOutputs[i];
3777
- if (output.value.toString() === userSatoshis.toString()) {
3778
- userOutput = output;
3779
- } else {
3780
- noUserOutput = output;
3781
- }
3782
- if (!output.address) {
3783
- output.address = withdrawChangeAddress;
3784
- }
3785
- }
3786
- let dis = 0;
3787
- if (newFee > maxBtcFee) {
3788
- dis = newFee - maxBtcFee;
3789
- newFee = maxBtcFee;
3790
- return {
3791
- gasFee: newFee,
3792
- withdrawFee,
3793
- isError: true,
3794
- errorMsg: "Gas exceeds maximum value"
3795
- };
3796
- }
3797
- userOutput.value = new import_big.default(userOutput.value).minus(newFee).minus(withdrawFee).toNumber();
3798
- if (userOutput.value < 0) {
3799
- return {
3800
- gasFee: newFee,
3801
- withdrawFee,
3802
- isError: true,
3803
- errorMsg: "Not enough gas"
3804
- };
3805
- }
3806
- if (noUserOutput) {
3807
- if (!noUserOutput.address) {
3808
- noUserOutput.address = withdrawChangeAddress;
3809
- }
3810
- noUserOutput.value = new import_big.default(noUserOutput.value).plus(newFee).plus(withdrawFee).plus(dis).toNumber();
3811
- } else {
3812
- noUserOutput = {
3813
- address: withdrawChangeAddress,
3814
- value: new import_big.default(newFee).plus(withdrawFee).plus(dis).toNumber()
3815
- };
3816
- newOutputs.push(noUserOutput);
3817
- }
3818
- let minValue = Math.min(...newInputs.map((input) => input.value));
3819
- let totalNoUserOutputValue = noUserOutput.value;
3820
- while (totalNoUserOutputValue >= minValue && minValue > 0 && newInputs.length > 0) {
3821
- totalNoUserOutputValue -= minValue;
3822
- noUserOutput.value = totalNoUserOutputValue;
3823
- const minValueIndex = newInputs.findIndex((input) => input.value === minValue);
3824
- if (minValueIndex > -1) {
3825
- newInputs.splice(minValueIndex, 1);
3826
- }
3827
- minValue = Math.min(...newInputs.map((input) => input.value));
3828
- }
3829
- let gasMore = 0;
3830
- if (noUserOutput.value === 0) {
3831
- newOutputs = newOutputs.filter((item) => item.value !== 0);
3832
- } else if (noUserOutput.value < Number(brgConfig.min_change_amount)) {
3833
- gasMore = Number(brgConfig.min_change_amount) - noUserOutput.value;
3834
- userOutput.value -= gasMore;
3835
- noUserOutput.value = Number(brgConfig.min_change_amount);
3836
- }
3837
- const insufficientOutput = newOutputs.some((item) => item.value < 0);
3838
- if (insufficientOutput) {
3839
- return {
3840
- gasFee: newFee,
3841
- withdrawFee,
3842
- isError: true,
3843
- errorMsg: "Not enough gas"
3844
- };
3845
- }
3846
- const inputSum = newInputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3847
- const outputSum = newOutputs.reduce((sum, cur) => sum + Number(cur.value), 0);
3848
- if (newFee + outputSum !== inputSum) {
3849
- return {
3850
- withdrawFee,
3851
- isError: true,
3852
- errorMsg: "Service busy, please try again later"
3853
- };
3854
- }
3855
- return {
3856
- withdrawFee: new import_big.default(withdrawFee).plus(gasLimit).plus(gasMore).toNumber(),
3857
- gasFee: new import_big.default(newFee).toNumber(),
3858
- inputs: newInputs,
3859
- outputs: newOutputs,
3860
- fromAmount: satoshis,
3861
- receiveAmount: userOutput.value,
3862
- isError: false
3863
- };
3864
- } catch (error) {
3865
- return {
3866
- withdrawFee: 0,
3867
- isError: true,
3868
- errorMsg: error.message
3869
- };
3870
- }
3871
- });
3872
- }
3873
3655
 
3874
3656
  // src/core/btcUtils.ts
3875
3657
  var bitcoin = __toESM(require("bitcoinjs-lib"), 1);
3876
- var import_coinselect2 = __toESM(require("coinselect"), 1);
3658
+ var import_coinselect = __toESM(require("coinselect"), 1);
3877
3659
  var ecc = __toESM(require("@bitcoinerlab/secp256k1"), 1);
3878
3660
  bitcoin.initEccLib(ecc);
3879
3661
  var NEAR_STORAGE_DEPOSIT_AMOUNT = "1250000000000000000000";
@@ -3969,7 +3751,7 @@ function calculateGasFee(account, amount, feeRate) {
3969
3751
  return __async(this, null, function* () {
3970
3752
  const _feeRate = feeRate || (yield getBtcGasPrice());
3971
3753
  const utxos = yield getBtcUtxos(account);
3972
- 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));
3973
3755
  console.log("calculateGasFee fee:", fee);
3974
3756
  return fee;
3975
3757
  });
@@ -4309,6 +4091,201 @@ function getWithdrawTransaction(_0) {
4309
4091
  return transaction;
4310
4092
  });
4311
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
+ }
4312
4289
  function uint8ArrayToHex(uint8Array) {
4313
4290
  return Array.from(uint8Array).map((byte) => byte.toString(16).padStart(2, "0")).join("");
4314
4291
  }
@@ -4948,7 +4925,7 @@ function getGroup(state) {
4948
4925
 
4949
4926
  // src/index.ts
4950
4927
  var getVersion = () => {
4951
- return "0.5.43-beta";
4928
+ return "0.5.44-beta";
4952
4929
  };
4953
4930
  if (typeof window !== "undefined") {
4954
4931
  window.__BTC_WALLET_VERSION = getVersion();