@airgap/bitcoin 0.13.45-beta.1 → 0.13.45-beta.3

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.
Files changed (73) hide show
  1. package/package.json +5 -5
  2. package/v0/index.js +10 -10
  3. package/v0/index.js.map +1 -1
  4. package/v0/protocol/BitcoinAddress.js +8 -9
  5. package/v0/protocol/BitcoinAddress.js.map +1 -1
  6. package/v0/protocol/BitcoinCryptoClient.js +16 -85
  7. package/v0/protocol/BitcoinCryptoClient.js.map +1 -1
  8. package/v0/protocol/BitcoinProtocol.js +590 -987
  9. package/v0/protocol/BitcoinProtocol.js.map +1 -1
  10. package/v0/protocol/BitcoinProtocolOptions.js +45 -111
  11. package/v0/protocol/BitcoinProtocolOptions.js.map +1 -1
  12. package/v0/protocol/BitcoinSegwitAddress.js +12 -29
  13. package/v0/protocol/BitcoinSegwitAddress.js.map +1 -1
  14. package/v0/protocol/BitcoinSegwitProtocol.js +348 -483
  15. package/v0/protocol/BitcoinSegwitProtocol.js.map +1 -1
  16. package/v0/protocol/BitcoinTestnetProtocol.js +28 -36
  17. package/v0/protocol/BitcoinTestnetProtocol.js.map +1 -1
  18. package/v0/serializer/validators/transaction-validator.js +22 -30
  19. package/v0/serializer/validators/transaction-validator.js.map +1 -1
  20. package/v0/serializer/validators/validators.js +23 -23
  21. package/v0/serializer/validators/validators.js.map +1 -1
  22. package/v1/block-explorer/BlockCypherBlockExplorer.js +12 -61
  23. package/v1/block-explorer/BlockCypherBlockExplorer.js.map +1 -1
  24. package/v1/data/BitcoinAddress.js +9 -10
  25. package/v1/data/BitcoinAddress.js.map +1 -1
  26. package/v1/data/BitcoinLegacyAddress.js +11 -12
  27. package/v1/data/BitcoinLegacyAddress.js.map +1 -1
  28. package/v1/data/BitcoinSegwitAddress.js +11 -12
  29. package/v1/data/BitcoinSegwitAddress.js.map +1 -1
  30. package/v1/data/BitcoinTaprootAddress.js +31 -22
  31. package/v1/data/BitcoinTaprootAddress.js.map +1 -1
  32. package/v1/index.js +11 -11
  33. package/v1/index.js.map +1 -1
  34. package/v1/module/BitcoinModule.d.ts +1 -1
  35. package/v1/module/BitcoinModule.js +44 -102
  36. package/v1/module/BitcoinModule.js.map +1 -1
  37. package/v1/module.js +2 -3
  38. package/v1/module.js.map +1 -1
  39. package/v1/protocol/BitcoinCryptoClient.js +22 -90
  40. package/v1/protocol/BitcoinCryptoClient.js.map +1 -1
  41. package/v1/protocol/BitcoinLegacyProtocol.js +520 -796
  42. package/v1/protocol/BitcoinLegacyProtocol.js.map +1 -1
  43. package/v1/protocol/BitcoinProtocol.js +735 -1169
  44. package/v1/protocol/BitcoinProtocol.js.map +1 -1
  45. package/v1/protocol/BitcoinSegwitProtocol.js +542 -796
  46. package/v1/protocol/BitcoinSegwitProtocol.js.map +1 -1
  47. package/v1/protocol/BitcoinTaprootProtocol.js +688 -1000
  48. package/v1/protocol/BitcoinTaprootProtocol.js.map +1 -1
  49. package/v1/protocol/BitcoinTestnetProtocol.js +14 -33
  50. package/v1/protocol/BitcoinTestnetProtocol.js.map +1 -1
  51. package/v1/serializer/v3/schemas/converter/transaction-converter.js +29 -52
  52. package/v1/serializer/v3/schemas/converter/transaction-converter.js.map +1 -1
  53. package/v1/serializer/v3/serializer-companion.js +98 -165
  54. package/v1/serializer/v3/serializer-companion.js.map +1 -1
  55. package/v1/serializer/v3/validators/transaction-validator.js +13 -16
  56. package/v1/serializer/v3/validators/transaction-validator.js.map +1 -1
  57. package/v1/serializer/v3/validators/validators.js +122 -213
  58. package/v1/serializer/v3/validators/validators.js.map +1 -1
  59. package/v1/types/crypto.d.ts +1 -1
  60. package/v1/types/key.d.ts +6 -6
  61. package/v1/types/protocol.d.ts +2 -2
  62. package/v1/types/transaction.d.ts +3 -3
  63. package/v1/utils/common.js +4 -6
  64. package/v1/utils/common.js.map +1 -1
  65. package/v1/utils/key.d.ts +5 -6
  66. package/v1/utils/key.js +38 -39
  67. package/v1/utils/key.js.map +1 -1
  68. package/v1/utils/network.js +3 -4
  69. package/v1/utils/network.js.map +1 -1
  70. package/v1/utils/protocol.js +25 -19
  71. package/v1/utils/protocol.js.map +1 -1
  72. package/v1/utils/signature.js +4 -5
  73. package/v1/utils/signature.js.map +1 -1
@@ -15,77 +15,41 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- var __generator = (this && this.__generator) || function (thisArg, body) {
35
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
36
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
- function verb(n) { return function (v) { return step([n, v]); }; }
38
- function step(op) {
39
- if (f) throw new TypeError("Generator is already executing.");
40
- while (_) try {
41
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
42
- if (y = 0, t) op = [op[0] & 2, t.value];
43
- switch (op[0]) {
44
- case 0: case 1: t = op; break;
45
- case 4: _.label++; return { value: op[1], done: false };
46
- case 5: _.label++; y = op[1]; op = [0]; continue;
47
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
- default:
49
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
- if (t[2]) _.ops.pop();
54
- _.trys.pop(); continue;
55
- }
56
- op = body.call(thisArg, _);
57
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
- }
60
- };
61
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
62
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
63
- if (ar || !(i in from)) {
64
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
65
- ar[i] = from[i];
66
- }
67
- }
68
- return to.concat(ar || Array.prototype.slice.call(from));
69
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
70
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
71
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
72
37
  };
73
38
  Object.defineProperty(exports, "__esModule", { value: true });
74
39
  exports.BitcoinProtocol = void 0;
75
- var index_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/axios-0.19.0/index"));
76
- var bignumber_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
77
- var index_2 = require("@airgap/coinlib-core/dependencies/src/bip39-2.5.0/index");
78
- var bitcoinJSMessage = __importStar(require("@airgap/coinlib-core/dependencies/src/bitcoinjs-message-2.1.1/index"));
79
- var errors_1 = require("@airgap/coinlib-core/errors");
80
- var coinlib_error_1 = require("@airgap/coinlib-core/errors/coinlib-error");
81
- var ProtocolSymbols_1 = require("@airgap/coinlib-core/utils/ProtocolSymbols");
82
- var BitcoinAddress_1 = require("./BitcoinAddress");
83
- var BitcoinCryptoClient_1 = require("./BitcoinCryptoClient");
84
- var BitcoinProtocolOptions_1 = require("./BitcoinProtocolOptions");
85
- var DUST_AMOUNT = 50;
86
- var BitcoinProtocol = /** @class */ (function () {
87
- function BitcoinProtocol(options) {
88
- if (options === void 0) { options = new BitcoinProtocolOptions_1.BitcoinProtocolOptions(); }
40
+ const index_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/axios-0.19.0/index"));
41
+ const bignumber_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
42
+ const index_2 = require("@airgap/coinlib-core/dependencies/src/bip39-2.5.0/index");
43
+ const bitcoinJSMessage = __importStar(require("@airgap/coinlib-core/dependencies/src/bitcoinjs-message-2.1.1/index"));
44
+ const errors_1 = require("@airgap/coinlib-core/errors");
45
+ const coinlib_error_1 = require("@airgap/coinlib-core/errors/coinlib-error");
46
+ const ProtocolSymbols_1 = require("@airgap/coinlib-core/utils/ProtocolSymbols");
47
+ const BitcoinAddress_1 = require("./BitcoinAddress");
48
+ const BitcoinCryptoClient_1 = require("./BitcoinCryptoClient");
49
+ const BitcoinProtocolOptions_1 = require("./BitcoinProtocolOptions");
50
+ const DUST_AMOUNT = 50;
51
+ class BitcoinProtocol {
52
+ constructor(options = new BitcoinProtocolOptions_1.BitcoinProtocolOptions()) {
89
53
  this.options = options;
90
54
  this.symbol = 'BTC';
91
55
  this.name = 'Bitcoin (Legacy)';
@@ -114,957 +78,596 @@ var BitcoinProtocol = /** @class */ (function () {
114
78
  }
115
79
  ];
116
80
  this.supportsHD = true;
117
- this.standardDerivationPath = "m/44'/0'/0'";
81
+ this.standardDerivationPath = `m/44'/0'/0'`;
118
82
  this.addressIsCaseSensitive = true;
119
83
  this.addressValidationPattern = '^(?:[13]{1}[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$';
120
84
  this.addressPlaceholder = '1ABC...';
121
85
  this.cryptoClient = new BitcoinCryptoClient_1.BitcoinCryptoClient(this, bitcoinJSMessage);
122
86
  }
123
- BitcoinProtocol.prototype.getSymbol = function () {
124
- return __awaiter(this, void 0, void 0, function () {
125
- return __generator(this, function (_a) {
126
- return [2 /*return*/, this.symbol];
127
- });
128
- });
129
- };
130
- BitcoinProtocol.prototype.getName = function () {
131
- return __awaiter(this, void 0, void 0, function () {
132
- return __generator(this, function (_a) {
133
- return [2 /*return*/, this.name];
134
- });
135
- });
136
- };
137
- BitcoinProtocol.prototype.getMarketSymbol = function () {
138
- return __awaiter(this, void 0, void 0, function () {
139
- return __generator(this, function (_a) {
140
- return [2 /*return*/, this.marketSymbol];
141
- });
142
- });
143
- };
144
- BitcoinProtocol.prototype.getAssetSymbol = function () {
145
- return __awaiter(this, void 0, void 0, function () {
146
- return __generator(this, function (_a) {
147
- return [2 /*return*/, undefined];
148
- });
149
- });
150
- };
151
- BitcoinProtocol.prototype.getFeeSymbol = function () {
152
- return __awaiter(this, void 0, void 0, function () {
153
- return __generator(this, function (_a) {
154
- return [2 /*return*/, this.feeSymbol];
155
- });
156
- });
157
- };
158
- BitcoinProtocol.prototype.getFeeDefaults = function () {
159
- return __awaiter(this, void 0, void 0, function () {
160
- return __generator(this, function (_a) {
161
- return [2 /*return*/, this.feeDefaults];
162
- });
163
- });
164
- };
165
- BitcoinProtocol.prototype.getDecimals = function () {
166
- return __awaiter(this, void 0, void 0, function () {
167
- return __generator(this, function (_a) {
168
- return [2 /*return*/, this.decimals];
169
- });
170
- });
171
- };
172
- BitcoinProtocol.prototype.getFeeDecimals = function () {
173
- return __awaiter(this, void 0, void 0, function () {
174
- return __generator(this, function (_a) {
175
- return [2 /*return*/, this.feeDecimals];
176
- });
177
- });
178
- };
179
- BitcoinProtocol.prototype.getIdentifier = function () {
180
- return __awaiter(this, void 0, void 0, function () {
181
- return __generator(this, function (_a) {
182
- return [2 /*return*/, this.identifier];
183
- });
184
- });
185
- };
186
- BitcoinProtocol.prototype.getUnits = function () {
187
- return __awaiter(this, void 0, void 0, function () {
188
- return __generator(this, function (_a) {
189
- return [2 /*return*/, this.units];
190
- });
191
- });
192
- };
193
- BitcoinProtocol.prototype.getSupportsHD = function () {
194
- return __awaiter(this, void 0, void 0, function () {
195
- return __generator(this, function (_a) {
196
- return [2 /*return*/, this.supportsHD];
197
- });
198
- });
199
- };
200
- BitcoinProtocol.prototype.getStandardDerivationPath = function () {
201
- return __awaiter(this, void 0, void 0, function () {
202
- return __generator(this, function (_a) {
203
- return [2 /*return*/, this.standardDerivationPath];
204
- });
205
- });
206
- };
207
- BitcoinProtocol.prototype.getAddressIsCaseSensitive = function () {
208
- return __awaiter(this, void 0, void 0, function () {
209
- return __generator(this, function (_a) {
210
- return [2 /*return*/, this.addressIsCaseSensitive];
211
- });
212
- });
213
- };
214
- BitcoinProtocol.prototype.getAddressValidationPattern = function () {
215
- return __awaiter(this, void 0, void 0, function () {
216
- return __generator(this, function (_a) {
217
- return [2 /*return*/, this.addressValidationPattern];
218
- });
219
- });
220
- };
221
- BitcoinProtocol.prototype.getAddressPlaceholder = function () {
222
- return __awaiter(this, void 0, void 0, function () {
223
- return __generator(this, function (_a) {
224
- return [2 /*return*/, this.addressPlaceholder];
225
- });
226
- });
227
- };
228
- BitcoinProtocol.prototype.getOptions = function () {
229
- return __awaiter(this, void 0, void 0, function () {
230
- return __generator(this, function (_a) {
231
- return [2 /*return*/, this.options];
232
- });
233
- });
234
- };
235
- BitcoinProtocol.prototype.getBlockExplorerLinkForAddress = function (address) {
236
- return __awaiter(this, void 0, void 0, function () {
237
- return __generator(this, function (_a) {
238
- return [2 /*return*/, this.options.network.blockExplorer.getAddressLink(address)];
239
- });
240
- });
241
- };
242
- BitcoinProtocol.prototype.getBlockExplorerLinkForTxId = function (txId) {
243
- return __awaiter(this, void 0, void 0, function () {
244
- return __generator(this, function (_a) {
245
- return [2 /*return*/, this.options.network.blockExplorer.getTransactionLink(txId)];
246
- });
247
- });
248
- };
249
- BitcoinProtocol.prototype.getPublicKeyFromMnemonic = function (mnemonic, derivationPath, password) {
250
- return __awaiter(this, void 0, void 0, function () {
251
- var secret;
252
- return __generator(this, function (_a) {
253
- secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
254
- return [2 /*return*/, this.getPublicKeyFromHexSecret(secret, derivationPath)];
255
- });
256
- });
257
- };
258
- BitcoinProtocol.prototype.getPrivateKeyFromMnemonic = function (mnemonic, derivationPath, password) {
259
- return __awaiter(this, void 0, void 0, function () {
260
- var secret;
261
- return __generator(this, function (_a) {
262
- secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
263
- return [2 /*return*/, this.getPrivateKeyFromHexSecret(secret, derivationPath)];
264
- });
265
- });
266
- };
267
- BitcoinProtocol.prototype.getExtendedPublicKeyFromMnemonic = function (mnemonic, derivationPath, password) {
268
- return __awaiter(this, void 0, void 0, function () {
269
- var secret;
270
- return __generator(this, function (_a) {
271
- secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
272
- return [2 /*return*/, this.getExtendedPublicKeyFromHexSecret(secret, derivationPath)];
273
- });
274
- });
275
- };
276
- BitcoinProtocol.prototype.getExtendedPrivateKeyFromMnemonic = function (mnemonic, derivationPath, password) {
277
- return __awaiter(this, void 0, void 0, function () {
278
- var secret;
279
- return __generator(this, function (_a) {
280
- secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
281
- return [2 /*return*/, this.getExtendedPrivateKeyFromHexSecret(secret, derivationPath)];
282
- });
283
- });
284
- };
285
- BitcoinProtocol.prototype.getPublicKeyFromHexSecret = function (secret, derivationPath) {
286
- return __awaiter(this, void 0, void 0, function () {
287
- var bitcoinNode;
288
- return __generator(this, function (_a) {
289
- bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
290
- return [2 /*return*/, bitcoinNode.derivePath(derivationPath).neutered().toBase58()];
291
- });
292
- });
293
- };
294
- BitcoinProtocol.prototype.getPrivateKeyFromHexSecret = function (secret, derivationPath) {
295
- return __awaiter(this, void 0, void 0, function () {
296
- var bitcoinNode;
297
- return __generator(this, function (_a) {
298
- bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
299
- return [2 /*return*/, bitcoinNode.derivePath(derivationPath).keyPair.d.toBuffer(32).toString('hex')];
300
- });
301
- });
302
- };
303
- BitcoinProtocol.prototype.getExtendedPublicKeyFromHexSecret = function (secret, derivationPath) {
304
- return __awaiter(this, void 0, void 0, function () {
305
- return __generator(this, function (_a) {
306
- return [2 /*return*/, this.getPublicKeyFromHexSecret(secret, derivationPath)];
307
- });
308
- });
309
- };
310
- BitcoinProtocol.prototype.getExtendedPrivateKeyFromHexSecret = function (secret, derivationPath) {
311
- return __awaiter(this, void 0, void 0, function () {
312
- var bitcoinNode;
313
- return __generator(this, function (_a) {
314
- bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
315
- return [2 /*return*/, bitcoinNode.derivePath(derivationPath).toBase58()];
316
- });
317
- });
318
- };
319
- BitcoinProtocol.prototype.getAddressFromPublicKey = function (publicKey, cursor) {
320
- return __awaiter(this, void 0, void 0, function () {
321
- var node, address;
322
- return __generator(this, function (_a) {
323
- node = this.options.config.bitcoinJSLib.HDNode.fromBase58(publicKey, this.options.network.extras.network);
324
- address = BitcoinAddress_1.BitcoinAddress.from(node);
325
- return [2 /*return*/, {
326
- address: address.asString(),
327
- cursor: { hasNext: false }
328
- }];
329
- });
330
- });
331
- };
332
- BitcoinProtocol.prototype.getAddressesFromPublicKey = function (publicKey, cursor) {
333
- return __awaiter(this, void 0, void 0, function () {
334
- return __generator(this, function (_a) {
335
- switch (_a.label) {
336
- case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey, cursor)];
337
- case 1: return [2 /*return*/, [_a.sent()]];
87
+ async getSymbol() {
88
+ return this.symbol;
89
+ }
90
+ async getName() {
91
+ return this.name;
92
+ }
93
+ async getMarketSymbol() {
94
+ return this.marketSymbol;
95
+ }
96
+ async getAssetSymbol() {
97
+ return undefined;
98
+ }
99
+ async getFeeSymbol() {
100
+ return this.feeSymbol;
101
+ }
102
+ async getFeeDefaults() {
103
+ return this.feeDefaults;
104
+ }
105
+ async getDecimals() {
106
+ return this.decimals;
107
+ }
108
+ async getFeeDecimals() {
109
+ return this.feeDecimals;
110
+ }
111
+ async getIdentifier() {
112
+ return this.identifier;
113
+ }
114
+ async getUnits() {
115
+ return this.units;
116
+ }
117
+ async getSupportsHD() {
118
+ return this.supportsHD;
119
+ }
120
+ async getStandardDerivationPath() {
121
+ return this.standardDerivationPath;
122
+ }
123
+ async getAddressIsCaseSensitive() {
124
+ return this.addressIsCaseSensitive;
125
+ }
126
+ async getAddressValidationPattern() {
127
+ return this.addressValidationPattern;
128
+ }
129
+ async getAddressPlaceholder() {
130
+ return this.addressPlaceholder;
131
+ }
132
+ async getOptions() {
133
+ return this.options;
134
+ }
135
+ async getBlockExplorerLinkForAddress(address) {
136
+ return this.options.network.blockExplorer.getAddressLink(address);
137
+ }
138
+ async getBlockExplorerLinkForTxId(txId) {
139
+ return this.options.network.blockExplorer.getTransactionLink(txId);
140
+ }
141
+ async getPublicKeyFromMnemonic(mnemonic, derivationPath, password) {
142
+ const secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
143
+ return this.getPublicKeyFromHexSecret(secret, derivationPath);
144
+ }
145
+ async getPrivateKeyFromMnemonic(mnemonic, derivationPath, password) {
146
+ const secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
147
+ return this.getPrivateKeyFromHexSecret(secret, derivationPath);
148
+ }
149
+ async getExtendedPublicKeyFromMnemonic(mnemonic, derivationPath, password) {
150
+ const secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
151
+ return this.getExtendedPublicKeyFromHexSecret(secret, derivationPath);
152
+ }
153
+ async getExtendedPrivateKeyFromMnemonic(mnemonic, derivationPath, password) {
154
+ const secret = (0, index_2.mnemonicToSeed)(mnemonic, password);
155
+ return this.getExtendedPrivateKeyFromHexSecret(secret, derivationPath);
156
+ }
157
+ async getPublicKeyFromHexSecret(secret, derivationPath) {
158
+ const bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
159
+ return bitcoinNode.derivePath(derivationPath).neutered().toBase58();
160
+ }
161
+ async getPrivateKeyFromHexSecret(secret, derivationPath) {
162
+ const bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
163
+ return bitcoinNode.derivePath(derivationPath).keyPair.d.toBuffer(32).toString('hex');
164
+ }
165
+ async getExtendedPublicKeyFromHexSecret(secret, derivationPath) {
166
+ return this.getPublicKeyFromHexSecret(secret, derivationPath);
167
+ }
168
+ async getExtendedPrivateKeyFromHexSecret(secret, derivationPath) {
169
+ const bitcoinNode = this.options.config.bitcoinJSLib.HDNode.fromSeedHex(secret, this.options.network.extras.network);
170
+ return bitcoinNode.derivePath(derivationPath).toBase58();
171
+ }
172
+ async getAddressFromPublicKey(publicKey, cursor) {
173
+ // broadcaster knows this (both broadcaster and signer)
174
+ const node = this.options.config.bitcoinJSLib.HDNode.fromBase58(publicKey, this.options.network.extras.network);
175
+ const address = BitcoinAddress_1.BitcoinAddress.from(node);
176
+ return {
177
+ address: address.asString(),
178
+ cursor: { hasNext: false }
179
+ };
180
+ }
181
+ async getAddressesFromPublicKey(publicKey, cursor) {
182
+ return [await this.getAddressFromPublicKey(publicKey, cursor)];
183
+ }
184
+ async getAddressFromExtendedPublicKey(extendedPublicKey, visibilityDerivationIndex, addressDerivationIndex) {
185
+ // broadcaster knows this (both broadcaster and signer)
186
+ const node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPublicKey, this.options.network.extras.network);
187
+ const address = BitcoinAddress_1.BitcoinAddress.from(node, visibilityDerivationIndex, addressDerivationIndex);
188
+ return {
189
+ address: address.asString(),
190
+ cursor: { hasNext: false }
191
+ };
192
+ }
193
+ async getAddressesFromExtendedPublicKey(extendedPublicKey, visibilityDerivationIndex, addressCount, offset) {
194
+ // broadcaster knows this (both broadcaster and signer)
195
+ const node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPublicKey, this.options.network.extras.network);
196
+ const generatorArray = Array.from(new Array(addressCount), (_, i) => i + offset);
197
+ return Promise.all(generatorArray.map((x) => {
198
+ const address = BitcoinAddress_1.BitcoinAddress.from(node, visibilityDerivationIndex, x);
199
+ return {
200
+ address: address.asString(),
201
+ cursor: { hasNext: false }
202
+ };
203
+ }));
204
+ }
205
+ async signWithPrivateKey(privateKey, transaction) {
206
+ const transactionBuilder = new this.options.config.bitcoinJSLib.TransactionBuilder(this.options.network.extras.network);
207
+ for (const input of transaction.ins) {
208
+ transactionBuilder.addInput(input.txId, input.vout);
209
+ }
210
+ for (const output of transaction.outs) {
211
+ if (output.isChange) {
212
+ // 1. `getAddressFromPublicKey` expects a base58 encoded key
213
+ const generatedChangeAddress = (await this.getAddressFromPublicKey(privateKey)).address;
214
+ if (generatedChangeAddress !== output.recipient) {
215
+ throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Change address could not be verified.');
338
216
  }
339
- });
340
- });
341
- };
342
- BitcoinProtocol.prototype.getAddressFromExtendedPublicKey = function (extendedPublicKey, visibilityDerivationIndex, addressDerivationIndex) {
343
- return __awaiter(this, void 0, void 0, function () {
344
- var node, address;
345
- return __generator(this, function (_a) {
346
- node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPublicKey, this.options.network.extras.network);
347
- address = BitcoinAddress_1.BitcoinAddress.from(node, visibilityDerivationIndex, addressDerivationIndex);
348
- return [2 /*return*/, {
349
- address: address.asString(),
350
- cursor: { hasNext: false }
351
- }];
352
- });
353
- });
354
- };
355
- BitcoinProtocol.prototype.getAddressesFromExtendedPublicKey = function (extendedPublicKey, visibilityDerivationIndex, addressCount, offset) {
356
- return __awaiter(this, void 0, void 0, function () {
357
- var node, generatorArray;
358
- return __generator(this, function (_a) {
359
- node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPublicKey, this.options.network.extras.network);
360
- generatorArray = Array.from(new Array(addressCount), function (_, i) { return i + offset; });
361
- return [2 /*return*/, Promise.all(generatorArray.map(function (x) {
362
- var address = BitcoinAddress_1.BitcoinAddress.from(node, visibilityDerivationIndex, x);
363
- return {
364
- address: address.asString(),
365
- cursor: { hasNext: false }
366
- };
367
- }))];
368
- });
369
- });
370
- };
371
- BitcoinProtocol.prototype.signWithPrivateKey = function (privateKey, transaction) {
372
- return __awaiter(this, void 0, void 0, function () {
373
- var transactionBuilder, _i, _a, input, _b, _c, output, generatedChangeAddress, i;
374
- return __generator(this, function (_d) {
375
- switch (_d.label) {
376
- case 0:
377
- transactionBuilder = new this.options.config.bitcoinJSLib.TransactionBuilder(this.options.network.extras.network);
378
- for (_i = 0, _a = transaction.ins; _i < _a.length; _i++) {
379
- input = _a[_i];
380
- transactionBuilder.addInput(input.txId, input.vout);
381
- }
382
- _b = 0, _c = transaction.outs;
383
- _d.label = 1;
384
- case 1:
385
- if (!(_b < _c.length)) return [3 /*break*/, 5];
386
- output = _c[_b];
387
- if (!output.isChange) return [3 /*break*/, 3];
388
- return [4 /*yield*/, this.getAddressFromPublicKey(privateKey)];
389
- case 2:
390
- generatedChangeAddress = (_d.sent()).address;
391
- if (generatedChangeAddress !== output.recipient) {
392
- throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Change address could not be verified.');
393
- }
394
- _d.label = 3;
395
- case 3:
396
- transactionBuilder.addOutput(output.recipient, new bignumber_1.default(output.value).toNumber());
397
- _d.label = 4;
398
- case 4:
399
- _b++;
400
- return [3 /*break*/, 1];
401
- case 5:
402
- for (i = 0; i < transaction.ins.length; i++) {
403
- // 2. `privateKey` is used as a hex string
404
- transactionBuilder.sign(i, Buffer.from(privateKey, 'hex'));
405
- }
406
- // TODO: given 1 & 2, check if it works
407
- return [2 /*return*/, transactionBuilder.build().toHex()];
217
+ }
218
+ transactionBuilder.addOutput(output.recipient, new bignumber_1.default(output.value).toNumber());
219
+ }
220
+ for (let i = 0; i < transaction.ins.length; i++) {
221
+ // 2. `privateKey` is used as a hex string
222
+ transactionBuilder.sign(i, Buffer.from(privateKey, 'hex'));
223
+ }
224
+ // TODO: given 1 & 2, check if it works
225
+ return transactionBuilder.build().toHex();
226
+ }
227
+ async signWithExtendedPrivateKey(extendedPrivateKey, transaction) {
228
+ const transactionBuilder = new this.options.config.bitcoinJSLib.TransactionBuilder(this.options.network.extras.network);
229
+ const node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPrivateKey, this.options.network.extras.network);
230
+ for (const input of transaction.ins) {
231
+ transactionBuilder.addInput(input.txId, input.vout);
232
+ }
233
+ const changeAddressBatchSize = 10;
234
+ const changeAddressMaxAddresses = 500;
235
+ for (const output of transaction.outs) {
236
+ let changeAddressIsValid = false;
237
+ if (output.isChange) {
238
+ if (output.derivationPath) {
239
+ const generatedChangeAddress = (await this.getAddressesFromExtendedPublicKey(extendedPrivateKey, 1, 1, parseInt(output.derivationPath, 10))).map((address) => address.address);
240
+ changeAddressIsValid = generatedChangeAddress.includes(output.recipient);
408
241
  }
409
- });
410
- });
411
- };
412
- BitcoinProtocol.prototype.signWithExtendedPrivateKey = function (extendedPrivateKey, transaction) {
413
- return __awaiter(this, void 0, void 0, function () {
414
- var transactionBuilder, node, _i, _a, input, changeAddressBatchSize, changeAddressMaxAddresses, _b, _c, output, changeAddressIsValid, generatedChangeAddress, x, addresses, i;
415
- return __generator(this, function (_d) {
416
- switch (_d.label) {
417
- case 0:
418
- transactionBuilder = new this.options.config.bitcoinJSLib.TransactionBuilder(this.options.network.extras.network);
419
- node = this.options.config.bitcoinJSLib.HDNode.fromBase58(extendedPrivateKey, this.options.network.extras.network);
420
- for (_i = 0, _a = transaction.ins; _i < _a.length; _i++) {
421
- input = _a[_i];
422
- transactionBuilder.addInput(input.txId, input.vout);
423
- }
424
- changeAddressBatchSize = 10;
425
- changeAddressMaxAddresses = 500;
426
- _b = 0, _c = transaction.outs;
427
- _d.label = 1;
428
- case 1:
429
- if (!(_b < _c.length)) return [3 /*break*/, 10];
430
- output = _c[_b];
431
- changeAddressIsValid = false;
432
- if (!output.isChange) return [3 /*break*/, 8];
433
- if (!output.derivationPath) return [3 /*break*/, 3];
434
- return [4 /*yield*/, this.getAddressesFromExtendedPublicKey(extendedPrivateKey, 1, 1, parseInt(output.derivationPath, 10))];
435
- case 2:
436
- generatedChangeAddress = (_d.sent()).map(function (address) { return address.address; });
437
- changeAddressIsValid = generatedChangeAddress.includes(output.recipient);
438
- return [3 /*break*/, 7];
439
- case 3:
440
- x = 0;
441
- _d.label = 4;
442
- case 4:
443
- if (!(x < changeAddressMaxAddresses)) return [3 /*break*/, 7];
444
- return [4 /*yield*/, this.getAddressesFromExtendedPublicKey(extendedPrivateKey, 1, changeAddressBatchSize, x)];
445
- case 5:
446
- addresses = (_d.sent()).map(function (address) { return address.address; });
242
+ else {
243
+ for (let x = 0; x < changeAddressMaxAddresses; x += changeAddressBatchSize) {
244
+ const addresses = (await this.getAddressesFromExtendedPublicKey(extendedPrivateKey, 1, changeAddressBatchSize, x)).map((address) => address.address);
447
245
  if (addresses.indexOf(output.recipient) >= 0) {
448
246
  changeAddressIsValid = true;
449
247
  x = changeAddressMaxAddresses;
450
248
  }
451
- _d.label = 6;
452
- case 6:
453
- x += changeAddressBatchSize;
454
- return [3 /*break*/, 4];
455
- case 7:
456
- if (!changeAddressIsValid) {
457
- throw new errors_1.InvalidValueError(coinlib_error_1.Domain.BITCOIN, 'Change address could not be verified.');
458
- }
459
- _d.label = 8;
460
- case 8:
461
- transactionBuilder.addOutput(output.recipient, new bignumber_1.default(output.value).toNumber());
462
- _d.label = 9;
463
- case 9:
464
- _b++;
465
- return [3 /*break*/, 1];
466
- case 10:
467
- for (i = 0; i < transaction.ins.length; i++) {
468
- transactionBuilder.sign(i, node.derivePath(transaction.ins[i].derivationPath));
469
- }
470
- return [2 /*return*/, transactionBuilder.build().toHex()];
471
- }
472
- });
473
- });
474
- };
475
- BitcoinProtocol.prototype.getTransactionDetails = function (unsignedTx) {
476
- return __awaiter(this, void 0, void 0, function () {
477
- var transaction, feeCalculator, _i, _a, txIn, _b, _c, txOut, warnings;
478
- return __generator(this, function (_d) {
479
- transaction = unsignedTx.transaction;
480
- feeCalculator = new bignumber_1.default(0);
481
- for (_i = 0, _a = transaction.ins; _i < _a.length; _i++) {
482
- txIn = _a[_i];
483
- feeCalculator = feeCalculator.plus(new bignumber_1.default(txIn.value));
484
- }
485
- for (_b = 0, _c = transaction.outs; _b < _c.length; _b++) {
486
- txOut = _c[_b];
487
- feeCalculator = feeCalculator.minus(new bignumber_1.default(txOut.value));
488
- }
489
- warnings = [];
490
- return [2 /*return*/, [
491
- {
492
- from: transaction.ins.map(function (obj) { return obj.address; }),
493
- to: transaction.outs.filter(function (obj) { return !obj.isChange; }).map(function (obj) { return obj.recipient; }),
494
- amount: transaction.outs
495
- .filter(function (obj) { return !obj.isChange; })
496
- .map(function (obj) { return new bignumber_1.default(obj.value); })
497
- .reduce(function (accumulator, currentValue) { return accumulator.plus(currentValue); })
498
- .toString(10),
499
- fee: feeCalculator.toString(10),
500
- protocolIdentifier: this.identifier,
501
- network: this.options.network,
502
- isInbound: false,
503
- transactionDetails: unsignedTx.transaction,
504
- warnings: warnings
505
- }
506
- ]];
507
- });
508
- });
509
- };
510
- BitcoinProtocol.prototype.getTransactionDetailsFromSigned = function (signedTx) {
511
- return __awaiter(this, void 0, void 0, function () {
512
- var tx, bitcoinTx;
513
- var _this = this;
514
- return __generator(this, function (_a) {
515
- tx = {
516
- to: [],
517
- from: signedTx.from,
518
- amount: signedTx.amount,
519
- fee: signedTx.fee,
520
- protocolIdentifier: this.identifier,
521
- network: this.options.network,
522
- isInbound: false,
523
- transactionDetails: signedTx.transaction
524
- };
525
- bitcoinTx = this.options.config.bitcoinJSLib.Transaction.fromHex(signedTx.transaction);
526
- bitcoinTx.outs.forEach(function (output) {
527
- var address = _this.options.config.bitcoinJSLib.address.fromOutputScript(output.script, _this.options.network.extras.network);
528
- // only works if one output is target and rest is change, but this way we can filter out change addresses
529
- if (new bignumber_1.default(output.value).isEqualTo(signedTx.amount)) {
530
- tx.to.push(address);
531
249
  }
532
- });
533
- return [2 /*return*/, [tx]];
534
- });
535
- });
536
- };
537
- BitcoinProtocol.prototype.getBalanceOfAddresses = function (addresses) {
538
- return __awaiter(this, void 0, void 0, function () {
539
- var valueAccumulator, _i, addresses_1, address, data;
540
- return __generator(this, function (_a) {
541
- switch (_a.label) {
542
- case 0:
543
- valueAccumulator = new bignumber_1.default(0);
544
- _i = 0, addresses_1 = addresses;
545
- _a.label = 1;
546
- case 1:
547
- if (!(_i < addresses_1.length)) return [3 /*break*/, 4];
548
- address = addresses_1[_i];
549
- return [4 /*yield*/, index_1.default.get("".concat(this.options.network.extras.indexerApi, "/api/v2/address/").concat(address, "?details=basic"), {
550
- responseType: 'json'
551
- })];
552
- case 2:
553
- data = (_a.sent()).data;
554
- valueAccumulator = valueAccumulator.plus(new bignumber_1.default(data.balance));
555
- _a.label = 3;
556
- case 3:
557
- _i++;
558
- return [3 /*break*/, 1];
559
- case 4: return [2 /*return*/, valueAccumulator.toString(10)];
560
250
  }
561
- });
562
- });
563
- };
564
- BitcoinProtocol.prototype.getBalanceOfPublicKey = function (publicKey) {
565
- return __awaiter(this, void 0, void 0, function () {
566
- var address;
567
- return __generator(this, function (_a) {
568
- switch (_a.label) {
569
- case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
570
- case 1:
571
- address = _a.sent();
572
- return [2 /*return*/, this.getBalanceOfAddresses([address.address])];
573
- }
574
- });
575
- });
576
- };
577
- BitcoinProtocol.prototype.getBalanceOfExtendedPublicKey = function (extendedPublicKey, offset) {
578
- if (offset === void 0) { offset = 0; }
579
- return __awaiter(this, void 0, void 0, function () {
580
- var data;
581
- return __generator(this, function (_a) {
582
- switch (_a.label) {
583
- case 0: return [4 /*yield*/, index_1.default.get("".concat(this.options.network.extras.indexerApi, "/api/v2/xpub/").concat(extendedPublicKey, "?pageSize=1"), {
584
- responseType: 'json'
585
- })];
586
- case 1:
587
- data = (_a.sent()).data;
588
- return [2 /*return*/, data.balance];
251
+ if (!changeAddressIsValid) {
252
+ throw new errors_1.InvalidValueError(coinlib_error_1.Domain.BITCOIN, 'Change address could not be verified.');
589
253
  }
590
- });
591
- });
592
- };
593
- BitcoinProtocol.prototype.getBalanceOfPublicKeyForSubProtocols = function (publicKey, subProtocols) {
594
- return __awaiter(this, void 0, void 0, function () {
595
- return __generator(this, function (_a) {
596
- throw Promise.reject('get balance of sub protocols not supported');
597
- });
598
- });
599
- };
600
- BitcoinProtocol.prototype.getAvailableBalanceOfAddresses = function (addresses) {
601
- return __awaiter(this, void 0, void 0, function () {
602
- return __generator(this, function (_a) {
603
- return [2 /*return*/, this.getBalanceOfAddresses(addresses)];
604
- });
605
- });
606
- };
607
- BitcoinProtocol.prototype.estimateMaxTransactionValueFromExtendedPublicKey = function (extendedPublicKey, recipients, fee) {
608
- return __awaiter(this, void 0, void 0, function () {
609
- return __generator(this, function (_a) {
610
- return [2 /*return*/, this.getBalanceOfExtendedPublicKey(extendedPublicKey)];
611
- });
254
+ }
255
+ transactionBuilder.addOutput(output.recipient, new bignumber_1.default(output.value).toNumber());
256
+ }
257
+ for (let i = 0; i < transaction.ins.length; i++) {
258
+ transactionBuilder.sign(i, node.derivePath(transaction.ins[i].derivationPath));
259
+ }
260
+ return transactionBuilder.build().toHex();
261
+ }
262
+ async getTransactionDetails(unsignedTx) {
263
+ // out of public information (both broadcaster and signer)
264
+ const transaction = unsignedTx.transaction;
265
+ let feeCalculator = new bignumber_1.default(0);
266
+ for (const txIn of transaction.ins) {
267
+ feeCalculator = feeCalculator.plus(new bignumber_1.default(txIn.value));
268
+ }
269
+ for (const txOut of transaction.outs) {
270
+ feeCalculator = feeCalculator.minus(new bignumber_1.default(txOut.value));
271
+ }
272
+ const warnings = [];
273
+ return [
274
+ {
275
+ from: transaction.ins.map((obj) => obj.address),
276
+ to: transaction.outs.filter((obj) => !obj.isChange).map((obj) => obj.recipient),
277
+ amount: transaction.outs
278
+ .filter((obj) => !obj.isChange)
279
+ .map((obj) => new bignumber_1.default(obj.value))
280
+ .reduce((accumulator, currentValue) => accumulator.plus(currentValue))
281
+ .toString(10),
282
+ fee: feeCalculator.toString(10),
283
+ protocolIdentifier: this.identifier,
284
+ network: this.options.network,
285
+ isInbound: false,
286
+ transactionDetails: unsignedTx.transaction,
287
+ warnings
288
+ }
289
+ ];
290
+ }
291
+ async getTransactionDetailsFromSigned(signedTx) {
292
+ const tx = {
293
+ to: [],
294
+ from: signedTx.from,
295
+ amount: signedTx.amount,
296
+ fee: signedTx.fee,
297
+ protocolIdentifier: this.identifier,
298
+ network: this.options.network,
299
+ isInbound: false,
300
+ transactionDetails: signedTx.transaction
301
+ };
302
+ const bitcoinTx = this.options.config.bitcoinJSLib.Transaction.fromHex(signedTx.transaction);
303
+ bitcoinTx.outs.forEach((output) => {
304
+ const address = this.options.config.bitcoinJSLib.address.fromOutputScript(output.script, this.options.network.extras.network);
305
+ // only works if one output is target and rest is change, but this way we can filter out change addresses
306
+ if (new bignumber_1.default(output.value).isEqualTo(signedTx.amount)) {
307
+ tx.to.push(address);
308
+ }
612
309
  });
613
- };
614
- BitcoinProtocol.prototype.estimateMaxTransactionValueFromPublicKey = function (publicKey, recipients, fee) {
615
- return __awaiter(this, void 0, void 0, function () {
616
- return __generator(this, function (_a) {
617
- return [2 /*return*/, this.getBalanceOfPublicKey(publicKey)];
618
- });
310
+ return [tx];
311
+ }
312
+ async getBalanceOfAddresses(addresses) {
313
+ let valueAccumulator = new bignumber_1.default(0);
314
+ // The API doesn't support batch checking of balances, so we have to do it manually
315
+ for (const address of addresses) {
316
+ const { data } = await index_1.default.get(`${this.options.network.extras.indexerApi}/api/v2/address/${address}?details=basic`, {
317
+ responseType: 'json'
318
+ });
319
+ valueAccumulator = valueAccumulator.plus(new bignumber_1.default(data.balance));
320
+ }
321
+ return valueAccumulator.toString(10);
322
+ }
323
+ async getBalanceOfPublicKey(publicKey) {
324
+ const address = await this.getAddressFromPublicKey(publicKey);
325
+ return this.getBalanceOfAddresses([address.address]);
326
+ }
327
+ async getBalanceOfExtendedPublicKey(extendedPublicKey, offset = 0) {
328
+ const { data } = await index_1.default.get(`${this.options.network.extras.indexerApi}/api/v2/xpub/${extendedPublicKey}?pageSize=1`, {
329
+ responseType: 'json'
619
330
  });
620
- };
621
- BitcoinProtocol.prototype.estimateFeeDefaultsFromExtendedPublicKey = function (publicKey, recipients, values, data) {
622
- return __awaiter(this, void 0, void 0, function () {
623
- var result, estimatedFee, feeStepFactor, mediumFee, lowFee, highFee;
624
- return __generator(this, function (_a) {
625
- switch (_a.label) {
626
- case 0: return [4 /*yield*/, index_1.default.get("".concat(this.options.network.extras.indexerApi, "/api/v2/estimatefee/5"))];
627
- case 1:
628
- result = (_a.sent()).data.result;
629
- estimatedFee = new bignumber_1.default(result).shiftedBy(this.feeDecimals);
630
- if (estimatedFee.isZero()) {
631
- return [2 /*return*/, this.feeDefaults];
632
- }
633
- feeStepFactor = new bignumber_1.default(0.5);
634
- mediumFee = estimatedFee;
635
- lowFee = mediumFee.minus(mediumFee.times(feeStepFactor)).integerValue(bignumber_1.default.ROUND_FLOOR);
636
- highFee = mediumFee.plus(mediumFee.times(feeStepFactor)).integerValue(bignumber_1.default.ROUND_FLOOR);
637
- return [2 /*return*/, {
638
- low: lowFee.shiftedBy(-this.feeDecimals).toFixed(),
639
- medium: mediumFee.shiftedBy(-this.feeDecimals).toFixed(),
640
- high: highFee.shiftedBy(-this.feeDecimals).toFixed()
641
- }];
642
- }
331
+ return data.balance;
332
+ }
333
+ async getBalanceOfPublicKeyForSubProtocols(publicKey, subProtocols) {
334
+ throw Promise.reject('get balance of sub protocols not supported');
335
+ }
336
+ async getAvailableBalanceOfAddresses(addresses) {
337
+ return this.getBalanceOfAddresses(addresses);
338
+ }
339
+ async estimateMaxTransactionValueFromExtendedPublicKey(extendedPublicKey, recipients, fee) {
340
+ return this.getBalanceOfExtendedPublicKey(extendedPublicKey);
341
+ }
342
+ async estimateMaxTransactionValueFromPublicKey(publicKey, recipients, fee) {
343
+ return this.getBalanceOfPublicKey(publicKey);
344
+ }
345
+ async estimateFeeDefaultsFromExtendedPublicKey(publicKey, recipients, values, data) {
346
+ const result = (await index_1.default.get(`${this.options.network.extras.indexerApi}/api/v2/estimatefee/5`)).data.result;
347
+ const estimatedFee = new bignumber_1.default(result).shiftedBy(this.feeDecimals);
348
+ if (estimatedFee.isZero()) {
349
+ return this.feeDefaults;
350
+ }
351
+ const feeStepFactor = new bignumber_1.default(0.5);
352
+ const mediumFee = estimatedFee;
353
+ const lowFee = mediumFee.minus(mediumFee.times(feeStepFactor)).integerValue(bignumber_1.default.ROUND_FLOOR);
354
+ const highFee = mediumFee.plus(mediumFee.times(feeStepFactor)).integerValue(bignumber_1.default.ROUND_FLOOR);
355
+ return {
356
+ low: lowFee.shiftedBy(-this.feeDecimals).toFixed(),
357
+ medium: mediumFee.shiftedBy(-this.feeDecimals).toFixed(),
358
+ high: highFee.shiftedBy(-this.feeDecimals).toFixed()
359
+ };
360
+ }
361
+ async estimateFeeDefaultsFromPublicKey(publicKey, recipients, values, data) {
362
+ return Promise.reject('estimating fee defaults using non extended public key not implemented');
363
+ }
364
+ async prepareTransactionFromExtendedPublicKey(extendedPublicKey, offset, recipients, values, fee, extras) {
365
+ const wrappedValues = values.map((value) => new bignumber_1.default(value));
366
+ const wrappedFee = new bignumber_1.default(fee);
367
+ const transaction = {
368
+ ins: [],
369
+ outs: []
370
+ };
371
+ if (recipients.length !== wrappedValues.length) {
372
+ throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'recipients do not match values');
373
+ }
374
+ const { data: utxos } = await index_1.default
375
+ .get(`${this.options.network.extras.indexerApi}/api/v2/utxo/${extendedPublicKey}?confirmed=true`, {
376
+ responseType: 'json'
377
+ })
378
+ .catch((error) => {
379
+ throw new errors_1.NetworkError(coinlib_error_1.Domain.BITCOIN, error);
380
+ });
381
+ if (utxos.length <= 0) {
382
+ throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, 'not enough balance'); // no transactions found on those addresses, probably won't find anything in the next ones
383
+ }
384
+ const totalRequiredBalance = wrappedValues
385
+ .reduce((accumulator, currentValue) => accumulator.plus(currentValue))
386
+ .plus(wrappedFee);
387
+ let valueAccumulator = new bignumber_1.default(0);
388
+ const getPathIndexes = (path) => {
389
+ const result = path
390
+ .split('/')
391
+ .slice(-2)
392
+ .map((item) => parseInt(item, 10))
393
+ .filter((item) => !isNaN(item));
394
+ if (result.length !== 2) {
395
+ throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Unexpected path format');
396
+ }
397
+ return [result[0], result[1]];
398
+ };
399
+ for (const utxo of utxos) {
400
+ valueAccumulator = valueAccumulator.plus(utxo.value);
401
+ const indexes = getPathIndexes(utxo.path);
402
+ const derivedAddress = await this.getAddressFromExtendedPublicKey(extendedPublicKey, indexes[0], indexes[1]);
403
+ if (derivedAddress.address === utxo.address) {
404
+ transaction.ins.push({
405
+ txId: utxo.txid,
406
+ value: new bignumber_1.default(utxo.value).toString(10),
407
+ vout: utxo.vout,
408
+ address: utxo.address,
409
+ derivationPath: indexes.join('/')
410
+ });
411
+ }
412
+ else {
413
+ throw new errors_1.InvalidValueError(coinlib_error_1.Domain.BITCOIN, `Invalid address ${JSON.stringify(utxo.address)} returned from API`);
414
+ }
415
+ if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
416
+ break;
417
+ }
418
+ }
419
+ if (valueAccumulator.isLessThan(totalRequiredBalance)) {
420
+ throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, 'not enough balance');
421
+ }
422
+ for (let i = 0; i < recipients.length; i++) {
423
+ transaction.outs.push({
424
+ recipient: recipients[i],
425
+ isChange: false,
426
+ value: wrappedValues[i].toString(10),
427
+ derivationPath: '' // TODO: Remove this as soon as our serializer supports optional properties
428
+ });
429
+ valueAccumulator = valueAccumulator.minus(wrappedValues[i]);
430
+ }
431
+ const lastUsedInternalAddress = Math.max(-1, ...utxos
432
+ .map((utxo) => getPathIndexes(utxo.path))
433
+ .filter((indexes) => indexes[0] === 1)
434
+ .map((indexes) => indexes[1]));
435
+ // If the change is considered dust, the transaction will fail.
436
+ // Dust is a variable value around 300-600 satoshis, depending on the configuration.
437
+ // We set a low fee here to not block any transactions, but it might still fail due to "dust".
438
+ const changeValue = valueAccumulator.minus(wrappedFee);
439
+ if (changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) {
440
+ const changeAddressIndex = lastUsedInternalAddress + 1;
441
+ const derivedAddress = await this.getAddressFromExtendedPublicKey(extendedPublicKey, 1, changeAddressIndex);
442
+ transaction.outs.push({
443
+ recipient: derivedAddress.address,
444
+ isChange: true,
445
+ value: changeValue.toString(10),
446
+ derivationPath: changeAddressIndex.toString()
643
447
  });
644
- });
645
- };
646
- BitcoinProtocol.prototype.estimateFeeDefaultsFromPublicKey = function (publicKey, recipients, values, data) {
647
- return __awaiter(this, void 0, void 0, function () {
648
- return __generator(this, function (_a) {
649
- return [2 /*return*/, Promise.reject('estimating fee defaults using non extended public key not implemented')];
448
+ }
449
+ return transaction;
450
+ }
451
+ async prepareTransactionFromPublicKey(publicKey, recipients, values, fee) {
452
+ const wrappedValues = values.map((value) => new bignumber_1.default(value));
453
+ const wrappedFee = new bignumber_1.default(fee);
454
+ const transaction = {
455
+ ins: [],
456
+ outs: []
457
+ };
458
+ if (recipients.length !== wrappedValues.length) {
459
+ throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Recipient and value length does not match.');
460
+ }
461
+ const address = (await this.getAddressFromPublicKey(publicKey)).address;
462
+ const { data: utxos } = await index_1.default.get(`${this.options.network.extras.indexerApi}/api/v2/utxo/${address}`, {
463
+ responseType: 'json'
464
+ });
465
+ const totalRequiredBalance = wrappedValues
466
+ .reduce((accumulator, currentValue) => accumulator.plus(currentValue))
467
+ .plus(wrappedFee);
468
+ let valueAccumulator = new bignumber_1.default(0);
469
+ for (const utxo of utxos) {
470
+ valueAccumulator = valueAccumulator.plus(new bignumber_1.default(utxo.value));
471
+ transaction.ins.push({
472
+ txId: utxo.txid,
473
+ value: new bignumber_1.default(utxo.value).toString(10),
474
+ vout: utxo.vout,
475
+ address
476
+ });
477
+ if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
478
+ break;
479
+ }
480
+ }
481
+ if (valueAccumulator.isLessThan(totalRequiredBalance)) {
482
+ throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, `not enough balance, having ${valueAccumulator.toFixed()} of ${totalRequiredBalance.toFixed()}`);
483
+ }
484
+ // tx.addInput(utxo.txid, utxo.vout)
485
+ for (let i = 0; i < recipients.length; i++) {
486
+ transaction.outs.push({
487
+ recipient: recipients[i],
488
+ isChange: false,
489
+ value: wrappedValues[i].toString(10)
490
+ });
491
+ valueAccumulator = valueAccumulator.minus(wrappedValues[i]);
492
+ // tx.addOutput(recipients[i], values[i])
493
+ }
494
+ // If the change is considered dust, the transaction will fail.
495
+ // Dust is a variable value around 300-600 satoshis, depending on the configuration.
496
+ // We set a low fee here to not block any transactions, but it might still fail due to "dust".
497
+ const changeValue = valueAccumulator.minus(wrappedFee);
498
+ if (changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) {
499
+ transaction.outs.push({
500
+ recipient: address,
501
+ isChange: true,
502
+ value: changeValue.toString(10)
650
503
  });
651
- });
652
- };
653
- BitcoinProtocol.prototype.prepareTransactionFromExtendedPublicKey = function (extendedPublicKey, offset, recipients, values, fee, extras) {
654
- return __awaiter(this, void 0, void 0, function () {
655
- var wrappedValues, wrappedFee, transaction, utxos, totalRequiredBalance, valueAccumulator, getPathIndexes, _i, utxos_1, utxo, indexes, derivedAddress, i, lastUsedInternalAddress, changeValue, changeAddressIndex, derivedAddress;
656
- return __generator(this, function (_a) {
657
- switch (_a.label) {
658
- case 0:
659
- wrappedValues = values.map(function (value) { return new bignumber_1.default(value); });
660
- wrappedFee = new bignumber_1.default(fee);
661
- transaction = {
662
- ins: [],
663
- outs: []
664
- };
665
- if (recipients.length !== wrappedValues.length) {
666
- throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'recipients do not match values');
667
- }
668
- return [4 /*yield*/, index_1.default
669
- .get("".concat(this.options.network.extras.indexerApi, "/api/v2/utxo/").concat(extendedPublicKey, "?confirmed=true"), {
670
- responseType: 'json'
671
- })
672
- .catch(function (error) {
673
- throw new errors_1.NetworkError(coinlib_error_1.Domain.BITCOIN, error);
674
- })];
675
- case 1:
676
- utxos = (_a.sent()).data;
677
- if (utxos.length <= 0) {
678
- throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, 'not enough balance'); // no transactions found on those addresses, probably won't find anything in the next ones
679
- }
680
- totalRequiredBalance = wrappedValues
681
- .reduce(function (accumulator, currentValue) { return accumulator.plus(currentValue); })
682
- .plus(wrappedFee);
683
- valueAccumulator = new bignumber_1.default(0);
684
- getPathIndexes = function (path) {
685
- var result = path
686
- .split('/')
687
- .slice(-2)
688
- .map(function (item) { return parseInt(item, 10); })
689
- .filter(function (item) { return !isNaN(item); });
690
- if (result.length !== 2) {
691
- throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Unexpected path format');
692
- }
693
- return [result[0], result[1]];
694
- };
695
- _i = 0, utxos_1 = utxos;
696
- _a.label = 2;
697
- case 2:
698
- if (!(_i < utxos_1.length)) return [3 /*break*/, 5];
699
- utxo = utxos_1[_i];
700
- valueAccumulator = valueAccumulator.plus(utxo.value);
701
- indexes = getPathIndexes(utxo.path);
702
- return [4 /*yield*/, this.getAddressFromExtendedPublicKey(extendedPublicKey, indexes[0], indexes[1])];
703
- case 3:
704
- derivedAddress = _a.sent();
705
- if (derivedAddress.address === utxo.address) {
706
- transaction.ins.push({
707
- txId: utxo.txid,
708
- value: new bignumber_1.default(utxo.value).toString(10),
709
- vout: utxo.vout,
710
- address: utxo.address,
711
- derivationPath: indexes.join('/')
712
- });
713
- }
714
- else {
715
- throw new errors_1.InvalidValueError(coinlib_error_1.Domain.BITCOIN, "Invalid address ".concat(JSON.stringify(utxo.address), " returned from API"));
716
- }
717
- if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
718
- return [3 /*break*/, 5];
719
- }
720
- _a.label = 4;
721
- case 4:
722
- _i++;
723
- return [3 /*break*/, 2];
724
- case 5:
725
- if (valueAccumulator.isLessThan(totalRequiredBalance)) {
726
- throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, 'not enough balance');
727
- }
728
- for (i = 0; i < recipients.length; i++) {
729
- transaction.outs.push({
730
- recipient: recipients[i],
731
- isChange: false,
732
- value: wrappedValues[i].toString(10),
733
- derivationPath: '' // TODO: Remove this as soon as our serializer supports optional properties
734
- });
735
- valueAccumulator = valueAccumulator.minus(wrappedValues[i]);
736
- }
737
- lastUsedInternalAddress = Math.max.apply(Math, __spreadArray([-1], utxos
738
- .map(function (utxo) { return getPathIndexes(utxo.path); })
739
- .filter(function (indexes) { return indexes[0] === 1; })
740
- .map(function (indexes) { return indexes[1]; }), false));
741
- changeValue = valueAccumulator.minus(wrappedFee);
742
- if (!changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) return [3 /*break*/, 7];
743
- changeAddressIndex = lastUsedInternalAddress + 1;
744
- return [4 /*yield*/, this.getAddressFromExtendedPublicKey(extendedPublicKey, 1, changeAddressIndex)];
745
- case 6:
746
- derivedAddress = _a.sent();
747
- transaction.outs.push({
748
- recipient: derivedAddress.address,
749
- isChange: true,
750
- value: changeValue.toString(10),
751
- derivationPath: changeAddressIndex.toString()
752
- });
753
- _a.label = 7;
754
- case 7: return [2 /*return*/, transaction];
504
+ }
505
+ return transaction;
506
+ }
507
+ async broadcastTransaction(rawTransaction) {
508
+ const { data } = await index_1.default.post(this.options.network.extras.indexerApi + '/api/v2/sendtx/', rawTransaction);
509
+ return data.result;
510
+ }
511
+ async getTransactionsFromExtendedPublicKey(extendedPublicKey, limit, cursor, addressOffset = 0) {
512
+ const page = cursor?.page ?? 1;
513
+ const { data } = await index_1.default.get(this.options.network.extras.indexerApi +
514
+ '/api/v2/xpub/' +
515
+ extendedPublicKey +
516
+ `?details=txs&tokens=used&pageSize=${limit}&page=${page}`, {
517
+ responseType: 'json'
518
+ });
519
+ const ourAddresses = (data.tokens || []).filter((token) => token.type === 'XPUBAddress').map((token) => token.name);
520
+ const airGapTransactions = [];
521
+ if (data.page == page) {
522
+ for (const transaction of data.transactions || []) {
523
+ const tempAirGapTransactionFrom = [];
524
+ const tempAirGapTransactionTo = [];
525
+ let tempAirGapTransactionIsInbound = true;
526
+ let amount = new bignumber_1.default(0);
527
+ for (const vin of transaction.vin) {
528
+ if (this.containsSome(vin.addresses, ourAddresses)) {
529
+ tempAirGapTransactionIsInbound = false;
530
+ }
531
+ tempAirGapTransactionFrom.push(...vin.addresses);
532
+ amount = amount.plus(vin.value);
755
533
  }
756
- });
757
- });
758
- };
759
- BitcoinProtocol.prototype.prepareTransactionFromPublicKey = function (publicKey, recipients, values, fee) {
760
- return __awaiter(this, void 0, void 0, function () {
761
- var wrappedValues, wrappedFee, transaction, address, utxos, totalRequiredBalance, valueAccumulator, _i, utxos_2, utxo, i, changeValue;
762
- return __generator(this, function (_a) {
763
- switch (_a.label) {
764
- case 0:
765
- wrappedValues = values.map(function (value) { return new bignumber_1.default(value); });
766
- wrappedFee = new bignumber_1.default(fee);
767
- transaction = {
768
- ins: [],
769
- outs: []
770
- };
771
- if (recipients.length !== wrappedValues.length) {
772
- throw new errors_1.ConditionViolationError(coinlib_error_1.Domain.BITCOIN, 'Recipient and value length does not match.');
534
+ for (const vout of transaction.vout) {
535
+ if (vout.addresses) {
536
+ tempAirGapTransactionTo.push(...vout.addresses);
537
+ // If receiving address is our address, and transaction is outbound => our change
538
+ if (this.containsSome(vout.addresses, ourAddresses) && !tempAirGapTransactionIsInbound) {
539
+ // remove only if related to this address
540
+ amount = amount.minus(vout.value);
773
541
  }
774
- return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
775
- case 1:
776
- address = (_a.sent()).address;
777
- return [4 /*yield*/, index_1.default.get("".concat(this.options.network.extras.indexerApi, "/api/v2/utxo/").concat(address), {
778
- responseType: 'json'
779
- })];
780
- case 2:
781
- utxos = (_a.sent()).data;
782
- totalRequiredBalance = wrappedValues
783
- .reduce(function (accumulator, currentValue) { return accumulator.plus(currentValue); })
784
- .plus(wrappedFee);
785
- valueAccumulator = new bignumber_1.default(0);
786
- for (_i = 0, utxos_2 = utxos; _i < utxos_2.length; _i++) {
787
- utxo = utxos_2[_i];
788
- valueAccumulator = valueAccumulator.plus(new bignumber_1.default(utxo.value));
789
- transaction.ins.push({
790
- txId: utxo.txid,
791
- value: new bignumber_1.default(utxo.value).toString(10),
792
- vout: utxo.vout,
793
- address: address
794
- });
795
- if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
796
- break;
797
- }
542
+ // If receiving address is not ours, and transaction isbound => senders change
543
+ if (!this.containsSome(vout.addresses, ourAddresses) && tempAirGapTransactionIsInbound) {
544
+ amount = amount.minus(vout.value);
798
545
  }
799
- if (valueAccumulator.isLessThan(totalRequiredBalance)) {
800
- throw new errors_1.BalanceError(coinlib_error_1.Domain.BITCOIN, "not enough balance, having ".concat(valueAccumulator.toFixed(), " of ").concat(totalRequiredBalance.toFixed()));
801
- }
802
- // tx.addInput(utxo.txid, utxo.vout)
803
- for (i = 0; i < recipients.length; i++) {
804
- transaction.outs.push({
805
- recipient: recipients[i],
806
- isChange: false,
807
- value: wrappedValues[i].toString(10)
808
- });
809
- valueAccumulator = valueAccumulator.minus(wrappedValues[i]);
810
- // tx.addOutput(recipients[i], values[i])
811
- }
812
- changeValue = valueAccumulator.minus(wrappedFee);
813
- if (changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) {
814
- transaction.outs.push({
815
- recipient: address,
816
- isChange: true,
817
- value: changeValue.toString(10)
818
- });
819
- }
820
- return [2 /*return*/, transaction];
546
+ }
821
547
  }
822
- });
823
- });
824
- };
825
- BitcoinProtocol.prototype.broadcastTransaction = function (rawTransaction) {
826
- return __awaiter(this, void 0, void 0, function () {
827
- var data;
828
- return __generator(this, function (_a) {
829
- switch (_a.label) {
830
- case 0: return [4 /*yield*/, index_1.default.post(this.options.network.extras.indexerApi + '/api/v2/sendtx/', rawTransaction)];
831
- case 1:
832
- data = (_a.sent()).data;
833
- return [2 /*return*/, data.result];
548
+ // deduct fee from amount
549
+ amount = amount.minus(transaction.fees);
550
+ const airGapTransaction = {
551
+ hash: transaction.txid,
552
+ from: tempAirGapTransactionFrom,
553
+ to: tempAirGapTransactionTo,
554
+ isInbound: tempAirGapTransactionIsInbound,
555
+ amount: amount.toString(10),
556
+ fee: new bignumber_1.default(transaction.fees).toString(10),
557
+ blockHeight: transaction.blockHeight.toString(),
558
+ protocolIdentifier: this.identifier,
559
+ network: this.options.network,
560
+ timestamp: transaction.blockTime
561
+ };
562
+ airGapTransactions.push(airGapTransaction);
563
+ }
564
+ }
565
+ return {
566
+ transactions: airGapTransactions,
567
+ cursor: {
568
+ page: cursor ? cursor.page + 1 : 2
569
+ }
570
+ };
571
+ }
572
+ async getTransactionsFromPublicKey(publicKey, limit, cursor) {
573
+ const address = await this.getAddressFromPublicKey(publicKey);
574
+ return this.getTransactionsFromAddresses([address.address], limit, cursor);
575
+ }
576
+ async getTransactionsFromAddresses(addresses, limit, cursor) {
577
+ const airGapTransactions = [];
578
+ const page = cursor?.page ?? 1;
579
+ const url = `${this.options.network.extras.indexerApi}/api/v2/address/${addresses[0]}?page=${page}&pageSize=${limit}&details=txs`;
580
+ const { data } = await index_1.default.get(url, {
581
+ responseType: 'json'
582
+ });
583
+ if (data.page == page) {
584
+ for (const transaction of data.transactions || []) {
585
+ const tempAirGapTransactionFrom = [];
586
+ const tempAirGapTransactionTo = [];
587
+ let tempAirGapTransactionIsInbound = true;
588
+ let amount = new bignumber_1.default(0);
589
+ for (const vin of transaction.vin) {
590
+ if (vin.addresses && this.containsSome(vin.addresses, addresses)) {
591
+ tempAirGapTransactionIsInbound = false;
592
+ }
593
+ tempAirGapTransactionFrom.push(...vin.addresses);
594
+ amount = vin.value ? amount.plus(vin.value) : amount;
834
595
  }
835
- });
836
- });
837
- };
838
- BitcoinProtocol.prototype.getTransactionsFromExtendedPublicKey = function (extendedPublicKey, limit, cursor, addressOffset) {
839
- var _a;
840
- if (addressOffset === void 0) { addressOffset = 0; }
841
- return __awaiter(this, void 0, void 0, function () {
842
- var page, data, ourAddresses, airGapTransactions, _i, _b, transaction, tempAirGapTransactionFrom, tempAirGapTransactionTo, tempAirGapTransactionIsInbound, amount, _c, _d, vin, _e, _f, vout, airGapTransaction;
843
- return __generator(this, function (_g) {
844
- switch (_g.label) {
845
- case 0:
846
- page = (_a = cursor === null || cursor === void 0 ? void 0 : cursor.page) !== null && _a !== void 0 ? _a : 1;
847
- return [4 /*yield*/, index_1.default.get(this.options.network.extras.indexerApi +
848
- '/api/v2/xpub/' +
849
- extendedPublicKey +
850
- "?details=txs&tokens=used&pageSize=".concat(limit, "&page=").concat(page), {
851
- responseType: 'json'
852
- })];
853
- case 1:
854
- data = (_g.sent()).data;
855
- ourAddresses = (data.tokens || []).filter(function (token) { return token.type === 'XPUBAddress'; }).map(function (token) { return token.name; });
856
- airGapTransactions = [];
857
- if (data.page == page) {
858
- for (_i = 0, _b = data.transactions || []; _i < _b.length; _i++) {
859
- transaction = _b[_i];
860
- tempAirGapTransactionFrom = [];
861
- tempAirGapTransactionTo = [];
862
- tempAirGapTransactionIsInbound = true;
863
- amount = new bignumber_1.default(0);
864
- for (_c = 0, _d = transaction.vin; _c < _d.length; _c++) {
865
- vin = _d[_c];
866
- if (this.containsSome(vin.addresses, ourAddresses)) {
867
- tempAirGapTransactionIsInbound = false;
868
- }
869
- tempAirGapTransactionFrom.push.apply(tempAirGapTransactionFrom, vin.addresses);
870
- amount = amount.plus(vin.value);
871
- }
872
- for (_e = 0, _f = transaction.vout; _e < _f.length; _e++) {
873
- vout = _f[_e];
874
- if (vout.addresses) {
875
- tempAirGapTransactionTo.push.apply(tempAirGapTransactionTo, vout.addresses);
876
- // If receiving address is our address, and transaction is outbound => our change
877
- if (this.containsSome(vout.addresses, ourAddresses) && !tempAirGapTransactionIsInbound) {
878
- // remove only if related to this address
879
- amount = amount.minus(vout.value);
880
- }
881
- // If receiving address is not ours, and transaction isbound => senders change
882
- if (!this.containsSome(vout.addresses, ourAddresses) && tempAirGapTransactionIsInbound) {
883
- amount = amount.minus(vout.value);
884
- }
885
- }
886
- }
887
- // deduct fee from amount
888
- amount = amount.minus(transaction.fees);
889
- airGapTransaction = {
890
- hash: transaction.txid,
891
- from: tempAirGapTransactionFrom,
892
- to: tempAirGapTransactionTo,
893
- isInbound: tempAirGapTransactionIsInbound,
894
- amount: amount.toString(10),
895
- fee: new bignumber_1.default(transaction.fees).toString(10),
896
- blockHeight: transaction.blockHeight.toString(),
897
- protocolIdentifier: this.identifier,
898
- network: this.options.network,
899
- timestamp: transaction.blockTime
900
- };
901
- airGapTransactions.push(airGapTransaction);
902
- }
596
+ for (const vout of transaction.vout) {
597
+ if (vout.addresses) {
598
+ tempAirGapTransactionTo.push(...vout.addresses);
599
+ // If receiving address is our address, and transaction is outbound => our change
600
+ if (this.containsSome(vout.addresses, addresses) && !tempAirGapTransactionIsInbound) {
601
+ // remove only if related to this address
602
+ amount = amount.minus(new bignumber_1.default(vout.value));
903
603
  }
904
- return [2 /*return*/, {
905
- transactions: airGapTransactions,
906
- cursor: {
907
- page: cursor ? cursor.page + 1 : 2
908
- }
909
- }];
910
- }
911
- });
912
- });
913
- };
914
- BitcoinProtocol.prototype.getTransactionsFromPublicKey = function (publicKey, limit, cursor) {
915
- return __awaiter(this, void 0, void 0, function () {
916
- var address;
917
- return __generator(this, function (_a) {
918
- switch (_a.label) {
919
- case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
920
- case 1:
921
- address = _a.sent();
922
- return [2 /*return*/, this.getTransactionsFromAddresses([address.address], limit, cursor)];
923
- }
924
- });
925
- });
926
- };
927
- BitcoinProtocol.prototype.getTransactionsFromAddresses = function (addresses, limit, cursor) {
928
- var _a;
929
- return __awaiter(this, void 0, void 0, function () {
930
- var airGapTransactions, page, url, data, _i, _b, transaction, tempAirGapTransactionFrom, tempAirGapTransactionTo, tempAirGapTransactionIsInbound, amount, _c, _d, vin, _e, _f, vout, airGapTransaction;
931
- return __generator(this, function (_g) {
932
- switch (_g.label) {
933
- case 0:
934
- airGapTransactions = [];
935
- page = (_a = cursor === null || cursor === void 0 ? void 0 : cursor.page) !== null && _a !== void 0 ? _a : 1;
936
- url = "".concat(this.options.network.extras.indexerApi, "/api/v2/address/").concat(addresses[0], "?page=").concat(page, "&pageSize=").concat(limit, "&details=txs");
937
- return [4 /*yield*/, index_1.default.get(url, {
938
- responseType: 'json'
939
- })];
940
- case 1:
941
- data = (_g.sent()).data;
942
- if (data.page == page) {
943
- for (_i = 0, _b = data.transactions || []; _i < _b.length; _i++) {
944
- transaction = _b[_i];
945
- tempAirGapTransactionFrom = [];
946
- tempAirGapTransactionTo = [];
947
- tempAirGapTransactionIsInbound = true;
948
- amount = new bignumber_1.default(0);
949
- for (_c = 0, _d = transaction.vin; _c < _d.length; _c++) {
950
- vin = _d[_c];
951
- if (vin.addresses && this.containsSome(vin.addresses, addresses)) {
952
- tempAirGapTransactionIsInbound = false;
953
- }
954
- tempAirGapTransactionFrom.push.apply(tempAirGapTransactionFrom, vin.addresses);
955
- amount = vin.value ? amount.plus(vin.value) : amount;
956
- }
957
- for (_e = 0, _f = transaction.vout; _e < _f.length; _e++) {
958
- vout = _f[_e];
959
- if (vout.addresses) {
960
- tempAirGapTransactionTo.push.apply(tempAirGapTransactionTo, vout.addresses);
961
- // If receiving address is our address, and transaction is outbound => our change
962
- if (this.containsSome(vout.addresses, addresses) && !tempAirGapTransactionIsInbound) {
963
- // remove only if related to this address
964
- amount = amount.minus(new bignumber_1.default(vout.value));
965
- }
966
- // If receiving address is not ours, and transaction isbound => senders change
967
- if (!this.containsSome(vout.addresses, addresses) && tempAirGapTransactionIsInbound) {
968
- amount = amount.minus(new bignumber_1.default(vout.value));
969
- }
970
- }
971
- }
972
- // deduct fee from amount
973
- amount = amount.minus(new bignumber_1.default(transaction.fees));
974
- airGapTransaction = {
975
- hash: transaction.txid,
976
- from: tempAirGapTransactionFrom,
977
- to: tempAirGapTransactionTo,
978
- isInbound: tempAirGapTransactionIsInbound,
979
- amount: amount.toString(10),
980
- fee: new bignumber_1.default(transaction.fees).toString(10),
981
- blockHeight: transaction.blockHeight.toString(),
982
- protocolIdentifier: this.identifier,
983
- network: this.options.network,
984
- timestamp: transaction.blockTime
985
- };
986
- airGapTransactions.push(airGapTransaction);
987
- }
604
+ // If receiving address is not ours, and transaction isbound => senders change
605
+ if (!this.containsSome(vout.addresses, addresses) && tempAirGapTransactionIsInbound) {
606
+ amount = amount.minus(new bignumber_1.default(vout.value));
988
607
  }
989
- return [2 /*return*/, {
990
- transactions: airGapTransactions,
991
- cursor: {
992
- page: cursor ? cursor.page + 1 : 2
993
- }
994
- }];
608
+ }
995
609
  }
996
- });
997
- });
998
- };
999
- BitcoinProtocol.prototype.containsSome = function (needles, haystack) {
1000
- for (var _i = 0, needles_1 = needles; _i < needles_1.length; _i++) {
1001
- var needle = needles_1[_i];
610
+ // deduct fee from amount
611
+ amount = amount.minus(new bignumber_1.default(transaction.fees));
612
+ const airGapTransaction = {
613
+ hash: transaction.txid,
614
+ from: tempAirGapTransactionFrom,
615
+ to: tempAirGapTransactionTo,
616
+ isInbound: tempAirGapTransactionIsInbound,
617
+ amount: amount.toString(10),
618
+ fee: new bignumber_1.default(transaction.fees).toString(10),
619
+ blockHeight: transaction.blockHeight.toString(),
620
+ protocolIdentifier: this.identifier,
621
+ network: this.options.network,
622
+ timestamp: transaction.blockTime
623
+ };
624
+ airGapTransactions.push(airGapTransaction);
625
+ }
626
+ }
627
+ return {
628
+ transactions: airGapTransactions,
629
+ cursor: {
630
+ page: cursor ? cursor.page + 1 : 2
631
+ }
632
+ };
633
+ }
634
+ containsSome(needles, haystack) {
635
+ for (const needle of needles) {
1002
636
  if (haystack.indexOf(needle) > -1) {
1003
637
  return true;
1004
638
  }
1005
639
  }
1006
640
  return false;
1007
- };
1008
- BitcoinProtocol.prototype.signMessage = function (message, keypair) {
1009
- return __awaiter(this, void 0, void 0, function () {
1010
- return __generator(this, function (_a) {
1011
- return [2 /*return*/, this.cryptoClient.signMessage(message, keypair)];
1012
- });
1013
- });
1014
- };
1015
- BitcoinProtocol.prototype.verifyMessage = function (message, signature, publicKey) {
1016
- return __awaiter(this, void 0, void 0, function () {
1017
- return __generator(this, function (_a) {
1018
- return [2 /*return*/, this.cryptoClient.verifyMessage(message, signature, publicKey)];
1019
- });
1020
- });
1021
- };
1022
- BitcoinProtocol.prototype.encryptAsymmetric = function (message, publicKey) {
1023
- return __awaiter(this, void 0, void 0, function () {
1024
- var childPublicKey;
1025
- return __generator(this, function (_a) {
1026
- childPublicKey = this.options.config.bitcoinJSLib.HDNode.fromBase58(publicKey, this.options.network.extras.network)
1027
- .derive(0)
1028
- .derive(0)
1029
- .getPublicKeyBuffer();
1030
- return [2 /*return*/, this.cryptoClient.encryptAsymmetric(message, childPublicKey)];
1031
- });
1032
- });
1033
- };
1034
- BitcoinProtocol.prototype.decryptAsymmetric = function (message, keypair) {
1035
- return __awaiter(this, void 0, void 0, function () {
1036
- var childPrivateKey;
1037
- return __generator(this, function (_a) {
1038
- childPrivateKey = this.options.config.bitcoinJSLib.HDNode.fromBase58(keypair.privateKey, this.options.network.extras.network)
1039
- .derive(0)
1040
- .derive(0)
1041
- .keyPair.d.toBuffer(32);
1042
- return [2 /*return*/, this.cryptoClient.decryptAsymmetric(message, { publicKey: '', privateKey: childPrivateKey.toString('hex') })];
1043
- });
1044
- });
1045
- };
1046
- BitcoinProtocol.prototype.encryptAES = function (message, privateKey) {
1047
- return __awaiter(this, void 0, void 0, function () {
1048
- return __generator(this, function (_a) {
1049
- return [2 /*return*/, this.cryptoClient.encryptAES(message, privateKey)];
1050
- });
1051
- });
1052
- };
1053
- BitcoinProtocol.prototype.decryptAES = function (message, privateKey) {
1054
- return __awaiter(this, void 0, void 0, function () {
1055
- return __generator(this, function (_a) {
1056
- return [2 /*return*/, this.cryptoClient.decryptAES(message, privateKey)];
1057
- });
1058
- });
1059
- };
1060
- BitcoinProtocol.prototype.getTransactionStatuses = function (transactionHashes) {
1061
- return __awaiter(this, void 0, void 0, function () {
1062
- return __generator(this, function (_a) {
1063
- return [2 /*return*/, Promise.reject('Transaction status not implemented')];
1064
- });
1065
- });
1066
- };
1067
- return BitcoinProtocol;
1068
- }());
641
+ }
642
+ async signMessage(message, keypair) {
643
+ return this.cryptoClient.signMessage(message, keypair);
644
+ }
645
+ async verifyMessage(message, signature, publicKey) {
646
+ return this.cryptoClient.verifyMessage(message, signature, publicKey);
647
+ }
648
+ async encryptAsymmetric(message, publicKey) {
649
+ const childPublicKey = this.options.config.bitcoinJSLib.HDNode.fromBase58(publicKey, this.options.network.extras.network)
650
+ .derive(0)
651
+ .derive(0)
652
+ .getPublicKeyBuffer();
653
+ return this.cryptoClient.encryptAsymmetric(message, childPublicKey);
654
+ }
655
+ async decryptAsymmetric(message, keypair) {
656
+ const childPrivateKey = this.options.config.bitcoinJSLib.HDNode.fromBase58(keypair.privateKey, this.options.network.extras.network)
657
+ .derive(0)
658
+ .derive(0)
659
+ .keyPair.d.toBuffer(32);
660
+ return this.cryptoClient.decryptAsymmetric(message, { publicKey: '', privateKey: childPrivateKey.toString('hex') });
661
+ }
662
+ async encryptAES(message, privateKey) {
663
+ return this.cryptoClient.encryptAES(message, privateKey);
664
+ }
665
+ async decryptAES(message, privateKey) {
666
+ return this.cryptoClient.decryptAES(message, privateKey);
667
+ }
668
+ async getTransactionStatuses(transactionHashes) {
669
+ return Promise.reject('Transaction status not implemented');
670
+ }
671
+ }
1069
672
  exports.BitcoinProtocol = BitcoinProtocol;
1070
673
  //# sourceMappingURL=BitcoinProtocol.js.map