@wallfree-dev/bitcoin 0.13.42

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 (167) hide show
  1. package/LICENSE.md +7 -0
  2. package/index.d.ts +1 -0
  3. package/index.js +18 -0
  4. package/index.js.map +1 -0
  5. package/package.json +66 -0
  6. package/readme.md +121 -0
  7. package/v0/index.d.ts +14 -0
  8. package/v0/index.js +34 -0
  9. package/v0/index.js.map +1 -0
  10. package/v0/protocol/BitcoinAddress.d.ts +9 -0
  11. package/v0/protocol/BitcoinAddress.js +23 -0
  12. package/v0/protocol/BitcoinAddress.js.map +1 -0
  13. package/v0/protocol/BitcoinCryptoClient.d.ts +11 -0
  14. package/v0/protocol/BitcoinCryptoClient.js +91 -0
  15. package/v0/protocol/BitcoinCryptoClient.js.map +1 -0
  16. package/v0/protocol/BitcoinProtocol.d.ts +168 -0
  17. package/v0/protocol/BitcoinProtocol.js +1070 -0
  18. package/v0/protocol/BitcoinProtocol.js.map +1 -0
  19. package/v0/protocol/BitcoinProtocolOptions.d.ts +26 -0
  20. package/v0/protocol/BitcoinProtocolOptions.js +148 -0
  21. package/v0/protocol/BitcoinProtocolOptions.js.map +1 -0
  22. package/v0/protocol/BitcoinSegwitAddress.d.ts +7 -0
  23. package/v0/protocol/BitcoinSegwitAddress.js +41 -0
  24. package/v0/protocol/BitcoinSegwitAddress.js.map +1 -0
  25. package/v0/protocol/BitcoinSegwitProtocol.d.ts +29 -0
  26. package/v0/protocol/BitcoinSegwitProtocol.js +548 -0
  27. package/v0/protocol/BitcoinSegwitProtocol.js.map +1 -0
  28. package/v0/protocol/BitcoinTestnetProtocol.d.ts +7 -0
  29. package/v0/protocol/BitcoinTestnetProtocol.js +58 -0
  30. package/v0/protocol/BitcoinTestnetProtocol.js.map +1 -0
  31. package/v0/protocol/BitcoinTypes.d.ts +21 -0
  32. package/v0/protocol/BitcoinTypes.js +3 -0
  33. package/v0/protocol/BitcoinTypes.js.map +1 -0
  34. package/v0/serializer/schemas/v2/transaction-sign-request-bitcoin-segwit.json +0 -0
  35. package/v0/serializer/schemas/v2/transaction-sign-request-bitcoin.json +73 -0
  36. package/v0/serializer/schemas/v2/transaction-sign-response-bitcoin-segwit.json +0 -0
  37. package/v0/serializer/schemas/v2/transaction-sign-response-bitcoin.json +37 -0
  38. package/v0/serializer/schemas/v3/transaction-sign-request-bitcoin-segwit.json +29 -0
  39. package/v0/serializer/schemas/v3/transaction-sign-request-bitcoin.json +73 -0
  40. package/v0/serializer/schemas/v3/transaction-sign-response-bitcoin-segwit.json +19 -0
  41. package/v0/serializer/schemas/v3/transaction-sign-response-bitcoin.json +37 -0
  42. package/v0/serializer/validators/transaction-validator.d.ts +15 -0
  43. package/v0/serializer/validators/transaction-validator.js +81 -0
  44. package/v0/serializer/validators/transaction-validator.js.map +1 -0
  45. package/v0/serializer/validators/validators.d.ts +1 -0
  46. package/v0/serializer/validators/validators.js +151 -0
  47. package/v0/serializer/validators/validators.js.map +1 -0
  48. package/v0/types/signed-transaction-bitcoin-segwit.d.ts +5 -0
  49. package/v0/types/signed-transaction-bitcoin-segwit.js +3 -0
  50. package/v0/types/signed-transaction-bitcoin-segwit.js.map +1 -0
  51. package/v0/types/signed-transaction-bitcoin.d.ts +9 -0
  52. package/v0/types/signed-transaction-bitcoin.js +3 -0
  53. package/v0/types/signed-transaction-bitcoin.js.map +1 -0
  54. package/v0/types/transaction-bitcoin.d.ts +20 -0
  55. package/v0/types/transaction-bitcoin.js +3 -0
  56. package/v0/types/transaction-bitcoin.js.map +1 -0
  57. package/v0/types/unsigned-transaction-bitcoin-segwit.d.ts +7 -0
  58. package/v0/types/unsigned-transaction-bitcoin-segwit.js +3 -0
  59. package/v0/types/unsigned-transaction-bitcoin-segwit.js.map +1 -0
  60. package/v0/types/unsigned-transaction-bitcoin.d.ts +22 -0
  61. package/v0/types/unsigned-transaction-bitcoin.js +3 -0
  62. package/v0/types/unsigned-transaction-bitcoin.js.map +1 -0
  63. package/v1/block-explorer/BlockCypherBlockExplorer.d.ts +9 -0
  64. package/v1/block-explorer/BlockCypherBlockExplorer.js +72 -0
  65. package/v1/block-explorer/BlockCypherBlockExplorer.js.map +1 -0
  66. package/v1/data/BitcoinAddress.d.ts +7 -0
  67. package/v1/data/BitcoinAddress.js +20 -0
  68. package/v1/data/BitcoinAddress.js.map +1 -0
  69. package/v1/data/BitcoinSegwitAddress.d.ts +9 -0
  70. package/v1/data/BitcoinSegwitAddress.js +25 -0
  71. package/v1/data/BitcoinSegwitAddress.js.map +1 -0
  72. package/v1/data/BitcoinTaprootAddress.d.ts +9 -0
  73. package/v1/data/BitcoinTaprootAddress.js +57 -0
  74. package/v1/data/BitcoinTaprootAddress.js.map +1 -0
  75. package/v1/index.d.ts +25 -0
  76. package/v1/index.js +30 -0
  77. package/v1/index.js.map +1 -0
  78. package/v1/module/BitcoinModule.d.ts +18 -0
  79. package/v1/module/BitcoinModule.js +116 -0
  80. package/v1/module/BitcoinModule.js.map +1 -0
  81. package/v1/module.d.ts +3 -0
  82. package/v1/module.js +24 -0
  83. package/v1/module.js.map +1 -0
  84. package/v1/protocol/BitcoinCryptoClient.d.ts +12 -0
  85. package/v1/protocol/BitcoinCryptoClient.js +96 -0
  86. package/v1/protocol/BitcoinCryptoClient.js.map +1 -0
  87. package/v1/protocol/BitcoinProtocol.d.ts +84 -0
  88. package/v1/protocol/BitcoinProtocol.js +1312 -0
  89. package/v1/protocol/BitcoinProtocol.js.map +1 -0
  90. package/v1/protocol/BitcoinSegwitProtocol.d.ts +56 -0
  91. package/v1/protocol/BitcoinSegwitProtocol.js +863 -0
  92. package/v1/protocol/BitcoinSegwitProtocol.js.map +1 -0
  93. package/v1/protocol/BitcoinTaprootProtocol.d.ts +60 -0
  94. package/v1/protocol/BitcoinTaprootProtocol.js +1079 -0
  95. package/v1/protocol/BitcoinTaprootProtocol.js.map +1 -0
  96. package/v1/protocol/BitcoinTestnetProtocol.d.ts +10 -0
  97. package/v1/protocol/BitcoinTestnetProtocol.js +70 -0
  98. package/v1/protocol/BitcoinTestnetProtocol.js.map +1 -0
  99. package/v1/serializer/v3/schemas/converter/transaction-converter.d.ts +19 -0
  100. package/v1/serializer/v3/schemas/converter/transaction-converter.js +96 -0
  101. package/v1/serializer/v3/schemas/converter/transaction-converter.js.map +1 -0
  102. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-segwit.d.ts +4 -0
  103. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-segwit.js +3 -0
  104. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-segwit.js.map +1 -0
  105. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-taproot.d.ts +4 -0
  106. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-taproot.js +3 -0
  107. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin-taproot.js.map +1 -0
  108. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin.d.ts +4 -0
  109. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin.js +3 -0
  110. package/v1/serializer/v3/schemas/definitions/transaction-sign-request-bitcoin.js.map +1 -0
  111. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-segwit.d.ts +3 -0
  112. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-segwit.js +3 -0
  113. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-segwit.js.map +1 -0
  114. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-taproot.d.ts +3 -0
  115. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-taproot.js +3 -0
  116. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin-taproot.js.map +1 -0
  117. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin.d.ts +7 -0
  118. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin.js +3 -0
  119. package/v1/serializer/v3/schemas/definitions/transaction-sign-response-bitcoin.js.map +1 -0
  120. package/v1/serializer/v3/schemas/generated/transaction-sign-request-bitcoin-segwit.json +29 -0
  121. package/v1/serializer/v3/schemas/generated/transaction-sign-request-bitcoin-taproot.json +29 -0
  122. package/v1/serializer/v3/schemas/generated/transaction-sign-request-bitcoin.json +79 -0
  123. package/v1/serializer/v3/schemas/generated/transaction-sign-response-bitcoin-segwit.json +19 -0
  124. package/v1/serializer/v3/schemas/generated/transaction-sign-response-bitcoin-taproot.json +19 -0
  125. package/v1/serializer/v3/schemas/generated/transaction-sign-response-bitcoin.json +37 -0
  126. package/v1/serializer/v3/serializer-companion.d.ts +14 -0
  127. package/v1/serializer/v3/serializer-companion.js +219 -0
  128. package/v1/serializer/v3/serializer-companion.js.map +1 -0
  129. package/v1/serializer/v3/validators/transaction-validator.d.ts +7 -0
  130. package/v1/serializer/v3/validators/transaction-validator.js +56 -0
  131. package/v1/serializer/v3/validators/transaction-validator.js.map +1 -0
  132. package/v1/serializer/v3/validators/validators.d.ts +7 -0
  133. package/v1/serializer/v3/validators/validators.js +238 -0
  134. package/v1/serializer/v3/validators/validators.js.map +1 -0
  135. package/v1/types/bitcoinjs.d.ts +20 -0
  136. package/v1/types/bitcoinjs.js +3 -0
  137. package/v1/types/bitcoinjs.js.map +1 -0
  138. package/v1/types/crypto.d.ts +2 -0
  139. package/v1/types/crypto.js +3 -0
  140. package/v1/types/crypto.js.map +1 -0
  141. package/v1/types/indexer.d.ts +81 -0
  142. package/v1/types/indexer.js +3 -0
  143. package/v1/types/indexer.js.map +1 -0
  144. package/v1/types/key.d.ts +6 -0
  145. package/v1/types/key.js +3 -0
  146. package/v1/types/key.js.map +1 -0
  147. package/v1/types/protocol.d.ts +17 -0
  148. package/v1/types/protocol.js +3 -0
  149. package/v1/types/protocol.js.map +1 -0
  150. package/v1/types/transaction.d.ts +49 -0
  151. package/v1/types/transaction.js +3 -0
  152. package/v1/types/transaction.js.map +1 -0
  153. package/v1/utils/common.d.ts +2 -0
  154. package/v1/utils/common.js +28 -0
  155. package/v1/utils/common.js.map +1 -0
  156. package/v1/utils/key.d.ts +34 -0
  157. package/v1/utils/key.js +190 -0
  158. package/v1/utils/key.js.map +1 -0
  159. package/v1/utils/network.d.ts +2 -0
  160. package/v1/utils/network.js +22 -0
  161. package/v1/utils/network.js.map +1 -0
  162. package/v1/utils/protocol.d.ts +10 -0
  163. package/v1/utils/protocol.js +33 -0
  164. package/v1/utils/protocol.js.map +1 -0
  165. package/v1/utils/signature.d.ts +2 -0
  166. package/v1/utils/signature.js +34 -0
  167. package/v1/utils/signature.js.map +1 -0
@@ -0,0 +1,1079 @@
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
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
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
+ };
81
+ var __importDefault = (this && this.__importDefault) || function (mod) {
82
+ return (mod && mod.__esModule) ? mod : { "default": mod };
83
+ };
84
+ Object.defineProperty(exports, "__esModule", { value: true });
85
+ exports.createBitcoinTaprootProtocol = exports.BitcoinTaprootProtocolImpl = void 0;
86
+ var coinlib_core_1 = require("@wallfree-dev/coinlib-core");
87
+ var index_1 = __importDefault(require("@wallfree-dev/coinlib-core/dependencies/src/axios-0.19.0/index"));
88
+ var bignumber_1 = __importDefault(require("@wallfree-dev/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
89
+ var errors_1 = require("@wallfree-dev/coinlib-core/errors");
90
+ var module_kit_1 = require("@wallfree-dev/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("@wallfree-dev/crypto");
100
+ var secp256k1_1 = __importDefault(require("@bitcoinerlab/secp256k1"));
101
+ // Implementation
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;
108
+ this._isBitcoinProtocol = true;
109
+ this._isBitcoinTaprootProtocol = true;
110
+ this.bip32 = (0, bip32_1.BIP32Factory)(secp256k1_1.default);
111
+ this.options = (0, BitcoinProtocol_1.createBitcoinProtocolOptions)(options.network);
112
+ this.bitcoinJS = {
113
+ lib: bitcoinJS,
114
+ config: {
115
+ network: (0, network_1.getBitcoinJSNetwork)(this.options.network, bitcoinJS)
116
+ }
117
+ };
118
+ this.bitcoinJS.lib.initEccLib(secp256k1_1.default);
119
+ this.segwit = new BitcoinSegwitProtocol_1.BitcoinSegwitProtocolImpl(options);
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})$' }) }) });
121
+ }
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
+ }
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.');
170
+ }
171
+ return [2 /*return*/];
172
+ });
173
+ });
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) {
221
+ switch (publicKey.type) {
222
+ case 'pub':
223
+ return this.getAddressFromNonExtendedPublicKey(publicKey);
224
+ case 'xpub':
225
+ return this.getAddressFromExtendedPublicKey(publicKey);
226
+ default:
227
+ (0, coinlib_core_1.assertNever)(publicKey);
228
+ throw new errors_1.UnsupportedError(coinlib_core_1.Domain.BITCOIN, 'Public key type is not supported.');
229
+ }
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
+ });
242
+ });
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)];
248
+ });
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
+ ]];
487
+ }
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');
509
+ }
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)];
523
+ }
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
+ }];
599
+ }
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
+ }];
682
+ }
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.');
697
+ }
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])];
711
+ }
712
+ });
713
+ });
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
+ }];
730
+ }
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
+ ];
776
+ }
777
+ });
778
+ });
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
+ });
793
+ });
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 = {
802
+ type: 'xpriv',
803
+ format: 'hex',
804
+ value: hexNode.secretKey
805
+ };
806
+ return (0, key_1.convertExtendedSecretKey)(extendedSecretKey, { format: 'encoded', type: 'xprv' });
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
+ });
813
+ });
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
+ });
826
+ });
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
+ });
833
+ });
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
890
+ });
891
+ return [2 /*return*/, BitcoinTaprootAddress_1.BitcoinTaprootAddress.fromPayment(payment).asString()];
892
+ });
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() })];
1066
+ }
1067
+ });
1068
+ });
1069
+ };
1070
+ return BitcoinTaprootProtocolImpl;
1071
+ }());
1072
+ exports.BitcoinTaprootProtocolImpl = BitcoinTaprootProtocolImpl;
1073
+ // Factory
1074
+ function createBitcoinTaprootProtocol(options) {
1075
+ if (options === void 0) { options = {}; }
1076
+ return new BitcoinTaprootProtocolImpl(options);
1077
+ }
1078
+ exports.createBitcoinTaprootProtocol = createBitcoinTaprootProtocol;
1079
+ //# sourceMappingURL=BitcoinTaprootProtocol.js.map