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

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 +9 -8
  5. package/v0/protocol/BitcoinAddress.js.map +1 -1
  6. package/v0/protocol/BitcoinCryptoClient.js +85 -16
  7. package/v0/protocol/BitcoinCryptoClient.js.map +1 -1
  8. package/v0/protocol/BitcoinProtocol.js +987 -590
  9. package/v0/protocol/BitcoinProtocol.js.map +1 -1
  10. package/v0/protocol/BitcoinProtocolOptions.js +111 -45
  11. package/v0/protocol/BitcoinProtocolOptions.js.map +1 -1
  12. package/v0/protocol/BitcoinSegwitAddress.js +29 -12
  13. package/v0/protocol/BitcoinSegwitAddress.js.map +1 -1
  14. package/v0/protocol/BitcoinSegwitProtocol.js +483 -348
  15. package/v0/protocol/BitcoinSegwitProtocol.js.map +1 -1
  16. package/v0/protocol/BitcoinTestnetProtocol.js +36 -28
  17. package/v0/protocol/BitcoinTestnetProtocol.js.map +1 -1
  18. package/v0/serializer/validators/transaction-validator.js +30 -22
  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 +61 -12
  23. package/v1/block-explorer/BlockCypherBlockExplorer.js.map +1 -1
  24. package/v1/data/BitcoinAddress.js +10 -9
  25. package/v1/data/BitcoinAddress.js.map +1 -1
  26. package/v1/data/BitcoinLegacyAddress.js +12 -11
  27. package/v1/data/BitcoinLegacyAddress.js.map +1 -1
  28. package/v1/data/BitcoinSegwitAddress.js +12 -11
  29. package/v1/data/BitcoinSegwitAddress.js.map +1 -1
  30. package/v1/data/BitcoinTaprootAddress.js +22 -31
  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 +102 -44
  36. package/v1/module/BitcoinModule.js.map +1 -1
  37. package/v1/module.js +3 -2
  38. package/v1/module.js.map +1 -1
  39. package/v1/protocol/BitcoinCryptoClient.js +90 -22
  40. package/v1/protocol/BitcoinCryptoClient.js.map +1 -1
  41. package/v1/protocol/BitcoinLegacyProtocol.js +796 -520
  42. package/v1/protocol/BitcoinLegacyProtocol.js.map +1 -1
  43. package/v1/protocol/BitcoinProtocol.js +1169 -735
  44. package/v1/protocol/BitcoinProtocol.js.map +1 -1
  45. package/v1/protocol/BitcoinSegwitProtocol.js +796 -542
  46. package/v1/protocol/BitcoinSegwitProtocol.js.map +1 -1
  47. package/v1/protocol/BitcoinTaprootProtocol.js +1000 -688
  48. package/v1/protocol/BitcoinTaprootProtocol.js.map +1 -1
  49. package/v1/protocol/BitcoinTestnetProtocol.js +33 -14
  50. package/v1/protocol/BitcoinTestnetProtocol.js.map +1 -1
  51. package/v1/serializer/v3/schemas/converter/transaction-converter.js +52 -29
  52. package/v1/serializer/v3/schemas/converter/transaction-converter.js.map +1 -1
  53. package/v1/serializer/v3/serializer-companion.js +165 -98
  54. package/v1/serializer/v3/serializer-companion.js.map +1 -1
  55. package/v1/serializer/v3/validators/transaction-validator.js +16 -13
  56. package/v1/serializer/v3/validators/transaction-validator.js.map +1 -1
  57. package/v1/serializer/v3/validators/validators.js +213 -122
  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 +6 -4
  64. package/v1/utils/common.js.map +1 -1
  65. package/v1/utils/key.d.ts +6 -5
  66. package/v1/utils/key.js +39 -38
  67. package/v1/utils/key.js.map +1 -1
  68. package/v1/utils/network.js +4 -3
  69. package/v1/utils/network.js.map +1 -1
  70. package/v1/utils/protocol.js +19 -25
  71. package/v1/utils/protocol.js.map +1 -1
  72. package/v1/utils/signature.js +5 -4
  73. package/v1/utils/signature.js.map +1 -1
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
14
  if (k2 === undefined) k2 = k;
4
15
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -15,48 +26,85 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
26
  }) : function(o, v) {
16
27
  o["default"] = v;
17
28
  });
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
- })();
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
+ return new (P || (P = Promise))(function (resolve, reject) {
39
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
42
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
43
+ });
44
+ };
45
+ var __generator = (this && this.__generator) || function (thisArg, body) {
46
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
47
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
48
+ function verb(n) { return function (v) { return step([n, v]); }; }
49
+ function step(op) {
50
+ if (f) throw new TypeError("Generator is already executing.");
51
+ while (_) try {
52
+ 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;
53
+ if (y = 0, t) op = [op[0] & 2, t.value];
54
+ switch (op[0]) {
55
+ case 0: case 1: t = op; break;
56
+ case 4: _.label++; return { value: op[1], done: false };
57
+ case 5: _.label++; y = op[1]; op = [0]; continue;
58
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
59
+ default:
60
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
61
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
62
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
63
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
64
+ if (t[2]) _.ops.pop();
65
+ _.trys.pop(); continue;
66
+ }
67
+ op = body.call(thisArg, _);
68
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
69
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
70
+ }
71
+ };
72
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
73
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
74
+ if (ar || !(i in from)) {
75
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
76
+ ar[i] = from[i];
77
+ }
78
+ }
79
+ return to.concat(ar || Array.prototype.slice.call(from));
80
+ };
35
81
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
82
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
83
  };
38
84
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.BitcoinTaprootProtocolImpl = void 0;
40
- exports.createBitcoinTaprootProtocol = createBitcoinTaprootProtocol;
41
- const coinlib_core_1 = require("@airgap/coinlib-core");
42
- const index_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/axios-0.19.0/index"));
43
- const bignumber_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
44
- const errors_1 = require("@airgap/coinlib-core/errors");
45
- const module_kit_1 = require("@airgap/module-kit");
46
- const bitcoin = __importStar(require("bitcoinjs-lib"));
47
- const BitcoinTaprootAddress_1 = require("../data/BitcoinTaprootAddress");
48
- const common_1 = require("../utils/common");
49
- const key_1 = require("../utils/key");
50
- const network_1 = require("../utils/network");
51
- const BitcoinProtocol_1 = require("./BitcoinProtocol");
52
- const bip32_1 = require("bip32");
53
- const BitcoinSegwitProtocol_1 = require("./BitcoinSegwitProtocol");
54
- const crypto_1 = require("@airgap/crypto");
55
- const secp256k1_1 = __importDefault(require("@bitcoinerlab/secp256k1"));
85
+ exports.createBitcoinTaprootProtocol = exports.BitcoinTaprootProtocolImpl = void 0;
86
+ var coinlib_core_1 = require("@airgap/coinlib-core");
87
+ var index_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/axios-0.19.0/index"));
88
+ var bignumber_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
89
+ var errors_1 = require("@airgap/coinlib-core/errors");
90
+ var module_kit_1 = require("@airgap/module-kit");
91
+ var bitcoin = __importStar(require("bitcoinjs-lib"));
92
+ var BitcoinTaprootAddress_1 = require("../data/BitcoinTaprootAddress");
93
+ var common_1 = require("../utils/common");
94
+ var key_1 = require("../utils/key");
95
+ var network_1 = require("../utils/network");
96
+ var BitcoinProtocol_1 = require("./BitcoinProtocol");
97
+ var bip32_1 = require("bip32");
98
+ var BitcoinSegwitProtocol_1 = require("./BitcoinSegwitProtocol");
99
+ var crypto_1 = require("@airgap/crypto");
100
+ var secp256k1_1 = __importDefault(require("@bitcoinerlab/secp256k1"));
56
101
  // Implementation
57
- const DUST_AMOUNT = 50;
58
- class BitcoinTaprootProtocolImpl {
59
- constructor(options = {}, bitcoinJS = bitcoin) {
102
+ var DUST_AMOUNT = 50;
103
+ var BitcoinTaprootProtocolImpl = /** @class */ (function () {
104
+ function BitcoinTaprootProtocolImpl(options, bitcoinJS) {
105
+ if (options === void 0) { options = {}; }
106
+ if (bitcoinJS === void 0) { bitcoinJS = bitcoin; }
107
+ var _a, _b, _c;
60
108
  this._isBitcoinProtocol = true;
61
109
  this._isBitcoinTaprootProtocol = true;
62
110
  this.bip32 = (0, bip32_1.BIP32Factory)(secp256k1_1.default);
@@ -69,82 +117,107 @@ class BitcoinTaprootProtocolImpl {
69
117
  };
70
118
  this.bitcoinJS.lib.initEccLib(secp256k1_1.default);
71
119
  this.segwit = new BitcoinSegwitProtocol_1.BitcoinSegwitProtocolImpl(options);
72
- this.metadata = {
73
- ...this.segwit.legacy.metadata,
74
- identifier: coinlib_core_1.MainProtocolSymbols.BTC_TAPROOT,
75
- name: 'Bitcoin (Taproot)',
76
- account: {
77
- ...(this.segwit.legacy.metadata.account ?? {}),
78
- standardDerivationPath: `m/86'/0'/0'`,
79
- address: {
80
- ...(this.segwit.legacy.metadata.account?.address ?? {}),
81
- regex: '^(?:[13]{1}[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$'
82
- }
83
- }
84
- };
85
- }
86
- async prepareTransactionWithPublicKey(publicKey, details, configuration) {
87
- switch (publicKey.type) {
88
- case 'pub':
89
- return this.prepareTransactionWithNonExtendedPublicKey(publicKey, details, configuration);
90
- case 'xpub':
91
- return this.prepareTransactionWithExtendedPublicKey(publicKey, details, configuration);
92
- default:
93
- (0, coinlib_core_1.assertNever)(publicKey);
94
- throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Unsupported public key type.');
95
- }
96
- }
97
- async prepareTransactionWithNonExtendedPublicKey(publicKey, details, configuration) {
98
- throw new Error('Method not implemented.');
99
- }
100
- async getCryptoConfiguration() {
101
- return this.segwit.getCryptoConfiguration();
102
- }
103
- async getKeyPairFromDerivative(derivative) {
104
- return this.segwit.getKeyPairFromDerivative(derivative);
120
+ this.metadata = __assign(__assign({}, this.segwit.legacy.metadata), { identifier: coinlib_core_1.MainProtocolSymbols.BTC_TAPROOT, name: 'Bitcoin (Taproot)', account: __assign(__assign({}, ((_a = this.segwit.legacy.metadata.account) !== null && _a !== void 0 ? _a : {})), { standardDerivationPath: "m/86'/0'/0'", address: __assign(__assign({}, ((_c = (_b = this.segwit.legacy.metadata.account) === null || _b === void 0 ? void 0 : _b.address) !== null && _c !== void 0 ? _c : {})), { regex: '^(?:[13]{1}[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$' }) }) });
105
121
  }
106
- async signTransactionWithSecretKey(transaction, secretKey) {
107
- switch (secretKey.type) {
108
- case 'priv':
109
- return this.signTransactionWithNonExtendedSecretKey(transaction, secretKey);
110
- case 'xpriv':
111
- return this.signTransactionWithExtendedSecretKey(transaction, secretKey);
112
- default:
113
- (0, coinlib_core_1.assertNever)(secretKey);
114
- throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Secret key type not supported.');
115
- }
116
- }
117
- async signTransactionWithExtendedSecretKey(transaction, secretKey) {
118
- const encodedExtendedSecretKey = (0, key_1.convertExtendedSecretKey)(secretKey, { format: 'encoded', type: 'xprv' });
119
- const bip32 = this.bip32.fromBase58(encodedExtendedSecretKey.value);
120
- const decodedPSBT = this.bitcoinJS.lib.Psbt.fromHex(transaction.psbt);
121
- decodedPSBT.data.inputs.forEach((input, index) => {
122
- input.tapBip32Derivation?.forEach((deriv) => {
123
- try {
124
- const cutoffFrom = deriv.path.lastIndexOf("'") || deriv.path.lastIndexOf('h');
125
- const childPath = deriv.path.substr(cutoffFrom + 2);
126
- const childNode = bip32.derivePath(childPath);
127
- const tweakedChildNode = childNode.tweak(this.bitcoinJS.lib.crypto.taggedHash('TapTweak', Buffer.from(childNode.publicKey.subarray(1, 33))));
128
- decodedPSBT.signInput(index, {
129
- publicKey: Buffer.from(tweakedChildNode.publicKey),
130
- sign: (hash, lowR) => Buffer.from(tweakedChildNode.sign(hash, lowR)),
131
- signSchnorr: (hash) => Buffer.from(tweakedChildNode.signSchnorr(hash))
132
- });
122
+ BitcoinTaprootProtocolImpl.prototype.prepareTransactionWithPublicKey = function (publicKey, details, configuration) {
123
+ return __awaiter(this, void 0, void 0, function () {
124
+ return __generator(this, function (_a) {
125
+ switch (publicKey.type) {
126
+ case 'pub':
127
+ return [2 /*return*/, this.prepareTransactionWithNonExtendedPublicKey(publicKey, details, configuration)];
128
+ case 'xpub':
129
+ return [2 /*return*/, this.prepareTransactionWithExtendedPublicKey(publicKey, details, configuration)];
130
+ default:
131
+ (0, coinlib_core_1.assertNever)(publicKey);
132
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Unsupported public key type.');
133
133
  }
134
- catch (e) {
135
- throw new Error(`Error signing index #${index}`);
134
+ return [2 /*return*/];
135
+ });
136
+ });
137
+ };
138
+ BitcoinTaprootProtocolImpl.prototype.prepareTransactionWithNonExtendedPublicKey = function (publicKey, details, configuration) {
139
+ return __awaiter(this, void 0, void 0, function () {
140
+ return __generator(this, function (_a) {
141
+ throw new Error('Method not implemented.');
142
+ });
143
+ });
144
+ };
145
+ BitcoinTaprootProtocolImpl.prototype.getCryptoConfiguration = function () {
146
+ return __awaiter(this, void 0, void 0, function () {
147
+ return __generator(this, function (_a) {
148
+ return [2 /*return*/, this.segwit.getCryptoConfiguration()];
149
+ });
150
+ });
151
+ };
152
+ BitcoinTaprootProtocolImpl.prototype.getKeyPairFromDerivative = function (derivative) {
153
+ return __awaiter(this, void 0, void 0, function () {
154
+ return __generator(this, function (_a) {
155
+ return [2 /*return*/, this.segwit.getKeyPairFromDerivative(derivative)];
156
+ });
157
+ });
158
+ };
159
+ BitcoinTaprootProtocolImpl.prototype.signTransactionWithSecretKey = function (transaction, secretKey) {
160
+ return __awaiter(this, void 0, void 0, function () {
161
+ return __generator(this, function (_a) {
162
+ switch (secretKey.type) {
163
+ case 'priv':
164
+ return [2 /*return*/, this.signTransactionWithNonExtendedSecretKey(transaction, secretKey)];
165
+ case 'xpriv':
166
+ return [2 /*return*/, this.signTransactionWithExtendedSecretKey(transaction, secretKey)];
167
+ default:
168
+ (0, coinlib_core_1.assertNever)(secretKey);
169
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Secret key type not supported.');
136
170
  }
171
+ return [2 /*return*/];
137
172
  });
138
173
  });
139
- return (0, module_kit_1.newSignedTransaction)({ psbt: decodedPSBT.toHex() });
140
- }
141
- async signTransactionWithNonExtendedSecretKey(transaction, secretKey) {
142
- throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Sign with non extended secret key not supported (Taproot).');
143
- }
144
- async getMetadata() {
145
- return this.metadata;
146
- }
147
- getAddressFromPublicKey(publicKey) {
174
+ };
175
+ BitcoinTaprootProtocolImpl.prototype.signTransactionWithExtendedSecretKey = function (transaction, secretKey) {
176
+ return __awaiter(this, void 0, void 0, function () {
177
+ var encodedExtendedSecretKey, bip32, decodedPSBT;
178
+ var _this = this;
179
+ return __generator(this, function (_a) {
180
+ encodedExtendedSecretKey = (0, key_1.convertExtendedSecretKey)(secretKey, { format: 'encoded', type: 'xprv' });
181
+ bip32 = this.bip32.fromBase58(encodedExtendedSecretKey.value);
182
+ decodedPSBT = this.bitcoinJS.lib.Psbt.fromHex(transaction.psbt);
183
+ decodedPSBT.data.inputs.forEach(function (input, index) {
184
+ var _a;
185
+ (_a = input.tapBip32Derivation) === null || _a === void 0 ? void 0 : _a.forEach(function (deriv) {
186
+ try {
187
+ var cutoffFrom = deriv.path.lastIndexOf("'") || deriv.path.lastIndexOf('h');
188
+ var childPath = deriv.path.substr(cutoffFrom + 2);
189
+ var childNode = bip32.derivePath(childPath);
190
+ var tweakedChildNode_1 = childNode.tweak(_this.bitcoinJS.lib.crypto.taggedHash('TapTweak', Buffer.from(childNode.publicKey.subarray(1, 33))));
191
+ decodedPSBT.signInput(index, {
192
+ publicKey: Buffer.from(tweakedChildNode_1.publicKey),
193
+ sign: function (hash, lowR) { return Buffer.from(tweakedChildNode_1.sign(hash, lowR)); },
194
+ signSchnorr: function (hash) { return Buffer.from(tweakedChildNode_1.signSchnorr(hash)); }
195
+ });
196
+ }
197
+ catch (e) {
198
+ throw new Error("Error signing index #".concat(index));
199
+ }
200
+ });
201
+ });
202
+ return [2 /*return*/, (0, module_kit_1.newSignedTransaction)({ psbt: decodedPSBT.toHex() })];
203
+ });
204
+ });
205
+ };
206
+ BitcoinTaprootProtocolImpl.prototype.signTransactionWithNonExtendedSecretKey = function (transaction, secretKey) {
207
+ return __awaiter(this, void 0, void 0, function () {
208
+ return __generator(this, function (_a) {
209
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Sign with non extended secret key not supported (Taproot).');
210
+ });
211
+ });
212
+ };
213
+ BitcoinTaprootProtocolImpl.prototype.getMetadata = function () {
214
+ return __awaiter(this, void 0, void 0, function () {
215
+ return __generator(this, function (_a) {
216
+ return [2 /*return*/, this.metadata];
217
+ });
218
+ });
219
+ };
220
+ BitcoinTaprootProtocolImpl.prototype.getAddressFromPublicKey = function (publicKey) {
148
221
  switch (publicKey.type) {
149
222
  case 'pub':
150
223
  return this.getAddressFromNonExtendedPublicKey(publicKey);
@@ -154,614 +227,853 @@ class BitcoinTaprootProtocolImpl {
154
227
  (0, coinlib_core_1.assertNever)(publicKey);
155
228
  throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Public key type is not supported.');
156
229
  }
157
- }
158
- async getAddressFromExtendedPublicKey(extendedPublicKey) {
159
- const encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
160
- const payment = this.bitcoinJS.lib.payments.p2tr({
161
- internalPubkey: Buffer.from(encodedExtendedPublicKey.value, 'hex').subarray(1, 33),
162
- network: this.bitcoinJS.config.network
230
+ };
231
+ BitcoinTaprootProtocolImpl.prototype.getAddressFromExtendedPublicKey = function (extendedPublicKey) {
232
+ return __awaiter(this, void 0, void 0, function () {
233
+ var encodedExtendedPublicKey, payment;
234
+ return __generator(this, function (_a) {
235
+ encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
236
+ payment = this.bitcoinJS.lib.payments.p2tr({
237
+ internalPubkey: Buffer.from(encodedExtendedPublicKey.value, 'hex').subarray(1, 33),
238
+ network: this.bitcoinJS.config.network
239
+ });
240
+ return [2 /*return*/, BitcoinTaprootAddress_1.BitcoinTaprootAddress.fromPayment(payment).asString()];
241
+ });
163
242
  });
164
- return BitcoinTaprootAddress_1.BitcoinTaprootAddress.fromPayment(payment).asString();
165
- }
166
- async getDetailsFromTransaction(transaction, _publicKey) {
167
- return this.getDetailsFromPSBT(transaction.psbt, _publicKey);
168
- }
169
- async getDetailsFromPSBT(psbt, publicKey) {
170
- const decodedPSBT = this.bitcoinJS.lib.Psbt.fromHex(psbt);
171
- let fee = new bignumber_1.default(0);
172
- for (const txIn of decodedPSBT.data.inputs) {
173
- fee = fee.plus(new bignumber_1.default(txIn.witnessUtxo?.value ?? 0));
174
- }
175
- for (const txOut of decodedPSBT.txOutputs) {
176
- fee = fee.minus(new bignumber_1.default(txOut.value));
177
- }
178
- const alerts = [];
179
- const clonedPSBT = decodedPSBT.clone();
180
- (0, common_1.eachRecursive)(clonedPSBT); // Convert all buffers to hex strings
181
- const amount = (() => {
182
- if (decodedPSBT.txOutputs.length === 1) {
183
- return new bignumber_1.default(decodedPSBT.txOutputs[0].value);
184
- }
185
- const unknownKeyVals = decodedPSBT.data.globalMap.unknownKeyVals;
186
- if (unknownKeyVals) {
187
- const amountArray = unknownKeyVals.filter((kv) => kv.key.equals(Buffer.from('amount')));
188
- if (amountArray.length > 0) {
189
- return new bignumber_1.default(amountArray[0].value.toString());
190
- }
191
- }
192
- let accumulated = new bignumber_1.default(0);
193
- let useAccumulated = false;
194
- decodedPSBT.data.outputs.forEach((outputKeyValues, index) => {
195
- if (outputKeyValues.unknownKeyVals) {
196
- const derivationPaths = outputKeyValues.unknownKeyVals
197
- .filter((kv) => kv.key.equals(Buffer.from('dp')))
198
- .map((kv) => kv.value.toString());
199
- if (derivationPaths.length > 0) {
200
- useAccumulated = true;
201
- return;
202
- }
203
- }
204
- const output = decodedPSBT.txOutputs[index];
205
- accumulated = accumulated.plus(output.value);
243
+ };
244
+ BitcoinTaprootProtocolImpl.prototype.getDetailsFromTransaction = function (transaction, _publicKey) {
245
+ return __awaiter(this, void 0, void 0, function () {
246
+ return __generator(this, function (_a) {
247
+ return [2 /*return*/, this.getDetailsFromPSBT(transaction.psbt, _publicKey)];
206
248
  });
207
- if (useAccumulated) {
208
- return accumulated;
209
- }
210
- return decodedPSBT.txOutputs
211
- .map((obj) => new bignumber_1.default(obj.value))
212
- .reduce((accumulator, currentValue) => accumulator.plus(currentValue));
213
- })();
214
- const changeAddressDatas = await Promise.all(decodedPSBT.data.outputs.map(async (obj, index) => {
215
- let isChangeAddress = false;
216
- let isOwned = false;
217
- let addressIndex = 0;
218
- const address = decodedPSBT.txOutputs[index].address;
219
- const amount = decodedPSBT.txOutputs[index].value;
220
- let ourGeneratedAddress;
221
- if (obj.bip32Derivation) {
222
- isChangeAddress = true;
223
- const getIndexes = obj.bip32Derivation[0].path.split('/');
224
- if (publicKey.type === 'xpub') {
225
- const ourPublickey = await this.deriveFromExtendedPublicKey(publicKey, 1, +getIndexes[getIndexes.length - 1]);
226
- ourGeneratedAddress = await this.getAddressFromPublicKey(ourPublickey);
227
- }
228
- else {
229
- ourGeneratedAddress = await this.getAddressFromNonExtendedPublicKey(publicKey);
230
- }
231
- if (ourGeneratedAddress === address) {
232
- isOwned = true;
233
- addressIndex = +getIndexes[getIndexes.length - 1];
234
- }
235
- for (let x = 0; x < 1000; x++) {
236
- const ourPublickey = await this.deriveFromExtendedPublicKey(publicKey, 1, x);
237
- ourGeneratedAddress = await this.getAddressFromPublicKey(ourPublickey);
238
- if (ourGeneratedAddress === address) {
239
- isOwned = true;
240
- addressIndex = x;
241
- break;
242
- }
243
- }
244
- }
245
- else if (obj.tapBip32Derivation) {
246
- isChangeAddress = true;
247
- const getIndexes = obj.tapBip32Derivation[0].path.split('/');
248
- if (publicKey.type === 'xpub') {
249
- const ourPublickey = await this.deriveFromExtendedPublicKey(publicKey, 1, +getIndexes[getIndexes.length - 1]);
250
- ourGeneratedAddress = await this.getAddressFromPublicKey(ourPublickey);
251
- }
252
- else {
253
- ourGeneratedAddress = await this.getAddressFromNonExtendedPublicKey(publicKey);
254
- }
255
- if (ourGeneratedAddress === address) {
256
- isOwned = true;
257
- addressIndex = +getIndexes[getIndexes.length - 1];
258
- }
259
- for (let x = 0; x < 1000; x++) {
260
- const ourPublickey = await this.deriveFromExtendedPublicKey(publicKey, 1, x);
261
- ourGeneratedAddress = await this.getAddressFromPublicKey(ourPublickey);
262
- if (ourGeneratedAddress === address) {
263
- isOwned = true;
264
- addressIndex = x;
265
- break;
266
- }
267
- }
268
- }
269
- else if (obj.unknownKeyVals) {
270
- for (let x = 0; x < 1000; x++) {
271
- isChangeAddress = true;
272
- const ourPublickey = await this.deriveFromExtendedPublicKey(publicKey, 1, x);
273
- ourGeneratedAddress = await this.getAddressFromPublicKey(ourPublickey);
274
- if (ourGeneratedAddress === address) {
275
- isOwned = true;
276
- addressIndex = x;
277
- break;
278
- }
279
- }
280
- }
281
- if (isChangeAddress && isOwned) {
282
- alerts.push({
283
- type: 'success',
284
- title: { type: 'plain', value: '' },
285
- description: { type: 'plain', value: 'Note: your change address has been verified' },
286
- icon: undefined,
287
- actions: undefined
288
- });
289
- }
290
- else if (isChangeAddress && !isOwned) {
291
- alerts.push({
292
- type: 'warning',
293
- title: { type: 'plain', value: '' },
294
- description: { type: 'plain', value: 'Note: your change address has not been verified' },
295
- icon: undefined,
296
- actions: undefined
297
- });
298
- }
299
- return [
300
- address,
301
- {
302
- isChangeAddress,
303
- isOwned,
304
- path: addressIndex === 0 ? '' : `m/86'/0'/0'/1/${addressIndex}`,
305
- amount
249
+ });
250
+ };
251
+ BitcoinTaprootProtocolImpl.prototype.getDetailsFromPSBT = function (psbt, publicKey) {
252
+ var _a, _b;
253
+ return __awaiter(this, void 0, void 0, function () {
254
+ var decodedPSBT, fee, _i, _c, txIn, _d, _e, txOut, alerts, clonedPSBT, amount, changeAddressDatas, changeAddressInfo;
255
+ var _this = this;
256
+ return __generator(this, function (_f) {
257
+ switch (_f.label) {
258
+ case 0:
259
+ decodedPSBT = this.bitcoinJS.lib.Psbt.fromHex(psbt);
260
+ fee = new bignumber_1.default(0);
261
+ for (_i = 0, _c = decodedPSBT.data.inputs; _i < _c.length; _i++) {
262
+ txIn = _c[_i];
263
+ fee = fee.plus(new bignumber_1.default((_b = (_a = txIn.witnessUtxo) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 0));
264
+ }
265
+ for (_d = 0, _e = decodedPSBT.txOutputs; _d < _e.length; _d++) {
266
+ txOut = _e[_d];
267
+ fee = fee.minus(new bignumber_1.default(txOut.value));
268
+ }
269
+ alerts = [];
270
+ clonedPSBT = decodedPSBT.clone();
271
+ (0, common_1.eachRecursive)(clonedPSBT); // Convert all buffers to hex strings
272
+ amount = (function () {
273
+ if (decodedPSBT.txOutputs.length === 1) {
274
+ return new bignumber_1.default(decodedPSBT.txOutputs[0].value);
275
+ }
276
+ var unknownKeyVals = decodedPSBT.data.globalMap.unknownKeyVals;
277
+ if (unknownKeyVals) {
278
+ var amountArray = unknownKeyVals.filter(function (kv) { return kv.key.equals(Buffer.from('amount')); });
279
+ if (amountArray.length > 0) {
280
+ return new bignumber_1.default(amountArray[0].value.toString());
281
+ }
282
+ }
283
+ var accumulated = new bignumber_1.default(0);
284
+ var useAccumulated = false;
285
+ decodedPSBT.data.outputs.forEach(function (outputKeyValues, index) {
286
+ if (outputKeyValues.unknownKeyVals) {
287
+ var derivationPaths = outputKeyValues.unknownKeyVals
288
+ .filter(function (kv) { return kv.key.equals(Buffer.from('dp')); })
289
+ .map(function (kv) { return kv.value.toString(); });
290
+ if (derivationPaths.length > 0) {
291
+ useAccumulated = true;
292
+ return;
293
+ }
294
+ }
295
+ var output = decodedPSBT.txOutputs[index];
296
+ accumulated = accumulated.plus(output.value);
297
+ });
298
+ if (useAccumulated) {
299
+ return accumulated;
300
+ }
301
+ return decodedPSBT.txOutputs
302
+ .map(function (obj) { return new bignumber_1.default(obj.value); })
303
+ .reduce(function (accumulator, currentValue) { return accumulator.plus(currentValue); });
304
+ })();
305
+ return [4 /*yield*/, Promise.all(decodedPSBT.data.outputs.map(function (obj, index) { return __awaiter(_this, void 0, void 0, function () {
306
+ var isChangeAddress, isOwned, addressIndex, address, amount, ourGeneratedAddress, getIndexes, ourPublickey, x, ourPublickey, getIndexes, ourPublickey, x, ourPublickey, x, ourPublickey;
307
+ return __generator(this, function (_a) {
308
+ switch (_a.label) {
309
+ case 0:
310
+ isChangeAddress = false;
311
+ isOwned = false;
312
+ addressIndex = 0;
313
+ address = decodedPSBT.txOutputs[index].address;
314
+ amount = decodedPSBT.txOutputs[index].value;
315
+ if (!obj.bip32Derivation) return [3 /*break*/, 11];
316
+ isChangeAddress = true;
317
+ getIndexes = obj.bip32Derivation[0].path.split('/');
318
+ if (!(publicKey.type === 'xpub')) return [3 /*break*/, 3];
319
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(publicKey, 1, +getIndexes[getIndexes.length - 1])];
320
+ case 1:
321
+ ourPublickey = _a.sent();
322
+ return [4 /*yield*/, this.getAddressFromPublicKey(ourPublickey)];
323
+ case 2:
324
+ ourGeneratedAddress = _a.sent();
325
+ return [3 /*break*/, 5];
326
+ case 3: return [4 /*yield*/, this.getAddressFromNonExtendedPublicKey(publicKey)];
327
+ case 4:
328
+ ourGeneratedAddress = _a.sent();
329
+ _a.label = 5;
330
+ case 5:
331
+ if (ourGeneratedAddress === address) {
332
+ isOwned = true;
333
+ addressIndex = +getIndexes[getIndexes.length - 1];
334
+ }
335
+ x = 0;
336
+ _a.label = 6;
337
+ case 6:
338
+ if (!(x < 1000)) return [3 /*break*/, 10];
339
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(publicKey, 1, x)];
340
+ case 7:
341
+ ourPublickey = _a.sent();
342
+ return [4 /*yield*/, this.getAddressFromPublicKey(ourPublickey)];
343
+ case 8:
344
+ ourGeneratedAddress = _a.sent();
345
+ if (ourGeneratedAddress === address) {
346
+ isOwned = true;
347
+ addressIndex = x;
348
+ return [3 /*break*/, 10];
349
+ }
350
+ _a.label = 9;
351
+ case 9:
352
+ x++;
353
+ return [3 /*break*/, 6];
354
+ case 10: return [3 /*break*/, 27];
355
+ case 11:
356
+ if (!obj.tapBip32Derivation) return [3 /*break*/, 22];
357
+ isChangeAddress = true;
358
+ getIndexes = obj.tapBip32Derivation[0].path.split('/');
359
+ if (!(publicKey.type === 'xpub')) return [3 /*break*/, 14];
360
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(publicKey, 1, +getIndexes[getIndexes.length - 1])];
361
+ case 12:
362
+ ourPublickey = _a.sent();
363
+ return [4 /*yield*/, this.getAddressFromPublicKey(ourPublickey)];
364
+ case 13:
365
+ ourGeneratedAddress = _a.sent();
366
+ return [3 /*break*/, 16];
367
+ case 14: return [4 /*yield*/, this.getAddressFromNonExtendedPublicKey(publicKey)];
368
+ case 15:
369
+ ourGeneratedAddress = _a.sent();
370
+ _a.label = 16;
371
+ case 16:
372
+ if (ourGeneratedAddress === address) {
373
+ isOwned = true;
374
+ addressIndex = +getIndexes[getIndexes.length - 1];
375
+ }
376
+ x = 0;
377
+ _a.label = 17;
378
+ case 17:
379
+ if (!(x < 1000)) return [3 /*break*/, 21];
380
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(publicKey, 1, x)];
381
+ case 18:
382
+ ourPublickey = _a.sent();
383
+ return [4 /*yield*/, this.getAddressFromPublicKey(ourPublickey)];
384
+ case 19:
385
+ ourGeneratedAddress = _a.sent();
386
+ if (ourGeneratedAddress === address) {
387
+ isOwned = true;
388
+ addressIndex = x;
389
+ return [3 /*break*/, 21];
390
+ }
391
+ _a.label = 20;
392
+ case 20:
393
+ x++;
394
+ return [3 /*break*/, 17];
395
+ case 21: return [3 /*break*/, 27];
396
+ case 22:
397
+ if (!obj.unknownKeyVals) return [3 /*break*/, 27];
398
+ x = 0;
399
+ _a.label = 23;
400
+ case 23:
401
+ if (!(x < 1000)) return [3 /*break*/, 27];
402
+ isChangeAddress = true;
403
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(publicKey, 1, x)];
404
+ case 24:
405
+ ourPublickey = _a.sent();
406
+ return [4 /*yield*/, this.getAddressFromPublicKey(ourPublickey)];
407
+ case 25:
408
+ ourGeneratedAddress = _a.sent();
409
+ if (ourGeneratedAddress === address) {
410
+ isOwned = true;
411
+ addressIndex = x;
412
+ return [3 /*break*/, 27];
413
+ }
414
+ _a.label = 26;
415
+ case 26:
416
+ x++;
417
+ return [3 /*break*/, 23];
418
+ case 27:
419
+ if (isChangeAddress && isOwned) {
420
+ alerts.push({
421
+ type: 'success',
422
+ title: { type: 'plain', value: '' },
423
+ description: { type: 'plain', value: 'Note: your change address has been verified' },
424
+ icon: undefined,
425
+ actions: undefined
426
+ });
427
+ }
428
+ else if (isChangeAddress && !isOwned) {
429
+ alerts.push({
430
+ type: 'warning',
431
+ title: { type: 'plain', value: '' },
432
+ description: { type: 'plain', value: 'Note: your change address has not been verified' },
433
+ icon: undefined,
434
+ actions: undefined
435
+ });
436
+ }
437
+ return [2 /*return*/, [
438
+ address,
439
+ {
440
+ isChangeAddress: isChangeAddress,
441
+ isOwned: isOwned,
442
+ path: addressIndex === 0 ? '' : "m/86'/0'/0'/1/".concat(addressIndex),
443
+ amount: amount
444
+ }
445
+ ]];
446
+ }
447
+ });
448
+ }); }))];
449
+ case 1:
450
+ changeAddressDatas = _f.sent();
451
+ changeAddressInfo = {};
452
+ changeAddressDatas.forEach(function (changeAddressData) {
453
+ changeAddressInfo[changeAddressData[0]] = changeAddressData[1];
454
+ });
455
+ return [2 /*return*/, [
456
+ {
457
+ from: decodedPSBT.data.inputs.map(function (obj) {
458
+ var _a, _b;
459
+ return (_b = (_a = obj.tapBip32Derivation) === null || _a === void 0 ? void 0 : _a.map(function (el) {
460
+ return _this.bitcoinJS.lib.payments.p2tr({
461
+ internalPubkey: el.pubkey,
462
+ network: _this.bitcoinJS.lib.networks.bitcoin
463
+ }).address;
464
+ }).join(' ')) !== null && _b !== void 0 ? _b : 'INVALID';
465
+ }),
466
+ to: decodedPSBT.txOutputs.map(function (obj) {
467
+ return obj.address || "Script: ".concat(obj.script.toString('hex')) || 'unknown';
468
+ }),
469
+ isInbound: false,
470
+ amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
471
+ fee: (0, module_kit_1.newAmount)(fee, 'blockchain'),
472
+ network: this.options.network,
473
+ changeAddressInfo: changeAddressInfo,
474
+ uiAlerts: alerts,
475
+ json: {
476
+ inputTx: (0, common_1.eachRecursive)(clonedPSBT.txInputs),
477
+ outputTx: (0, common_1.eachRecursive)(clonedPSBT.txOutputs),
478
+ inputData: clonedPSBT.data.inputs,
479
+ outputData: clonedPSBT.data.outputs,
480
+ PSBTVersion: clonedPSBT.version,
481
+ PSBTLocktime: clonedPSBT.locktime,
482
+ PSBTGlobalMap: clonedPSBT.data.globalMap,
483
+ rawPSBT: psbt
484
+ }
485
+ }
486
+ ]];
306
487
  }
307
- ];
308
- }));
309
- const changeAddressInfo = {};
310
- changeAddressDatas.forEach((changeAddressData) => {
311
- changeAddressInfo[changeAddressData[0]] = changeAddressData[1];
312
- });
313
- return [
314
- {
315
- from: decodedPSBT.data.inputs.map((obj) => obj.tapBip32Derivation
316
- ?.map((el) => this.bitcoinJS.lib.payments.p2tr({
317
- internalPubkey: el.pubkey,
318
- network: this.bitcoinJS.lib.networks.bitcoin
319
- }).address)
320
- .join(' ') ?? 'INVALID'),
321
- to: decodedPSBT.txOutputs.map((obj) => {
322
- return obj.address || `Script: ${obj.script.toString('hex')}` || 'unknown';
323
- }),
324
- isInbound: false,
325
- amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
326
- fee: (0, module_kit_1.newAmount)(fee, 'blockchain'),
327
- network: this.options.network,
328
- changeAddressInfo,
329
- uiAlerts: alerts,
330
- json: {
331
- inputTx: (0, common_1.eachRecursive)(clonedPSBT.txInputs),
332
- outputTx: (0, common_1.eachRecursive)(clonedPSBT.txOutputs),
333
- inputData: clonedPSBT.data.inputs,
334
- outputData: clonedPSBT.data.outputs,
335
- PSBTVersion: clonedPSBT.version,
336
- PSBTLocktime: clonedPSBT.locktime,
337
- PSBTGlobalMap: clonedPSBT.data.globalMap,
338
- rawPSBT: psbt
488
+ });
489
+ });
490
+ };
491
+ BitcoinTaprootProtocolImpl.prototype.getNetwork = function () {
492
+ return __awaiter(this, void 0, void 0, function () {
493
+ return __generator(this, function (_a) {
494
+ return [2 /*return*/, this.options.network];
495
+ });
496
+ });
497
+ };
498
+ BitcoinTaprootProtocolImpl.prototype.getTransactionsForPublicKey = function (publicKey, limit, cursor) {
499
+ return __awaiter(this, void 0, void 0, function () {
500
+ return __generator(this, function (_a) {
501
+ switch (publicKey.type) {
502
+ case 'pub':
503
+ return [2 /*return*/, this.getTransactionsForNonExtendedPublicKey(publicKey, limit, cursor)];
504
+ case 'xpub':
505
+ return [2 /*return*/, this.getTransactionsForExtendedPublicKey(publicKey, limit, cursor)];
506
+ default:
507
+ (0, coinlib_core_1.assertNever)(publicKey);
508
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Public key type not supported');
339
509
  }
340
- }
341
- ];
342
- }
343
- async getNetwork() {
344
- return this.options.network;
345
- }
346
- async getTransactionsForPublicKey(publicKey, limit, cursor) {
347
- switch (publicKey.type) {
348
- case 'pub':
349
- return this.getTransactionsForNonExtendedPublicKey(publicKey, limit, cursor);
350
- case 'xpub':
351
- return this.getTransactionsForExtendedPublicKey(publicKey, limit, cursor);
352
- default:
353
- (0, coinlib_core_1.assertNever)(publicKey);
354
- throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Public key type not supported');
355
- }
356
- }
357
- async getTransactionsForNonExtendedPublicKey(publicKey, limit, cursor) {
358
- const address = await this.getAddressFromPublicKey(publicKey);
359
- return this.getTransactionsForAddresses([address], limit, cursor);
360
- }
361
- async getTransactionsForExtendedPublicKey(extendedPublicKey, limit, cursor) {
362
- const encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
363
- const page = cursor?.page ?? 1;
364
- const url = `${this.options.network.indexerApi}/api/v2/xpub/tr(${encodedExtendedPublicKey.value})?details=txs&tokens=used&pageSize=${limit}&page=${page}`;
365
- const { data } = await index_1.default.get(url, {
366
- responseType: 'json'
367
- });
368
- const ourAddresses = (data.tokens || []).filter((token) => token.type === 'XPUBAddress').map((token) => token.name);
369
- const airGapTransactions = [];
370
- if (data.page === page) {
371
- for (const transaction of data.transactions || []) {
372
- const tempAirGapTransactionFrom = [];
373
- const tempAirGapTransactionTo = [];
374
- let tempAirGapTransactionIsInbound = true;
375
- let amountNotAdded = true;
376
- let amount = new bignumber_1.default(0);
377
- for (const vin of transaction.vin) {
378
- if ((0, common_1.containsSome)(vin.addresses, ourAddresses)) {
379
- tempAirGapTransactionIsInbound = false;
380
- }
381
- tempAirGapTransactionFrom.push(...vin.addresses);
510
+ return [2 /*return*/];
511
+ });
512
+ });
513
+ };
514
+ BitcoinTaprootProtocolImpl.prototype.getTransactionsForNonExtendedPublicKey = function (publicKey, limit, cursor) {
515
+ return __awaiter(this, void 0, void 0, function () {
516
+ var address;
517
+ return __generator(this, function (_a) {
518
+ switch (_a.label) {
519
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
520
+ case 1:
521
+ address = _a.sent();
522
+ return [2 /*return*/, this.getTransactionsForAddresses([address], limit, cursor)];
382
523
  }
383
- for (const vout of transaction.vout) {
384
- if (vout.addresses) {
385
- tempAirGapTransactionTo.push(...vout.addresses);
386
- }
387
- if ((0, common_1.containsSome)(vout.addresses, ourAddresses) && transaction.vout.length > 2) {
388
- amount = amount.plus(vout.value);
389
- amountNotAdded = false;
390
- }
524
+ });
525
+ });
526
+ };
527
+ BitcoinTaprootProtocolImpl.prototype.getTransactionsForExtendedPublicKey = function (extendedPublicKey, limit, cursor) {
528
+ var _a;
529
+ return __awaiter(this, void 0, void 0, function () {
530
+ var encodedExtendedPublicKey, page, url, data, ourAddresses, airGapTransactions, _i, _b, transaction, tempAirGapTransactionFrom, tempAirGapTransactionTo, tempAirGapTransactionIsInbound, amountNotAdded, amount, _c, _d, vin, _e, _f, vout, airGapTransaction, hasNext;
531
+ return __generator(this, function (_g) {
532
+ switch (_g.label) {
533
+ case 0:
534
+ encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
535
+ page = (_a = cursor === null || cursor === void 0 ? void 0 : cursor.page) !== null && _a !== void 0 ? _a : 1;
536
+ url = "".concat(this.options.network.indexerApi, "/api/v2/xpub/tr(").concat(encodedExtendedPublicKey.value, ")?details=txs&tokens=used&pageSize=").concat(limit, "&page=").concat(page);
537
+ return [4 /*yield*/, index_1.default.get(url, {
538
+ responseType: 'json'
539
+ })];
540
+ case 1:
541
+ data = (_g.sent()).data;
542
+ ourAddresses = (data.tokens || []).filter(function (token) { return token.type === 'XPUBAddress'; }).map(function (token) { return token.name; });
543
+ airGapTransactions = [];
544
+ if (data.page === page) {
545
+ for (_i = 0, _b = data.transactions || []; _i < _b.length; _i++) {
546
+ transaction = _b[_i];
547
+ tempAirGapTransactionFrom = [];
548
+ tempAirGapTransactionTo = [];
549
+ tempAirGapTransactionIsInbound = true;
550
+ amountNotAdded = true;
551
+ amount = new bignumber_1.default(0);
552
+ for (_c = 0, _d = transaction.vin; _c < _d.length; _c++) {
553
+ vin = _d[_c];
554
+ if ((0, common_1.containsSome)(vin.addresses, ourAddresses)) {
555
+ tempAirGapTransactionIsInbound = false;
556
+ }
557
+ tempAirGapTransactionFrom.push.apply(tempAirGapTransactionFrom, vin.addresses);
558
+ }
559
+ for (_e = 0, _f = transaction.vout; _e < _f.length; _e++) {
560
+ vout = _f[_e];
561
+ if (vout.addresses) {
562
+ tempAirGapTransactionTo.push.apply(tempAirGapTransactionTo, vout.addresses);
563
+ }
564
+ if ((0, common_1.containsSome)(vout.addresses, ourAddresses) && transaction.vout.length > 2) {
565
+ amount = amount.plus(vout.value);
566
+ amountNotAdded = false;
567
+ }
568
+ }
569
+ // deduct fee from amount
570
+ //amount = amount.minus(transaction.fees)
571
+ if (amountNotAdded) {
572
+ amount = amount.plus(transaction.vout[0].value);
573
+ }
574
+ airGapTransaction = {
575
+ from: tempAirGapTransactionFrom,
576
+ to: tempAirGapTransactionTo,
577
+ isInbound: tempAirGapTransactionIsInbound,
578
+ amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
579
+ fee: (0, module_kit_1.newAmount)(transaction.fees, 'blockchain'),
580
+ status: {
581
+ type: 'applied',
582
+ hash: transaction.txid,
583
+ block: transaction.blockHeight.toString()
584
+ },
585
+ network: this.options.network,
586
+ timestamp: transaction.blockTime
587
+ };
588
+ airGapTransactions.push(airGapTransaction);
589
+ }
590
+ }
591
+ hasNext = page < data.totalPages;
592
+ return [2 /*return*/, {
593
+ transactions: airGapTransactions,
594
+ cursor: {
595
+ hasNext: hasNext,
596
+ page: hasNext ? page + 1 : undefined
597
+ }
598
+ }];
391
599
  }
392
- // deduct fee from amount
393
- //amount = amount.minus(transaction.fees)
394
- if (amountNotAdded) {
395
- amount = amount.plus(transaction.vout[0].value);
600
+ });
601
+ });
602
+ };
603
+ BitcoinTaprootProtocolImpl.prototype.getTransactionsForAddress = function (address, limit, cursor) {
604
+ return __awaiter(this, void 0, void 0, function () {
605
+ return __generator(this, function (_a) {
606
+ return [2 /*return*/, this.getTransactionsForAddresses([address], limit, cursor)];
607
+ });
608
+ });
609
+ };
610
+ BitcoinTaprootProtocolImpl.prototype.getTransactionsForAddresses = function (addresses, limit, cursor) {
611
+ var _a;
612
+ return __awaiter(this, void 0, void 0, function () {
613
+ var airGapTransactions, page, url, data, _i, _b, transaction, tempAirGapTransactionFrom, tempAirGapTransactionTo, tempAirGapTransactionIsInbound, amount, _c, _d, vin, _e, _f, vout, airGapTransaction, hasNext;
614
+ return __generator(this, function (_g) {
615
+ switch (_g.label) {
616
+ case 0:
617
+ airGapTransactions = [];
618
+ page = (_a = cursor === null || cursor === void 0 ? void 0 : cursor.page) !== null && _a !== void 0 ? _a : 1;
619
+ url = "".concat(this.options.network.indexerApi, "/api/v2/address/").concat(addresses[0], "?page=").concat(page, "&pageSize=").concat(limit, "&details=txs");
620
+ return [4 /*yield*/, index_1.default.get(url, {
621
+ responseType: 'json'
622
+ })];
623
+ case 1:
624
+ data = (_g.sent()).data;
625
+ if (data.page == page) {
626
+ for (_i = 0, _b = data.transactions || []; _i < _b.length; _i++) {
627
+ transaction = _b[_i];
628
+ tempAirGapTransactionFrom = [];
629
+ tempAirGapTransactionTo = [];
630
+ tempAirGapTransactionIsInbound = true;
631
+ amount = new bignumber_1.default(0);
632
+ for (_c = 0, _d = transaction.vin; _c < _d.length; _c++) {
633
+ vin = _d[_c];
634
+ if (vin.addresses && (0, common_1.containsSome)(vin.addresses, addresses)) {
635
+ tempAirGapTransactionIsInbound = false;
636
+ }
637
+ tempAirGapTransactionFrom.push.apply(tempAirGapTransactionFrom, vin.addresses);
638
+ amount = vin.value ? amount.plus(vin.value) : amount;
639
+ }
640
+ for (_e = 0, _f = transaction.vout; _e < _f.length; _e++) {
641
+ vout = _f[_e];
642
+ if (vout.addresses) {
643
+ tempAirGapTransactionTo.push.apply(tempAirGapTransactionTo, vout.addresses);
644
+ // If receiving address is our address, and transaction is outbound => our change
645
+ if ((0, common_1.containsSome)(vout.addresses, addresses) && !tempAirGapTransactionIsInbound) {
646
+ // remove only if related to this address
647
+ amount = amount.minus(new bignumber_1.default(vout.value));
648
+ }
649
+ // If receiving address is not ours, and transaction isbound => senders change
650
+ if (!(0, common_1.containsSome)(vout.addresses, addresses) && tempAirGapTransactionIsInbound) {
651
+ amount = amount.minus(new bignumber_1.default(vout.value));
652
+ }
653
+ }
654
+ }
655
+ // deduct fee from amount
656
+ amount = amount.minus(new bignumber_1.default(transaction.fees));
657
+ airGapTransaction = {
658
+ from: tempAirGapTransactionFrom,
659
+ to: tempAirGapTransactionTo,
660
+ isInbound: tempAirGapTransactionIsInbound,
661
+ amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
662
+ fee: (0, module_kit_1.newAmount)(transaction.fees, 'blockchain'),
663
+ status: {
664
+ type: 'applied',
665
+ hash: transaction.txid,
666
+ block: transaction.blockHeight.toString()
667
+ },
668
+ network: this.options.network,
669
+ timestamp: transaction.blockTime
670
+ };
671
+ airGapTransactions.push(airGapTransaction);
672
+ }
673
+ }
674
+ hasNext = page < data.totalPages;
675
+ return [2 /*return*/, {
676
+ transactions: airGapTransactions,
677
+ cursor: {
678
+ hasNext: hasNext,
679
+ page: hasNext ? page + 1 : undefined
680
+ }
681
+ }];
396
682
  }
397
- const airGapTransaction = {
398
- from: tempAirGapTransactionFrom,
399
- to: tempAirGapTransactionTo,
400
- isInbound: tempAirGapTransactionIsInbound,
401
- amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
402
- fee: (0, module_kit_1.newAmount)(transaction.fees, 'blockchain'),
403
- status: {
404
- type: 'applied',
405
- hash: transaction.txid,
406
- block: transaction.blockHeight.toString()
407
- },
408
- network: this.options.network,
409
- timestamp: transaction.blockTime
410
- };
411
- airGapTransactions.push(airGapTransaction);
412
- }
413
- }
414
- const hasNext = page < data.totalPages;
415
- return {
416
- transactions: airGapTransactions,
417
- cursor: {
418
- hasNext,
419
- page: hasNext ? page + 1 : undefined
420
- }
421
- };
422
- }
423
- async getTransactionsForAddress(address, limit, cursor) {
424
- return this.getTransactionsForAddresses([address], limit, cursor);
425
- }
426
- async getTransactionsForAddresses(addresses, limit, cursor) {
427
- const airGapTransactions = [];
428
- const page = cursor?.page ?? 1;
429
- const url = `${this.options.network.indexerApi}/api/v2/address/${addresses[0]}?page=${page}&pageSize=${limit}&details=txs`;
430
- const { data } = await index_1.default.get(url, {
431
- responseType: 'json'
432
- });
433
- if (data.page == page) {
434
- for (const transaction of data.transactions || []) {
435
- const tempAirGapTransactionFrom = [];
436
- const tempAirGapTransactionTo = [];
437
- let tempAirGapTransactionIsInbound = true;
438
- let amount = new bignumber_1.default(0);
439
- for (const vin of transaction.vin) {
440
- if (vin.addresses && (0, common_1.containsSome)(vin.addresses, addresses)) {
441
- tempAirGapTransactionIsInbound = false;
442
- }
443
- tempAirGapTransactionFrom.push(...vin.addresses);
444
- amount = vin.value ? amount.plus(vin.value) : amount;
683
+ });
684
+ });
685
+ };
686
+ BitcoinTaprootProtocolImpl.prototype.getBalanceOfPublicKey = function (publicKey) {
687
+ return __awaiter(this, void 0, void 0, function () {
688
+ return __generator(this, function (_a) {
689
+ switch (publicKey.type) {
690
+ case 'pub':
691
+ return [2 /*return*/, this.getBalanceOfNonExtendedPublicKey(publicKey)];
692
+ case 'xpub':
693
+ return [2 /*return*/, this.getBalanceOfExtendedPublicKey(publicKey)];
694
+ default:
695
+ (0, coinlib_core_1.assertNever)(publicKey);
696
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Unsupported public key type.');
445
697
  }
446
- for (const vout of transaction.vout) {
447
- if (vout.addresses) {
448
- tempAirGapTransactionTo.push(...vout.addresses);
449
- // If receiving address is our address, and transaction is outbound => our change
450
- if ((0, common_1.containsSome)(vout.addresses, addresses) && !tempAirGapTransactionIsInbound) {
451
- // remove only if related to this address
452
- amount = amount.minus(new bignumber_1.default(vout.value));
453
- }
454
- // If receiving address is not ours, and transaction isbound => senders change
455
- if (!(0, common_1.containsSome)(vout.addresses, addresses) && tempAirGapTransactionIsInbound) {
456
- amount = amount.minus(new bignumber_1.default(vout.value));
457
- }
458
- }
698
+ return [2 /*return*/];
699
+ });
700
+ });
701
+ };
702
+ BitcoinTaprootProtocolImpl.prototype.getBalanceOfNonExtendedPublicKey = function (publicKey) {
703
+ return __awaiter(this, void 0, void 0, function () {
704
+ var address;
705
+ return __generator(this, function (_a) {
706
+ switch (_a.label) {
707
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
708
+ case 1:
709
+ address = _a.sent();
710
+ return [2 /*return*/, this.getBalanceOfAddresses([address])];
459
711
  }
460
- // deduct fee from amount
461
- amount = amount.minus(new bignumber_1.default(transaction.fees));
462
- const airGapTransaction = {
463
- from: tempAirGapTransactionFrom,
464
- to: tempAirGapTransactionTo,
465
- isInbound: tempAirGapTransactionIsInbound,
466
- amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
467
- fee: (0, module_kit_1.newAmount)(transaction.fees, 'blockchain'),
468
- status: {
469
- type: 'applied',
470
- hash: transaction.txid,
471
- block: transaction.blockHeight.toString()
472
- },
473
- network: this.options.network,
474
- timestamp: transaction.blockTime
475
- };
476
- airGapTransactions.push(airGapTransaction);
477
- }
478
- }
479
- const hasNext = page < data.totalPages;
480
- return {
481
- transactions: airGapTransactions,
482
- cursor: {
483
- hasNext,
484
- page: hasNext ? page + 1 : undefined
485
- }
486
- };
487
- }
488
- async getBalanceOfPublicKey(publicKey) {
489
- switch (publicKey.type) {
490
- case 'pub':
491
- return this.getBalanceOfNonExtendedPublicKey(publicKey);
492
- case 'xpub':
493
- return this.getBalanceOfExtendedPublicKey(publicKey);
494
- default:
495
- (0, coinlib_core_1.assertNever)(publicKey);
496
- throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Unsupported public key type.');
497
- }
498
- }
499
- async getBalanceOfNonExtendedPublicKey(publicKey) {
500
- const address = await this.getAddressFromPublicKey(publicKey);
501
- return this.getBalanceOfAddresses([address]);
502
- }
503
- async getBalanceOfExtendedPublicKey(extendedPublicKey) {
504
- const encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
505
- const { data } = await index_1.default.get(`${this.options.network.indexerApi}/api/v2/xpub/tr(${encodedExtendedPublicKey.value})?pageSize=1`, {
506
- responseType: 'json'
712
+ });
507
713
  });
508
- return {
509
- total: (0, module_kit_1.newAmount)(data.balance, 'blockchain')
510
- };
511
- }
512
- async getTransactionMaxAmountWithPublicKey(publicKey, to, configuration) {
513
- return this.segwit.getTransactionMaxAmountWithPublicKey(publicKey, to, configuration);
514
- }
515
- async getTransactionFeeWithPublicKey(publicKey, details, configuration) {
516
- return this.segwit.getTransactionFeeWithPublicKey(publicKey, details, configuration);
517
- }
518
- async broadcastTransaction(transaction) {
519
- const psbt = this.bitcoinJS.lib.Psbt.fromHex(transaction.psbt);
520
- // Verify and finalize each Taproot input
521
- psbt.data.inputs.forEach((input, index) => {
522
- if (input.tapInternalKey) {
523
- try {
524
- const finalized = psbt.finalizeTaprootInput(index);
525
- if (!finalized) {
526
- throw new Error(`Failed to finalize Taproot input #${index}`);
527
- }
714
+ };
715
+ BitcoinTaprootProtocolImpl.prototype.getBalanceOfExtendedPublicKey = function (extendedPublicKey) {
716
+ return __awaiter(this, void 0, void 0, function () {
717
+ var encodedExtendedPublicKey, data;
718
+ return __generator(this, function (_a) {
719
+ switch (_a.label) {
720
+ case 0:
721
+ encodedExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
722
+ return [4 /*yield*/, index_1.default.get("".concat(this.options.network.indexerApi, "/api/v2/xpub/tr(").concat(encodedExtendedPublicKey.value, ")?pageSize=1"), {
723
+ responseType: 'json'
724
+ })];
725
+ case 1:
726
+ data = (_a.sent()).data;
727
+ return [2 /*return*/, {
728
+ total: (0, module_kit_1.newAmount)(data.balance, 'blockchain')
729
+ }];
528
730
  }
529
- catch (error) {
530
- throw new Error(`Error finalizing Taproot input #${index}: ${error}`);
731
+ });
732
+ });
733
+ };
734
+ BitcoinTaprootProtocolImpl.prototype.getTransactionMaxAmountWithPublicKey = function (publicKey, to, configuration) {
735
+ return __awaiter(this, void 0, void 0, function () {
736
+ return __generator(this, function (_a) {
737
+ return [2 /*return*/, this.segwit.getTransactionMaxAmountWithPublicKey(publicKey, to, configuration)];
738
+ });
739
+ });
740
+ };
741
+ BitcoinTaprootProtocolImpl.prototype.getTransactionFeeWithPublicKey = function (publicKey, details, configuration) {
742
+ return __awaiter(this, void 0, void 0, function () {
743
+ return __generator(this, function (_a) {
744
+ return [2 /*return*/, this.segwit.getTransactionFeeWithPublicKey(publicKey, details, configuration)];
745
+ });
746
+ });
747
+ };
748
+ BitcoinTaprootProtocolImpl.prototype.broadcastTransaction = function (transaction) {
749
+ return __awaiter(this, void 0, void 0, function () {
750
+ var psbt, hexTransaction, data;
751
+ return __generator(this, function (_a) {
752
+ switch (_a.label) {
753
+ case 0:
754
+ psbt = this.bitcoinJS.lib.Psbt.fromHex(transaction.psbt);
755
+ // Verify and finalize each Taproot input
756
+ psbt.data.inputs.forEach(function (input, index) {
757
+ if (input.tapInternalKey) {
758
+ try {
759
+ var finalized = psbt.finalizeTaprootInput(index);
760
+ if (!finalized) {
761
+ throw new Error("Failed to finalize Taproot input #".concat(index));
762
+ }
763
+ }
764
+ catch (error) {
765
+ throw new Error("Error finalizing Taproot input #".concat(index, ": ").concat(error));
766
+ }
767
+ }
768
+ });
769
+ hexTransaction = psbt.extractTransaction().toHex();
770
+ return [4 /*yield*/, index_1.default.post("".concat(this.options.network.indexerApi, "/api/v2/sendtx/"), hexTransaction)];
771
+ case 1:
772
+ data = (_a.sent()).data;
773
+ return [2 /*return*/, data.result
774
+ // return ''
775
+ ];
531
776
  }
532
- }
777
+ });
533
778
  });
534
- // Extract and broadcast the finalized transaction
535
- const hexTransaction = psbt.extractTransaction().toHex();
536
- const { data } = await index_1.default.post(`${this.options.network.indexerApi}/api/v2/sendtx/`, hexTransaction);
537
- return data.result;
538
- // return ''
539
- }
540
- async getExtendedKeyPairFromDerivative(derivative) {
541
- const bip32 = this.derivativeToBip32Node(derivative);
542
- return {
543
- secretKey: (0, module_kit_1.newExtendedSecretKey)(bip32.toBase58(), 'encoded'),
544
- publicKey: (0, key_1.convertExtendedPublicKey)((0, module_kit_1.newExtendedPublicKey)(bip32.neutered().toBase58(), 'encoded'), {
545
- format: 'encoded',
546
- type: 'xpub'
547
- })
548
- };
549
- }
550
- derivativeToBip32Node(derivative) {
551
- const extendedSecretKey = this.convertCryptoDerivative(derivative);
552
- return this.bip32.fromBase58(extendedSecretKey.value, this.bitcoinJS.config.network);
553
- }
554
- convertCryptoDerivative(derivative) {
555
- const hexNode = (0, crypto_1.encodeDerivative)('hex', {
556
- ...derivative,
557
- secretKey: `00${derivative.secretKey}`
779
+ };
780
+ BitcoinTaprootProtocolImpl.prototype.getExtendedKeyPairFromDerivative = function (derivative) {
781
+ return __awaiter(this, void 0, void 0, function () {
782
+ var bip32;
783
+ return __generator(this, function (_a) {
784
+ bip32 = this.derivativeToBip32Node(derivative);
785
+ return [2 /*return*/, {
786
+ secretKey: (0, module_kit_1.newExtendedSecretKey)(bip32.toBase58(), 'encoded'),
787
+ publicKey: (0, key_1.convertExtendedPublicKey)((0, module_kit_1.newExtendedPublicKey)(bip32.neutered().toBase58(), 'encoded'), {
788
+ format: 'encoded',
789
+ type: 'xpub'
790
+ })
791
+ }];
792
+ });
558
793
  });
559
- const extendedSecretKey = {
794
+ };
795
+ BitcoinTaprootProtocolImpl.prototype.derivativeToBip32Node = function (derivative) {
796
+ var extendedSecretKey = this.convertCryptoDerivative(derivative);
797
+ return this.bip32.fromBase58(extendedSecretKey.value, this.bitcoinJS.config.network);
798
+ };
799
+ BitcoinTaprootProtocolImpl.prototype.convertCryptoDerivative = function (derivative) {
800
+ var hexNode = (0, crypto_1.encodeDerivative)('hex', __assign(__assign({}, derivative), { secretKey: "00".concat(derivative.secretKey) }));
801
+ var extendedSecretKey = {
560
802
  type: 'xpriv',
561
803
  format: 'hex',
562
804
  value: hexNode.secretKey
563
805
  };
564
806
  return (0, key_1.convertExtendedSecretKey)(extendedSecretKey, { format: 'encoded', type: 'xprv' });
565
- }
566
- async deriveFromExtendedSecretKey(extendedSecretKey, visibilityIndex, addressIndex) {
567
- return this.segwit.deriveFromExtendedSecretKey(extendedSecretKey, visibilityIndex, addressIndex);
568
- }
569
- async deriveFromExtendedPublicKey(extendedPublicKey, visibilityIndex, addressIndex) {
570
- const encodedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
571
- const derivedBip32 = this.bip32
572
- .fromBase58(encodedPublicKey.value, this.bitcoinJS.config.network)
573
- .derive(visibilityIndex)
574
- .derive(addressIndex);
575
- return (0, module_kit_1.newPublicKey)(Buffer.from(derivedBip32.publicKey).toString('hex'), 'hex');
576
- }
577
- async signMessageWithKeyPair(message, keyPair) {
578
- return this.segwit.signMessageWithKeyPair(message, keyPair);
579
- }
580
- async verifyMessageWithPublicKey(message, signature, publicKey) {
581
- return this.segwit.verifyMessageWithPublicKey(message, signature, publicKey);
582
- }
583
- async decryptAsymmetricWithKeyPair(payload, keyPair) {
584
- return this.segwit.decryptAsymmetricWithKeyPair(payload, keyPair);
585
- }
586
- async encryptAsymmetricWithPublicKey(payload, publicKey) {
587
- return this.segwit.encryptAsymmetricWithPublicKey(payload, publicKey);
588
- }
589
- async encryptAESWithSecretKey(payload, secretKey) {
590
- return this.segwit.encryptAESWithSecretKey(payload, secretKey);
591
- }
592
- decryptAESWithSecretKey(payload, secretKey) {
593
- return this.segwit.decryptAESWithSecretKey(payload, secretKey);
594
- }
595
- async getBalanceOfAddress(address, configuration) {
596
- return this.segwit.getBalanceOfAddress(address);
597
- }
598
- async getBalanceOfAddresses(addresses, configuration) {
599
- return this.segwit.getBalanceOfAddresses(addresses);
600
- }
601
- // Common methods similar to Segwit implementation
602
- // ... [Include all the common methods from Segwit implementation but modify for Taproot]
603
- async getAddressFromNonExtendedPublicKey(publicKey) {
604
- const hexPublicKey = (0, key_1.convertPublicKey)(publicKey, 'hex');
605
- const payment = this.bitcoinJS.lib.payments.p2tr({
606
- internalPubkey: Buffer.from(hexPublicKey.value, 'hex').subarray(1, 33),
607
- network: this.bitcoinJS.config.network
807
+ };
808
+ BitcoinTaprootProtocolImpl.prototype.deriveFromExtendedSecretKey = function (extendedSecretKey, visibilityIndex, addressIndex) {
809
+ return __awaiter(this, void 0, void 0, function () {
810
+ return __generator(this, function (_a) {
811
+ return [2 /*return*/, this.segwit.deriveFromExtendedSecretKey(extendedSecretKey, visibilityIndex, addressIndex)];
812
+ });
608
813
  });
609
- return BitcoinTaprootAddress_1.BitcoinTaprootAddress.fromPayment(payment).asString();
610
- }
611
- async prepareTransactionWithExtendedPublicKey(extendedPublicKey, details, configuration) {
612
- if (configuration?.masterFingerprint === undefined) {
613
- throw new errors_1.ConditionViolationError(coinlib_core_1.Domain.BITCOIN, 'Master fingerprint not set.');
614
- }
615
- let fee;
616
- if (configuration?.fee !== undefined) {
617
- fee = configuration.fee;
618
- }
619
- else {
620
- const estimatedFee = await this.getTransactionFeeWithPublicKey(extendedPublicKey, details);
621
- fee = estimatedFee.medium;
622
- }
623
- const wrappedFee = new bignumber_1.default((0, module_kit_1.newAmount)(fee).blockchain(this.segwit.legacy.units).value);
624
- const transaction = (0, module_kit_1.newUnsignedTransaction)({
625
- ins: [],
626
- outs: []
814
+ };
815
+ BitcoinTaprootProtocolImpl.prototype.deriveFromExtendedPublicKey = function (extendedPublicKey, visibilityIndex, addressIndex) {
816
+ return __awaiter(this, void 0, void 0, function () {
817
+ var encodedPublicKey, derivedBip32;
818
+ return __generator(this, function (_a) {
819
+ encodedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
820
+ derivedBip32 = this.bip32
821
+ .fromBase58(encodedPublicKey.value, this.bitcoinJS.config.network)
822
+ .derive(visibilityIndex)
823
+ .derive(addressIndex);
824
+ return [2 /*return*/, (0, module_kit_1.newPublicKey)(Buffer.from(derivedBip32.publicKey).toString('hex'), 'hex')];
825
+ });
627
826
  });
628
- const { data: utxos } = await index_1.default.get(`${this.options.network.indexerApi}/api/v2/utxo/tr(${extendedPublicKey.value})?confirmed=true`, {
629
- responseType: 'json'
827
+ };
828
+ BitcoinTaprootProtocolImpl.prototype.signMessageWithKeyPair = function (message, keyPair) {
829
+ return __awaiter(this, void 0, void 0, function () {
830
+ return __generator(this, function (_a) {
831
+ return [2 /*return*/, this.segwit.signMessageWithKeyPair(message, keyPair)];
832
+ });
630
833
  });
631
- if (utxos.length <= 0) {
632
- throw new errors_1.BalanceError(coinlib_core_1.Domain.BITCOIN, 'Not enough balance.'); // no transactions found on those addresses, probably won't find anything in the next ones
633
- }
634
- const totalRequiredBalance = details
635
- .map(({ amount }) => new bignumber_1.default((0, module_kit_1.newAmount)(amount).blockchain(this.segwit.legacy.units).value))
636
- .reduce((accumulator, currentValue) => accumulator.plus(currentValue))
637
- .plus(wrappedFee);
638
- let valueAccumulator = new bignumber_1.default(0);
639
- const getPathIndexes = (path) => {
640
- const result = path
641
- .split('/')
642
- .slice(-2)
643
- .map((item) => parseInt(item))
644
- .filter((item) => !isNaN(item));
645
- if (result.length !== 2) {
646
- throw new Error('Unexpected path format');
647
- }
648
- return [result[0], result[1]];
649
- };
650
- for (const utxo of utxos) {
651
- valueAccumulator = valueAccumulator.plus(utxo.value);
652
- const indexes = getPathIndexes(utxo.path);
653
- const derivedPublicKey = await this.deriveFromExtendedPublicKey(extendedPublicKey, indexes[0], indexes[1]);
654
- const derivedAddress = await this.getAddressFromPublicKey(derivedPublicKey);
655
- if (derivedAddress === utxo.address) {
656
- transaction.ins.push({
657
- txId: utxo.txid,
658
- value: new bignumber_1.default(utxo.value).toString(10),
659
- vout: utxo.vout,
660
- address: utxo.address,
661
- derivationPath: utxo.path
834
+ };
835
+ BitcoinTaprootProtocolImpl.prototype.verifyMessageWithPublicKey = function (message, signature, publicKey) {
836
+ return __awaiter(this, void 0, void 0, function () {
837
+ return __generator(this, function (_a) {
838
+ return [2 /*return*/, this.segwit.verifyMessageWithPublicKey(message, signature, publicKey)];
839
+ });
840
+ });
841
+ };
842
+ BitcoinTaprootProtocolImpl.prototype.decryptAsymmetricWithKeyPair = function (payload, keyPair) {
843
+ return __awaiter(this, void 0, void 0, function () {
844
+ return __generator(this, function (_a) {
845
+ return [2 /*return*/, this.segwit.decryptAsymmetricWithKeyPair(payload, keyPair)];
846
+ });
847
+ });
848
+ };
849
+ BitcoinTaprootProtocolImpl.prototype.encryptAsymmetricWithPublicKey = function (payload, publicKey) {
850
+ return __awaiter(this, void 0, void 0, function () {
851
+ return __generator(this, function (_a) {
852
+ return [2 /*return*/, this.segwit.encryptAsymmetricWithPublicKey(payload, publicKey)];
853
+ });
854
+ });
855
+ };
856
+ BitcoinTaprootProtocolImpl.prototype.encryptAESWithSecretKey = function (payload, secretKey) {
857
+ return __awaiter(this, void 0, void 0, function () {
858
+ return __generator(this, function (_a) {
859
+ return [2 /*return*/, this.segwit.encryptAESWithSecretKey(payload, secretKey)];
860
+ });
861
+ });
862
+ };
863
+ BitcoinTaprootProtocolImpl.prototype.decryptAESWithSecretKey = function (payload, secretKey) {
864
+ return this.segwit.decryptAESWithSecretKey(payload, secretKey);
865
+ };
866
+ BitcoinTaprootProtocolImpl.prototype.getBalanceOfAddress = function (address, configuration) {
867
+ return __awaiter(this, void 0, void 0, function () {
868
+ return __generator(this, function (_a) {
869
+ return [2 /*return*/, this.segwit.getBalanceOfAddress(address)];
870
+ });
871
+ });
872
+ };
873
+ BitcoinTaprootProtocolImpl.prototype.getBalanceOfAddresses = function (addresses, configuration) {
874
+ return __awaiter(this, void 0, void 0, function () {
875
+ return __generator(this, function (_a) {
876
+ return [2 /*return*/, this.segwit.getBalanceOfAddresses(addresses)];
877
+ });
878
+ });
879
+ };
880
+ // Common methods similar to Segwit implementation
881
+ // ... [Include all the common methods from Segwit implementation but modify for Taproot]
882
+ BitcoinTaprootProtocolImpl.prototype.getAddressFromNonExtendedPublicKey = function (publicKey) {
883
+ return __awaiter(this, void 0, void 0, function () {
884
+ var hexPublicKey, payment;
885
+ return __generator(this, function (_a) {
886
+ hexPublicKey = (0, key_1.convertPublicKey)(publicKey, 'hex');
887
+ payment = this.bitcoinJS.lib.payments.p2tr({
888
+ internalPubkey: Buffer.from(hexPublicKey.value, 'hex').subarray(1, 33),
889
+ network: this.bitcoinJS.config.network
662
890
  });
663
- }
664
- else {
665
- throw new Error('Invalid address returned from API');
666
- }
667
- if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
668
- break;
669
- }
670
- }
671
- if (valueAccumulator.isLessThan(totalRequiredBalance)) {
672
- throw new Error('not enough balance 2');
673
- }
674
- for (let i = 0; i < details.length; i++) {
675
- const value = (0, module_kit_1.newAmount)(details[i].amount).blockchain(this.segwit.legacy.units).value;
676
- transaction.outs.push({
677
- recipient: details[i].to,
678
- isChange: false,
679
- value
680
- });
681
- valueAccumulator = valueAccumulator.minus(value);
682
- }
683
- const lastUsedInternalAddress = Math.max(-1, ...utxos
684
- .map((utxo) => getPathIndexes(utxo.path))
685
- .filter((indexes) => indexes[0] === 1)
686
- .map((indexes) => indexes[1]));
687
- // If the change is considered dust, the transaction will fail.
688
- // Dust is a variable value around 300-600 satoshis, depending on the configuration.
689
- // We set a low fee here to not block any transactions, but it might still fail due to "dust".
690
- const changeValue = valueAccumulator.minus(wrappedFee);
691
- if (changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) {
692
- const changeAddressIndex = lastUsedInternalAddress + 1;
693
- const derivedPublicKey = await this.deriveFromExtendedPublicKey(extendedPublicKey, 1, changeAddressIndex);
694
- const derivedAddress = await this.getAddressFromPublicKey(derivedPublicKey);
695
- transaction.outs.push({
696
- recipient: derivedAddress,
697
- isChange: true,
698
- value: changeValue.toString(10),
699
- derivationPath: `1/${changeAddressIndex}`
891
+ return [2 /*return*/, BitcoinTaprootAddress_1.BitcoinTaprootAddress.fromPayment(payment).asString()];
700
892
  });
701
- }
702
- const psbt = new this.bitcoinJS.lib.Psbt();
703
- // We add the total amount of the transaction to the global map. This can be used to show the info in the "from-to" component after the transaction was signed.
704
- psbt.addUnknownKeyValToGlobal({
705
- key: Buffer.from('amount'),
706
- value: Buffer.from(details
707
- .reduce((accumulator, next) => {
708
- return accumulator.plus((0, module_kit_1.newAmount)(next.amount).blockchain(this.segwit.legacy.units).value);
709
- }, new bignumber_1.default(0))
710
- .toString())
711
- });
712
- const xpubExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
713
- const keyPair = this.bip32.fromBase58(xpubExtendedPublicKey.value);
714
- const replaceByFee = configuration?.replaceByFee ? true : false;
715
- transaction.ins.forEach((tx) => {
716
- const indexes = getPathIndexes(tx.derivationPath);
717
- const childNode = keyPair.derivePath(indexes.join('/'));
718
- const xOnlyPubkey = childNode.publicKey.length === 33 ? childNode.publicKey.slice(1, 33) : childNode.publicKey;
719
- const payment = this.bitcoinJS.lib.payments.p2tr({
720
- internalPubkey: Buffer.from(xOnlyPubkey),
721
- network: this.bitcoinJS.config.network
722
- });
723
- const inputCommon = {
724
- hash: tx.txId,
725
- index: tx.vout,
726
- sequence: replaceByFee ? 0xfffffffd : undefined,
727
- witnessUtxo: {
728
- script: payment.output,
729
- value: parseInt(tx.value, 10)
893
+ });
894
+ };
895
+ BitcoinTaprootProtocolImpl.prototype.prepareTransactionWithExtendedPublicKey = function (extendedPublicKey, details, configuration) {
896
+ return __awaiter(this, void 0, void 0, function () {
897
+ var fee, estimatedFee, wrappedFee, transaction, utxos, totalRequiredBalance, valueAccumulator, getPathIndexes, _i, utxos_1, utxo, indexes, derivedPublicKey, derivedAddress, i, value, lastUsedInternalAddress, changeValue, changeAddressIndex, derivedPublicKey, derivedAddress, psbt, xpubExtendedPublicKey, keyPair, replaceByFee;
898
+ var _this = this;
899
+ return __generator(this, function (_a) {
900
+ switch (_a.label) {
901
+ case 0:
902
+ if ((configuration === null || configuration === void 0 ? void 0 : configuration.masterFingerprint) === undefined) {
903
+ throw new errors_1.ConditionViolationError(coinlib_core_1.Domain.BITCOIN, 'Master fingerprint not set.');
904
+ }
905
+ if (!((configuration === null || configuration === void 0 ? void 0 : configuration.fee) !== undefined)) return [3 /*break*/, 1];
906
+ fee = configuration.fee;
907
+ return [3 /*break*/, 3];
908
+ case 1: return [4 /*yield*/, this.getTransactionFeeWithPublicKey(extendedPublicKey, details)];
909
+ case 2:
910
+ estimatedFee = _a.sent();
911
+ fee = estimatedFee.medium;
912
+ _a.label = 3;
913
+ case 3:
914
+ wrappedFee = new bignumber_1.default((0, module_kit_1.newAmount)(fee).blockchain(this.segwit.legacy.units).value);
915
+ transaction = (0, module_kit_1.newUnsignedTransaction)({
916
+ ins: [],
917
+ outs: []
918
+ });
919
+ return [4 /*yield*/, index_1.default.get("".concat(this.options.network.indexerApi, "/api/v2/utxo/tr(").concat(extendedPublicKey.value, ")?confirmed=true"), {
920
+ responseType: 'json'
921
+ })];
922
+ case 4:
923
+ utxos = (_a.sent()).data;
924
+ if (utxos.length <= 0) {
925
+ throw new errors_1.BalanceError(coinlib_core_1.Domain.BITCOIN, 'Not enough balance.'); // no transactions found on those addresses, probably won't find anything in the next ones
926
+ }
927
+ totalRequiredBalance = details
928
+ .map(function (_a) {
929
+ var amount = _a.amount;
930
+ return new bignumber_1.default((0, module_kit_1.newAmount)(amount).blockchain(_this.segwit.legacy.units).value);
931
+ })
932
+ .reduce(function (accumulator, currentValue) { return accumulator.plus(currentValue); })
933
+ .plus(wrappedFee);
934
+ valueAccumulator = new bignumber_1.default(0);
935
+ getPathIndexes = function (path) {
936
+ var result = path
937
+ .split('/')
938
+ .slice(-2)
939
+ .map(function (item) { return parseInt(item); })
940
+ .filter(function (item) { return !isNaN(item); });
941
+ if (result.length !== 2) {
942
+ throw new Error('Unexpected path format');
943
+ }
944
+ return [result[0], result[1]];
945
+ };
946
+ _i = 0, utxos_1 = utxos;
947
+ _a.label = 5;
948
+ case 5:
949
+ if (!(_i < utxos_1.length)) return [3 /*break*/, 9];
950
+ utxo = utxos_1[_i];
951
+ valueAccumulator = valueAccumulator.plus(utxo.value);
952
+ indexes = getPathIndexes(utxo.path);
953
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(extendedPublicKey, indexes[0], indexes[1])];
954
+ case 6:
955
+ derivedPublicKey = _a.sent();
956
+ return [4 /*yield*/, this.getAddressFromPublicKey(derivedPublicKey)];
957
+ case 7:
958
+ derivedAddress = _a.sent();
959
+ if (derivedAddress === utxo.address) {
960
+ transaction.ins.push({
961
+ txId: utxo.txid,
962
+ value: new bignumber_1.default(utxo.value).toString(10),
963
+ vout: utxo.vout,
964
+ address: utxo.address,
965
+ derivationPath: utxo.path
966
+ });
967
+ }
968
+ else {
969
+ throw new Error('Invalid address returned from API');
970
+ }
971
+ if (valueAccumulator.isGreaterThanOrEqualTo(totalRequiredBalance)) {
972
+ return [3 /*break*/, 9];
973
+ }
974
+ _a.label = 8;
975
+ case 8:
976
+ _i++;
977
+ return [3 /*break*/, 5];
978
+ case 9:
979
+ if (valueAccumulator.isLessThan(totalRequiredBalance)) {
980
+ throw new Error('not enough balance 2');
981
+ }
982
+ for (i = 0; i < details.length; i++) {
983
+ value = (0, module_kit_1.newAmount)(details[i].amount).blockchain(this.segwit.legacy.units).value;
984
+ transaction.outs.push({
985
+ recipient: details[i].to,
986
+ isChange: false,
987
+ value: value
988
+ });
989
+ valueAccumulator = valueAccumulator.minus(value);
990
+ }
991
+ lastUsedInternalAddress = Math.max.apply(Math, __spreadArray([-1], utxos
992
+ .map(function (utxo) { return getPathIndexes(utxo.path); })
993
+ .filter(function (indexes) { return indexes[0] === 1; })
994
+ .map(function (indexes) { return indexes[1]; }), false));
995
+ changeValue = valueAccumulator.minus(wrappedFee);
996
+ if (!changeValue.isGreaterThan(new bignumber_1.default(DUST_AMOUNT))) return [3 /*break*/, 12];
997
+ changeAddressIndex = lastUsedInternalAddress + 1;
998
+ return [4 /*yield*/, this.deriveFromExtendedPublicKey(extendedPublicKey, 1, changeAddressIndex)];
999
+ case 10:
1000
+ derivedPublicKey = _a.sent();
1001
+ return [4 /*yield*/, this.getAddressFromPublicKey(derivedPublicKey)];
1002
+ case 11:
1003
+ derivedAddress = _a.sent();
1004
+ transaction.outs.push({
1005
+ recipient: derivedAddress,
1006
+ isChange: true,
1007
+ value: changeValue.toString(10),
1008
+ derivationPath: "1/".concat(changeAddressIndex)
1009
+ });
1010
+ _a.label = 12;
1011
+ case 12:
1012
+ psbt = new this.bitcoinJS.lib.Psbt();
1013
+ // We add the total amount of the transaction to the global map. This can be used to show the info in the "from-to" component after the transaction was signed.
1014
+ psbt.addUnknownKeyValToGlobal({
1015
+ key: Buffer.from('amount'),
1016
+ value: Buffer.from(details
1017
+ .reduce(function (accumulator, next) {
1018
+ return accumulator.plus((0, module_kit_1.newAmount)(next.amount).blockchain(_this.segwit.legacy.units).value);
1019
+ }, new bignumber_1.default(0))
1020
+ .toString())
1021
+ });
1022
+ xpubExtendedPublicKey = (0, key_1.convertExtendedPublicKey)(extendedPublicKey, { format: 'encoded', type: 'xpub' });
1023
+ keyPair = this.bip32.fromBase58(xpubExtendedPublicKey.value);
1024
+ replaceByFee = (configuration === null || configuration === void 0 ? void 0 : configuration.replaceByFee) ? true : false;
1025
+ transaction.ins.forEach(function (tx) {
1026
+ var indexes = getPathIndexes(tx.derivationPath);
1027
+ var childNode = keyPair.derivePath(indexes.join('/'));
1028
+ var xOnlyPubkey = childNode.publicKey.length === 33 ? childNode.publicKey.slice(1, 33) : childNode.publicKey;
1029
+ var payment = _this.bitcoinJS.lib.payments.p2tr({
1030
+ internalPubkey: Buffer.from(xOnlyPubkey),
1031
+ network: _this.bitcoinJS.config.network
1032
+ });
1033
+ var inputCommon = {
1034
+ hash: tx.txId,
1035
+ index: tx.vout,
1036
+ sequence: replaceByFee ? 0xfffffffd : undefined,
1037
+ witnessUtxo: {
1038
+ script: payment.output,
1039
+ value: parseInt(tx.value, 10)
1040
+ }
1041
+ };
1042
+ var p2shOutput = payment.output;
1043
+ if (!p2shOutput) {
1044
+ throw new Error('no p2shOutput');
1045
+ }
1046
+ var fingerprintBuffer = Buffer.from(configuration.masterFingerprint.value, 'hex');
1047
+ psbt.addInput(__assign(__assign({}, inputCommon), { tapInternalKey: Buffer.from(xOnlyPubkey), tapBip32Derivation: [
1048
+ {
1049
+ leafHashes: [],
1050
+ path: tx.derivationPath,
1051
+ pubkey: Buffer.from(xOnlyPubkey),
1052
+ masterFingerprint: fingerprintBuffer
1053
+ }
1054
+ ] }));
1055
+ });
1056
+ transaction.outs.forEach(function (out, index) {
1057
+ psbt.addOutput({ address: out.recipient, value: parseInt(out.value, 10) });
1058
+ if (out.derivationPath) {
1059
+ psbt.addUnknownKeyValToOutput(index, {
1060
+ key: Buffer.from('dp'),
1061
+ value: Buffer.from(out.derivationPath, 'utf8')
1062
+ });
1063
+ }
1064
+ });
1065
+ return [2 /*return*/, (0, module_kit_1.newUnsignedTransaction)({ psbt: psbt.toHex() })];
730
1066
  }
731
- };
732
- const p2shOutput = payment.output;
733
- if (!p2shOutput) {
734
- throw new Error('no p2shOutput');
735
- }
736
- const fingerprintBuffer = Buffer.from(configuration.masterFingerprint.value, 'hex');
737
- psbt.addInput({
738
- ...inputCommon,
739
- tapInternalKey: Buffer.from(xOnlyPubkey),
740
- tapBip32Derivation: [
741
- {
742
- leafHashes: [],
743
- path: tx.derivationPath,
744
- pubkey: Buffer.from(xOnlyPubkey),
745
- masterFingerprint: fingerprintBuffer
746
- }
747
- ]
748
- });
749
- });
750
- transaction.outs.forEach((out, index) => {
751
- psbt.addOutput({ address: out.recipient, value: parseInt(out.value, 10) });
752
- if (out.derivationPath) {
753
- psbt.addUnknownKeyValToOutput(index, {
754
- key: Buffer.from('dp'),
755
- value: Buffer.from(out.derivationPath, 'utf8')
756
- });
757
- }
1067
+ });
758
1068
  });
759
- return (0, module_kit_1.newUnsignedTransaction)({ psbt: psbt.toHex() });
760
- }
761
- }
1069
+ };
1070
+ return BitcoinTaprootProtocolImpl;
1071
+ }());
762
1072
  exports.BitcoinTaprootProtocolImpl = BitcoinTaprootProtocolImpl;
763
1073
  // Factory
764
- function createBitcoinTaprootProtocol(options = {}) {
1074
+ function createBitcoinTaprootProtocol(options) {
1075
+ if (options === void 0) { options = {}; }
765
1076
  return new BitcoinTaprootProtocolImpl(options);
766
1077
  }
1078
+ exports.createBitcoinTaprootProtocol = createBitcoinTaprootProtocol;
767
1079
  //# sourceMappingURL=BitcoinTaprootProtocol.js.map