@atomicfinance/bitcoin-node-wallet-provider 3.5.0 → 3.5.2

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.
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const bitcoin_utils_1 = require("@atomicfinance/bitcoin-utils");
7
+ const crypto_1 = require("@atomicfinance/crypto");
8
+ const jsonrpc_provider_1 = require("@atomicfinance/jsonrpc-provider");
9
+ const provider_1 = __importDefault(require("@atomicfinance/provider"));
10
+ const types_1 = require("@atomicfinance/types");
11
+ const bitcoin_networks_1 = require("bitcoin-networks");
12
+ const bitcoinjs_lib_1 = require("bitcoinjs-lib");
13
+ const lodash_1 = require("lodash");
14
+ const BIP70_CHAIN_TO_NETWORK = {
15
+ main: bitcoin_networks_1.BitcoinNetworks.bitcoin,
16
+ test: bitcoin_networks_1.BitcoinNetworks.bitcoin_testnet,
17
+ regtest: bitcoin_networks_1.BitcoinNetworks.bitcoin_regtest,
18
+ };
19
+ class BitcoinNodeWalletProvider extends provider_1.default {
20
+ constructor(opts) {
21
+ super();
22
+ const { uri, username, password, network, addressType = types_1.bitcoin.AddressType.BECH32, } = opts;
23
+ const addressTypes = Object.values(types_1.bitcoin.AddressType);
24
+ if (!addressTypes.includes(addressType)) {
25
+ throw new Error(`addressType must be one of ${addressTypes.join(',')}`);
26
+ }
27
+ this._addressType = addressType;
28
+ this._network = network;
29
+ this._rpc = new jsonrpc_provider_1.JsonRpcProvider(uri, username, password);
30
+ this._addressInfoCache = {};
31
+ }
32
+ async signMessage(message, from) {
33
+ return this._rpc
34
+ .jsonrpc('signmessage', from, message)
35
+ .then((result) => Buffer.from(result, 'base64').toString('hex'));
36
+ }
37
+ async withTxFee(func, feePerByte) {
38
+ const feePerKB = new types_1.BigNumber(feePerByte).div(1e8).times(1000).toNumber();
39
+ const originalTxFee = (await this._rpc.jsonrpc('getwalletinfo'))
40
+ .paytxfee;
41
+ await this._rpc.jsonrpc('settxfee', feePerKB);
42
+ const result = await func();
43
+ await this._rpc.jsonrpc('settxfee', originalTxFee);
44
+ return result;
45
+ }
46
+ async _sendTransaction(options) {
47
+ const value = new types_1.BigNumber(options.value).dividedBy(1e8).toNumber();
48
+ const hash = await this._rpc.jsonrpc('sendtoaddress', options.to, value, '', '', false, true);
49
+ const transaction = await this._rpc.jsonrpc('gettransaction', hash, true);
50
+ const fee = new types_1.BigNumber(transaction.fee).abs().times(1e8).toNumber();
51
+ return (0, bitcoin_utils_1.normalizeTransactionObject)((0, bitcoin_utils_1.decodeRawTransaction)(transaction.hex, this._network), fee);
52
+ }
53
+ async sendTransaction(options) {
54
+ return options.fee
55
+ ? this.withTxFee(async () => this._sendTransaction(options), options.fee)
56
+ : this._sendTransaction(options);
57
+ }
58
+ async updateTransactionFee(tx, newFeePerByte) {
59
+ const txHash = (0, lodash_1.isString)(tx) ? tx : tx.hash;
60
+ return this.withTxFee(async () => {
61
+ const result = await this._rpc.jsonrpc('bumpfee', txHash);
62
+ const transaction = await this._rpc.jsonrpc('gettransaction', result.txid, true);
63
+ const fee = new types_1.BigNumber(transaction.fee).abs().times(1e8).toNumber();
64
+ return (0, bitcoin_utils_1.normalizeTransactionObject)((0, bitcoin_utils_1.decodeRawTransaction)(transaction.hex, this._network), fee);
65
+ }, newFeePerByte);
66
+ }
67
+ async signPSBT(data, inputs) {
68
+ const psbt = bitcoinjs_lib_1.Psbt.fromBase64(data, { network: this._network });
69
+ for (const input of inputs) {
70
+ const usedAddresses = await this.getUsedAddresses();
71
+ const address = usedAddresses.find((address) => address.derivationPath === input.derivationPath);
72
+ const wif = await this.dumpPrivKey(address.address);
73
+ const keyPair = bitcoinjs_lib_1.ECPair.fromWIF(wif, this._network);
74
+ psbt.signInput(input.index, keyPair);
75
+ }
76
+ return psbt.toBase64();
77
+ }
78
+ async signBatchP2SHTransaction(inputs, addresses, tx, locktime, segwit = false) {
79
+ const wallets = [];
80
+ for (const address of addresses) {
81
+ const wif = await this.dumpPrivKey(address);
82
+ const wallet = bitcoinjs_lib_1.ECPair.fromWIF(wif, this._network);
83
+ wallets.push(wallet);
84
+ }
85
+ const sigs = [];
86
+ for (let i = 0; i < inputs.length; i++) {
87
+ let sigHash;
88
+ if (segwit) {
89
+ sigHash = tx.hashForWitnessV0(inputs[i].index, inputs[i].outputScript, inputs[i].vout.vSat, bitcoinjs_lib_1.Transaction.SIGHASH_ALL); // AMOUNT NEEDS TO BE PREVOUT AMOUNT
90
+ }
91
+ else {
92
+ sigHash = tx.hashForSignature(inputs[i].index, inputs[i].outputScript, bitcoinjs_lib_1.Transaction.SIGHASH_ALL);
93
+ }
94
+ const sig = bitcoinjs_lib_1.script.signature.encode(wallets[i].sign(sigHash), bitcoinjs_lib_1.Transaction.SIGHASH_ALL);
95
+ sigs.push(sig);
96
+ }
97
+ return sigs;
98
+ }
99
+ async dumpPrivKey(address) {
100
+ return this._rpc.jsonrpc('dumpprivkey', address);
101
+ }
102
+ async getNewAddress(addressType, label = '') {
103
+ const params = addressType ? [label, addressType] : [label];
104
+ const newAddress = await this._rpc.jsonrpc('getnewaddress', ...params);
105
+ if (!newAddress)
106
+ return null;
107
+ return this.getAddressInfo(newAddress);
108
+ }
109
+ async getAddressInfo(address) {
110
+ if (address in this._addressInfoCache) {
111
+ return this._addressInfoCache[address];
112
+ }
113
+ const addressInfo = await this._rpc.jsonrpc('getaddressinfo', address);
114
+ let publicKey, derivationPath;
115
+ if (!addressInfo.iswatchonly) {
116
+ publicKey = addressInfo.pubkey;
117
+ derivationPath = addressInfo.hdkeypath;
118
+ }
119
+ const addressObject = new types_1.Address({ address, publicKey, derivationPath });
120
+ this._addressInfoCache[address] = addressObject;
121
+ return addressObject;
122
+ }
123
+ async getAddresses() {
124
+ return this.getUsedAddresses();
125
+ }
126
+ async getUnusedAddress() {
127
+ return this.getNewAddress(this._addressType);
128
+ }
129
+ async getUsedAddresses() {
130
+ const usedAddresses = await this._rpc.jsonrpc('listaddressgroupings');
131
+ const emptyAddresses = await this._rpc.jsonrpc('listreceivedbyaddress', 0, true, false);
132
+ const addrs = (0, lodash_1.uniq)([
133
+ ...(0, lodash_1.flatten)(usedAddresses).map((addr) => addr[0]),
134
+ ...emptyAddresses.map((a) => a.address),
135
+ ]);
136
+ const addressObjects = await Promise.all(addrs.map((address) => this.getAddressInfo(address)));
137
+ return addressObjects;
138
+ }
139
+ async getWalletAddress(address) {
140
+ return this.getAddressInfo(address);
141
+ }
142
+ async isWalletAvailable() {
143
+ try {
144
+ await this._rpc.jsonrpc('getwalletinfo');
145
+ return true;
146
+ }
147
+ catch (e) {
148
+ return false;
149
+ }
150
+ }
151
+ async getConnectedNetwork() {
152
+ const blockchainInfo = await this._rpc.jsonrpc('getblockchaininfo');
153
+ const chain = blockchainInfo.chain;
154
+ return BIP70_CHAIN_TO_NETWORK[chain];
155
+ }
156
+ async generateSecret(message) {
157
+ const secretAddressLabel = 'secretAddress';
158
+ let address;
159
+ try {
160
+ const labelAddresses = await this._rpc.jsonrpc('getaddressesbylabel', secretAddressLabel);
161
+ address = Object.keys(labelAddresses)[0];
162
+ }
163
+ catch (e) {
164
+ // Label does not exist
165
+ address = (await this.getNewAddress(types_1.bitcoin.AddressType.LEGACY, secretAddressLabel)).address; // Signing only possible with legacy addresses
166
+ }
167
+ const signedMessage = await this.signMessage(message, address);
168
+ const secret = (0, crypto_1.sha256)(signedMessage);
169
+ return secret;
170
+ }
171
+ }
172
+ exports.default = BitcoinNodeWalletProvider;
173
+ //# sourceMappingURL=BitcoinNodeWalletProvider.js.map
package/lib/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BitcoinNodeWalletProvider = void 0;
7
+ const BitcoinNodeWalletProvider_1 = __importDefault(require("./BitcoinNodeWalletProvider"));
8
+ exports.BitcoinNodeWalletProvider = BitcoinNodeWalletProvider_1.default;
9
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomicfinance/bitcoin-node-wallet-provider",
3
- "version": "3.5.0",
3
+ "version": "3.5.2",
4
4
  "description": "",
5
5
  "module": "dist/index.js",
6
6
  "main": "dist/index.js",
@@ -25,11 +25,11 @@
25
25
  "node": ">=14"
26
26
  },
27
27
  "dependencies": {
28
- "@atomicfinance/bitcoin-utils": "^3.5.0",
29
- "@atomicfinance/crypto": "^3.5.0",
30
- "@atomicfinance/jsonrpc-provider": "^3.5.0",
31
- "@atomicfinance/types": "^3.5.0",
32
- "@atomicfinance/utils": "^3.5.0",
28
+ "@atomicfinance/bitcoin-utils": "^3.5.2",
29
+ "@atomicfinance/crypto": "^3.5.2",
30
+ "@atomicfinance/jsonrpc-provider": "^3.5.2",
31
+ "@atomicfinance/types": "^3.5.2",
32
+ "@atomicfinance/utils": "^3.5.2",
33
33
  "@babel/runtime": "^7.12.1",
34
34
  "bignumber.js": "^9.0.0",
35
35
  "bitcoin-networks": "^1.0.0",