@bitgo-beta/sdk-coin-avaxp 2.0.0

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 (113) hide show
  1. package/.eslintignore +5 -0
  2. package/.eslintrc.json +7 -0
  3. package/.mocharc.yml +8 -0
  4. package/CHANGELOG.md +168 -0
  5. package/LICENSE +191 -0
  6. package/README.md +39 -0
  7. package/dist/src/avaxp.d.ts +69 -0
  8. package/dist/src/avaxp.d.ts.map +1 -0
  9. package/dist/src/avaxp.js +248 -0
  10. package/dist/src/iface.d.ts +43 -0
  11. package/dist/src/iface.d.ts.map +1 -0
  12. package/dist/src/iface.js +3 -0
  13. package/dist/src/index.d.ts +5 -0
  14. package/dist/src/index.d.ts.map +1 -0
  15. package/dist/src/index.js +30 -0
  16. package/dist/src/lib/atomicTransactionBuilder.d.ts +33 -0
  17. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -0
  18. package/dist/src/lib/atomicTransactionBuilder.js +122 -0
  19. package/dist/src/lib/delegatorTxBuilder.d.ts +96 -0
  20. package/dist/src/lib/delegatorTxBuilder.d.ts.map +1 -0
  21. package/dist/src/lib/delegatorTxBuilder.js +287 -0
  22. package/dist/src/lib/errors.d.ts +8 -0
  23. package/dist/src/lib/errors.d.ts.map +1 -0
  24. package/dist/src/lib/errors.js +19 -0
  25. package/dist/src/lib/exportTxBuilder.d.ts +34 -0
  26. package/dist/src/lib/exportTxBuilder.d.ts.map +1 -0
  27. package/dist/src/lib/exportTxBuilder.js +88 -0
  28. package/dist/src/lib/iface.d.ts +58 -0
  29. package/dist/src/lib/iface.d.ts.map +1 -0
  30. package/dist/src/lib/iface.js +18 -0
  31. package/dist/src/lib/importInCTxBuilder.d.ts +48 -0
  32. package/dist/src/lib/importInCTxBuilder.d.ts.map +1 -0
  33. package/dist/src/lib/importInCTxBuilder.js +152 -0
  34. package/dist/src/lib/importTxBuilder.d.ts +18 -0
  35. package/dist/src/lib/importTxBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/importTxBuilder.js +67 -0
  37. package/dist/src/lib/index.d.ts +9 -0
  38. package/dist/src/lib/index.d.ts.map +1 -0
  39. package/dist/src/lib/index.js +29 -0
  40. package/dist/src/lib/keyPair.d.ts +59 -0
  41. package/dist/src/lib/keyPair.d.ts.map +1 -0
  42. package/dist/src/lib/keyPair.js +151 -0
  43. package/dist/src/lib/transaction.d.ts +81 -0
  44. package/dist/src/lib/transaction.d.ts.map +1 -0
  45. package/dist/src/lib/transaction.js +277 -0
  46. package/dist/src/lib/transactionBuilder.d.ts +122 -0
  47. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  48. package/dist/src/lib/transactionBuilder.js +224 -0
  49. package/dist/src/lib/transactionBuilderFactory.d.ts +42 -0
  50. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  51. package/dist/src/lib/transactionBuilderFactory.js +107 -0
  52. package/dist/src/lib/transferBuilder.d.ts +18 -0
  53. package/dist/src/lib/transferBuilder.d.ts.map +1 -0
  54. package/dist/src/lib/transferBuilder.js +31 -0
  55. package/dist/src/lib/utils.d.ts +152 -0
  56. package/dist/src/lib/utils.d.ts.map +1 -0
  57. package/dist/src/lib/utils.js +300 -0
  58. package/dist/src/lib/utxoEngine.d.ts +45 -0
  59. package/dist/src/lib/utxoEngine.d.ts.map +1 -0
  60. package/dist/src/lib/utxoEngine.js +89 -0
  61. package/dist/src/lib/validatorTxBuilder.d.ts +37 -0
  62. package/dist/src/lib/validatorTxBuilder.d.ts.map +1 -0
  63. package/dist/src/lib/validatorTxBuilder.js +69 -0
  64. package/dist/src/tavaxp.d.ts +9 -0
  65. package/dist/src/tavaxp.d.ts.map +1 -0
  66. package/dist/src/tavaxp.js +14 -0
  67. package/dist/test/resources/avaxp.d.ts +178 -0
  68. package/dist/test/resources/avaxp.d.ts.map +1 -0
  69. package/dist/test/resources/avaxp.js +953 -0
  70. package/dist/test/resources/errors.d.ts +18 -0
  71. package/dist/test/resources/errors.d.ts.map +1 -0
  72. package/dist/test/resources/errors.js +21 -0
  73. package/dist/test/resources/keychains.d.ts +18 -0
  74. package/dist/test/resources/keychains.d.ts.map +1 -0
  75. package/dist/test/resources/keychains.js +30 -0
  76. package/dist/test/resources/tx/importC.d.ts +29 -0
  77. package/dist/test/resources/tx/importC.d.ts.map +1 -0
  78. package/dist/test/resources/tx/importC.js +42 -0
  79. package/dist/test/resources/tx/importP.d.ts +29 -0
  80. package/dist/test/resources/tx/importP.d.ts.map +1 -0
  81. package/dist/test/resources/tx/importP.js +42 -0
  82. package/dist/test/unit/avaxp.d.ts +2 -0
  83. package/dist/test/unit/avaxp.d.ts.map +1 -0
  84. package/dist/test/unit/avaxp.js +553 -0
  85. package/dist/test/unit/lib/exportP2CTxBuilder.d.ts +2 -0
  86. package/dist/test/unit/lib/exportP2CTxBuilder.d.ts.map +1 -0
  87. package/dist/test/unit/lib/exportP2CTxBuilder.js +173 -0
  88. package/dist/test/unit/lib/importC2PTxBuilder.d.ts +2 -0
  89. package/dist/test/unit/lib/importC2PTxBuilder.d.ts.map +1 -0
  90. package/dist/test/unit/lib/importC2PTxBuilder.js +85 -0
  91. package/dist/test/unit/lib/importP2CTxBuilder.d.ts +2 -0
  92. package/dist/test/unit/lib/importP2CTxBuilder.d.ts.map +1 -0
  93. package/dist/test/unit/lib/importP2CTxBuilder.js +125 -0
  94. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  95. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  96. package/dist/test/unit/lib/keyPair.js +172 -0
  97. package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
  98. package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
  99. package/dist/test/unit/lib/signFlowTestSuit.js +80 -0
  100. package/dist/test/unit/lib/transactionBuilderFactory.d.ts +2 -0
  101. package/dist/test/unit/lib/transactionBuilderFactory.d.ts.map +1 -0
  102. package/dist/test/unit/lib/transactionBuilderFactory.js +114 -0
  103. package/dist/test/unit/lib/utils.d.ts +2 -0
  104. package/dist/test/unit/lib/utils.d.ts.map +1 -0
  105. package/dist/test/unit/lib/utils.js +69 -0
  106. package/dist/test/unit/lib/utxoEngine.d.ts +2 -0
  107. package/dist/test/unit/lib/utxoEngine.d.ts.map +1 -0
  108. package/dist/test/unit/lib/utxoEngine.js +168 -0
  109. package/dist/test/unit/lib/validateTxBuilder.d.ts +2 -0
  110. package/dist/test/unit/lib/validateTxBuilder.d.ts.map +1 -0
  111. package/dist/test/unit/lib/validateTxBuilder.js +318 -0
  112. package/dist/tsconfig.tsbuildinfo +10238 -0
  113. package/package.json +62 -0
@@ -0,0 +1,152 @@
1
+ /// <reference types="node" />
2
+ import { BaseUtils, Entry } from '@bitgo-beta/sdk-core';
3
+ import { Buffer as BufferAvax } from 'avalanche';
4
+ import { NodeIDStringToBuffer } from 'avalanche/dist/utils';
5
+ import { BaseTx, TransferableOutput } from 'avalanche/dist/apis/platformvm';
6
+ import { Credential } from 'avalanche/dist/common/credentials';
7
+ import { AvalancheNetwork } from '@bitgo-beta/statics';
8
+ import { Signature } from 'avalanche/dist/common';
9
+ import { Output, Tx } from './iface';
10
+ export declare class Utils implements BaseUtils {
11
+ private binTools;
12
+ cb58Decode: (bytes: string | BufferAvax) => BufferAvax;
13
+ cb58Encode: (bytes: BufferAvax) => string;
14
+ stringToBuffer: (str: string) => BufferAvax;
15
+ bufferToString: (buff: BufferAvax) => string;
16
+ NodeIDStringToBuffer: typeof NodeIDStringToBuffer;
17
+ addressToString: (hrp: string, chainid: string, bytes: BufferAvax) => string;
18
+ includeIn(walletAddresses: string[], otxoOutputAddresses: string[]): boolean;
19
+ /**
20
+ * Checks if it is a valid address no illegal characters
21
+ *
22
+ * @param {string} address - address to be validated
23
+ * @returns {boolean} - the validation result
24
+ */
25
+ /** @inheritdoc */
26
+ isValidAddress(address: string | string[]): boolean;
27
+ private isValidAddressRegex;
28
+ /**
29
+ * Checks if it is a valid blockId with length 66 including 0x
30
+ *
31
+ * @param {string} hash - blockId to be validated
32
+ * @returns {boolean} - the validation result
33
+ */
34
+ /** @inheritdoc */
35
+ isValidBlockId(hash: string): boolean;
36
+ /**
37
+ * Checks if the string is a valid protocol public key or
38
+ * extended public key.
39
+ *
40
+ * @param {string} pub - the public key to be validated
41
+ * @returns {boolean} - the validation result
42
+ */
43
+ isValidPublicKey(pub: string): boolean;
44
+ parseAddress: (pub: string) => BufferAvax;
45
+ /**
46
+ * Returns whether or not the string is a valid protocol private key, or extended
47
+ * private key.
48
+ *
49
+ * The protocol key format is described in the @stacks/transactions npm package, in the
50
+ * createStacksPrivateKey function:
51
+ * https://github.com/blockstack/stacks.js/blob/master/packages/transactions/src/keys.ts#L125
52
+ *
53
+ * @param {string} prv - the private key (or extended private key) to be validated
54
+ * @returns {boolean} - the validation result
55
+ */
56
+ isValidPrivateKey(prv: string): boolean;
57
+ /**
58
+ * Returns whether or not the string is a composed of hex chars only
59
+ *
60
+ * @param {string} maybe - the string to be validated
61
+ * @returns {boolean} - the validation result
62
+ */
63
+ allHexChars(maybe: string): boolean;
64
+ /** @inheritdoc */
65
+ isValidSignature(signature: string): boolean;
66
+ /** @inheritdoc */
67
+ isValidTransactionId(txId: string): boolean;
68
+ getCredentials(tx: BaseTx): Credential[];
69
+ /**
70
+ * Avaxp wrapper to create signature and return it for credentials using Avalanche's buffer
71
+ * @param network
72
+ * @param message
73
+ * @param prv
74
+ * @return signature
75
+ */
76
+ createSignatureAvaxBuffer(network: AvalancheNetwork, message: BufferAvax, prv: BufferAvax): BufferAvax;
77
+ /**
78
+ * Avaxp wrapper to create signature and return it for credentials
79
+ * @param network
80
+ * @param message
81
+ * @param prv
82
+ * @return signature
83
+ */
84
+ createSignature(network: AvalancheNetwork, message: Buffer, prv: Buffer): Buffer;
85
+ /**
86
+ * Avaxp wrapper to verify signature using Avalanche's buffer
87
+ * @param network
88
+ * @param message
89
+ * @param signature
90
+ * @param prv
91
+ * @return true if it's verify successful
92
+ */
93
+ verifySignatureAvaxBuffer(network: AvalancheNetwork, message: BufferAvax, signature: BufferAvax, prv: BufferAvax): boolean;
94
+ /**
95
+ * Avaxp wrapper to verify signature
96
+ * @param network
97
+ * @param message
98
+ * @param signature
99
+ * @param prv
100
+ * @return true if it's verify successful
101
+ */
102
+ verifySignature(network: AvalancheNetwork, message: Buffer, signature: Buffer, prv: Buffer): boolean;
103
+ createSig(sigHex: string): Signature;
104
+ /**
105
+ * Avaxp wrapper to recovery signature using Avalanche's buffer
106
+ * @param network
107
+ * @param message
108
+ * @param signature
109
+ * @return
110
+ */
111
+ recoverySignatureAvaxBuffer(network: AvalancheNetwork, message: BufferAvax, signature: BufferAvax): BufferAvax;
112
+ /**
113
+ * Avaxp wrapper to verify signature
114
+ * @param network
115
+ * @param message
116
+ * @param signature
117
+ * @return true if it's verify successful
118
+ */
119
+ recoverySignature(network: AvalancheNetwork, message: Buffer, signature: Buffer): Buffer;
120
+ sha256(buf: Uint8Array): Buffer;
121
+ /**
122
+ * Check the raw transaction has a valid format in the blockchain context, throw otherwise.
123
+ * It's to reuse in TransactionBuilder and TransactionBuilderFactory
124
+ *
125
+ * @param rawTransaction Transaction as hex string
126
+ */
127
+ validateRawTransaction(rawTransaction: string): void;
128
+ /**
129
+ * Check if tx is for the blockchainId
130
+ *
131
+ * @param {Tx} tx
132
+ * @param {string} blockchainId
133
+ * @returns true if tx is for blockchainId
134
+ */
135
+ isTransactionOf(tx: Tx, blockchainId: string): boolean;
136
+ /**
137
+ * Check if Output is from PVM.
138
+ * Output could be EVM or PVM output.
139
+ * @param {Output} output
140
+ * @returns {boolean} output is TransferableOutput
141
+ */
142
+ isTransferableOutput(output: Output): output is TransferableOutput;
143
+ /**
144
+ * Return a mapper function to that network address representation.
145
+ * @param network required to stringify addresses
146
+ * @return mapper function
147
+ */
148
+ mapOutputToEntry(network: AvalancheNetwork): (Output: any) => Entry;
149
+ }
150
+ declare const utils: Utils;
151
+ export default utils;
152
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":";AAAA,OAAO,EAIL,SAAS,EAGT,KAAK,EACN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAgB,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAgB,MAAM,EAAyB,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACjH,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAErC,qBAAa,KAAM,YAAW,SAAS;IACrC,OAAO,CAAC,QAAQ,CAA0B;IACnC,UAAU,6CAA4B;IACtC,UAAU,gCAA4B;IACtC,cAAc,8BAAgC;IAC9C,cAAc,+BAAgC;IAC9C,oBAAoB,8BAAwB;IAC5C,eAAe,8DAAiC;IAEhD,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,GAAG,OAAO;IAInF;;;;;OAKG;IACH,kBAAkB;IAClB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;IAYnD,OAAO,CAAC,mBAAmB;IAI3B;;;;;OAKG;IACH,kBAAkB;IAClB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;;;OAMG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAoC/B,YAAY,QAAS,MAAM,KAAG,UAAU,CAAuC;IAEtF;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAUvC;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAInC,kBAAkB;IAClB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI5C,kBAAkB;IAClB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI3C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,EAAE;IAIxC;;;;;;OAMG;IACH,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU;IAMtG;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAIhF;;;;;;;OAOG;IACH,yBAAyB,CACvB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,EACrB,GAAG,EAAE,UAAU,GACd,OAAO;IAMV;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IASpG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAMpC;;;;;;OAMG;IACH,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU;IAK9G;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAIxF,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM;IAI/B;;;;;OAKG;IACH,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IASpD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAItD;;;;;OAKG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,kBAAkB;IAIlE;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,CAAC,MAAM,KAAA,KAAK,KAAK;CAwB/D;AAED,QAAA,MAAM,KAAK,OAAc,CAAC;AAE1B,eAAe,KAAK,CAAC"}
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.Utils = void 0;
23
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
24
+ const avalanche_1 = require("avalanche");
25
+ const utils_1 = require("avalanche/dist/utils");
26
+ const elliptic_1 = require("elliptic");
27
+ const platformvm_1 = require("avalanche/dist/apis/platformvm");
28
+ const keychain_1 = require("avalanche/dist/apis/platformvm/keychain");
29
+ const common_1 = require("avalanche/dist/common");
30
+ const createHash = __importStar(require("create-hash"));
31
+ class Utils {
32
+ constructor() {
33
+ this.binTools = avalanche_1.BinTools.getInstance();
34
+ this.cb58Decode = this.binTools.cb58Decode;
35
+ this.cb58Encode = this.binTools.cb58Encode;
36
+ this.stringToBuffer = this.binTools.stringToBuffer;
37
+ this.bufferToString = this.binTools.bufferToString;
38
+ this.NodeIDStringToBuffer = utils_1.NodeIDStringToBuffer;
39
+ this.addressToString = this.binTools.addressToString;
40
+ this.parseAddress = (pub) => this.binTools.stringToAddress(pub);
41
+ }
42
+ includeIn(walletAddresses, otxoOutputAddresses) {
43
+ return walletAddresses.map((a) => otxoOutputAddresses.includes(a)).reduce((a, b) => a && b, true);
44
+ }
45
+ /**
46
+ * Checks if it is a valid address no illegal characters
47
+ *
48
+ * @param {string} address - address to be validated
49
+ * @returns {boolean} - the validation result
50
+ */
51
+ /** @inheritdoc */
52
+ isValidAddress(address) {
53
+ const addressArr = Array.isArray(address) ? address : address.split('~');
54
+ for (const address of addressArr) {
55
+ if (!this.isValidAddressRegex(address)) {
56
+ return false;
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ isValidAddressRegex(address) {
62
+ return /^(^P||NodeID)-[a-zA-Z0-9]+$/.test(address);
63
+ }
64
+ /**
65
+ * Checks if it is a valid blockId with length 66 including 0x
66
+ *
67
+ * @param {string} hash - blockId to be validated
68
+ * @returns {boolean} - the validation result
69
+ */
70
+ /** @inheritdoc */
71
+ isValidBlockId(hash) {
72
+ return this.binTools.isCB58(hash) && this.binTools.b58ToBuffer(hash).length === 36;
73
+ }
74
+ /**
75
+ * Checks if the string is a valid protocol public key or
76
+ * extended public key.
77
+ *
78
+ * @param {string} pub - the public key to be validated
79
+ * @returns {boolean} - the validation result
80
+ */
81
+ isValidPublicKey(pub) {
82
+ if (sdk_core_1.isValidXpub(pub))
83
+ return true;
84
+ let pubBuf;
85
+ if (pub.length === 50) {
86
+ try {
87
+ pubBuf = utils.cb58Decode(pub);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ else {
94
+ if (pub.length !== 66 && pub.length !== 130)
95
+ return false;
96
+ const firstByte = pub.slice(0, 2);
97
+ // uncompressed public key
98
+ if (pub.length === 130 && firstByte !== '04')
99
+ return false;
100
+ // compressed public key
101
+ if (pub.length === 66 && firstByte !== '02' && firstByte !== '03')
102
+ return false;
103
+ if (!this.allHexChars(pub))
104
+ return false;
105
+ pubBuf = avalanche_1.Buffer.from(pub, 'hex');
106
+ }
107
+ // validate the public key
108
+ const secp256k1 = new elliptic_1.ec('secp256k1');
109
+ try {
110
+ const keyPair = secp256k1.keyFromPublic(pubBuf);
111
+ const { result } = keyPair.validate();
112
+ return result;
113
+ }
114
+ catch (e) {
115
+ return false;
116
+ }
117
+ }
118
+ /**
119
+ * Returns whether or not the string is a valid protocol private key, or extended
120
+ * private key.
121
+ *
122
+ * The protocol key format is described in the @stacks/transactions npm package, in the
123
+ * createStacksPrivateKey function:
124
+ * https://github.com/blockstack/stacks.js/blob/master/packages/transactions/src/keys.ts#L125
125
+ *
126
+ * @param {string} prv - the private key (or extended private key) to be validated
127
+ * @returns {boolean} - the validation result
128
+ */
129
+ isValidPrivateKey(prv) {
130
+ if (sdk_core_1.isValidXprv(prv))
131
+ return true;
132
+ if (prv.length !== 64 && prv.length !== 66)
133
+ return false;
134
+ if (prv.length === 66 && prv.slice(64) !== '01')
135
+ return false;
136
+ return this.allHexChars(prv);
137
+ }
138
+ /**
139
+ * Returns whether or not the string is a composed of hex chars only
140
+ *
141
+ * @param {string} maybe - the string to be validated
142
+ * @returns {boolean} - the validation result
143
+ */
144
+ allHexChars(maybe) {
145
+ return /^([0-9a-f])+$/i.test(maybe);
146
+ }
147
+ /** @inheritdoc */
148
+ isValidSignature(signature) {
149
+ throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
150
+ }
151
+ /** @inheritdoc */
152
+ isValidTransactionId(txId) {
153
+ throw new sdk_core_1.NotImplementedError('isValidTransactionId not implemented');
154
+ }
155
+ getCredentials(tx) {
156
+ return tx.getIns().map((ins) => platformvm_1.SelectCredentialClass(ins.getInput().getCredentialID()));
157
+ }
158
+ /**
159
+ * Avaxp wrapper to create signature and return it for credentials using Avalanche's buffer
160
+ * @param network
161
+ * @param message
162
+ * @param prv
163
+ * @return signature
164
+ */
165
+ createSignatureAvaxBuffer(network, message, prv) {
166
+ const ky = new keychain_1.KeyPair(network.hrp, network.networkID.toString());
167
+ ky.importKey(prv);
168
+ return ky.sign(message);
169
+ }
170
+ /**
171
+ * Avaxp wrapper to create signature and return it for credentials
172
+ * @param network
173
+ * @param message
174
+ * @param prv
175
+ * @return signature
176
+ */
177
+ createSignature(network, message, prv) {
178
+ return Buffer.from(this.createSignatureAvaxBuffer(network, avalanche_1.Buffer.from(message), avalanche_1.Buffer.from(prv)));
179
+ }
180
+ /**
181
+ * Avaxp wrapper to verify signature using Avalanche's buffer
182
+ * @param network
183
+ * @param message
184
+ * @param signature
185
+ * @param prv
186
+ * @return true if it's verify successful
187
+ */
188
+ verifySignatureAvaxBuffer(network, message, signature, prv) {
189
+ const ky = new keychain_1.KeyPair(network.hrp, network.networkID.toString());
190
+ ky.importKey(prv);
191
+ return ky.verify(message, signature);
192
+ }
193
+ /**
194
+ * Avaxp wrapper to verify signature
195
+ * @param network
196
+ * @param message
197
+ * @param signature
198
+ * @param prv
199
+ * @return true if it's verify successful
200
+ */
201
+ verifySignature(network, message, signature, prv) {
202
+ return this.verifySignatureAvaxBuffer(network, avalanche_1.Buffer.from(message), avalanche_1.Buffer.from(signature), avalanche_1.Buffer.from(prv));
203
+ }
204
+ createSig(sigHex) {
205
+ const sig = new common_1.Signature();
206
+ sig.fromBuffer(avalanche_1.Buffer.from(sigHex.padStart(130, '0'), 'hex'));
207
+ return sig;
208
+ }
209
+ /**
210
+ * Avaxp wrapper to recovery signature using Avalanche's buffer
211
+ * @param network
212
+ * @param message
213
+ * @param signature
214
+ * @return
215
+ */
216
+ recoverySignatureAvaxBuffer(network, message, signature) {
217
+ const ky = new keychain_1.KeyPair(network.hrp, network.networkID.toString());
218
+ return ky.recover(message, signature);
219
+ }
220
+ /**
221
+ * Avaxp wrapper to verify signature
222
+ * @param network
223
+ * @param message
224
+ * @param signature
225
+ * @return true if it's verify successful
226
+ */
227
+ recoverySignature(network, message, signature) {
228
+ return Buffer.from(this.recoverySignatureAvaxBuffer(network, avalanche_1.Buffer.from(message), avalanche_1.Buffer.from(signature)));
229
+ }
230
+ sha256(buf) {
231
+ return createHash.default('sha256').update(buf).digest();
232
+ }
233
+ /**
234
+ * Check the raw transaction has a valid format in the blockchain context, throw otherwise.
235
+ * It's to reuse in TransactionBuilder and TransactionBuilderFactory
236
+ *
237
+ * @param rawTransaction Transaction as hex string
238
+ */
239
+ validateRawTransaction(rawTransaction) {
240
+ if (!rawTransaction) {
241
+ throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
242
+ }
243
+ if (!utils.allHexChars(rawTransaction)) {
244
+ throw new sdk_core_1.ParseTransactionError('Raw transaction is not hex string');
245
+ }
246
+ }
247
+ /**
248
+ * Check if tx is for the blockchainId
249
+ *
250
+ * @param {Tx} tx
251
+ * @param {string} blockchainId
252
+ * @returns true if tx is for blockchainId
253
+ */
254
+ isTransactionOf(tx, blockchainId) {
255
+ return utils.cb58Encode(tx.getUnsignedTx().getTransaction().getBlockchainID()) === blockchainId;
256
+ }
257
+ /**
258
+ * Check if Output is from PVM.
259
+ * Output could be EVM or PVM output.
260
+ * @param {Output} output
261
+ * @returns {boolean} output is TransferableOutput
262
+ */
263
+ isTransferableOutput(output) {
264
+ return 'getOutput' in output;
265
+ }
266
+ /**
267
+ * Return a mapper function to that network address representation.
268
+ * @param network required to stringify addresses
269
+ * @return mapper function
270
+ */
271
+ mapOutputToEntry(network) {
272
+ return (output) => {
273
+ if (this.isTransferableOutput(output)) {
274
+ const amountOutput = output.getOutput();
275
+ const address = amountOutput
276
+ .getAddresses()
277
+ .map((a) => this.addressToString(network.hrp, network.alias, a))
278
+ .sort()
279
+ .join('~');
280
+ return {
281
+ value: amountOutput.getAmount().toString(),
282
+ address,
283
+ };
284
+ }
285
+ else {
286
+ const evmOutput = output;
287
+ return {
288
+ // it should be evmOuput.getAmount(), but it returns a 0.
289
+ value: new avalanche_1.BN(evmOutput.amount).toString(),
290
+ // C-Chain address.
291
+ address: '0x' + evmOutput.getAddressString(),
292
+ };
293
+ }
294
+ };
295
+ }
296
+ }
297
+ exports.Utils = Utils;
298
+ const utils = new Utils();
299
+ exports.default = utils;
300
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtREFROEI7QUFDOUIseUNBQStEO0FBQy9ELGdEQUE0RDtBQUM1RCx1Q0FBOEI7QUFDOUIsK0RBQWlIO0FBRWpILHNFQUFpRjtBQUVqRixrREFBa0Q7QUFDbEQsd0RBQTBDO0FBSTFDLE1BQWEsS0FBSztJQUFsQjtRQUNVLGFBQVEsR0FBRyxvQkFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25DLGVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUN0QyxlQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFDdEMsbUJBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQztRQUM5QyxtQkFBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDO1FBQzlDLHlCQUFvQixHQUFHLDRCQUFvQixDQUFDO1FBQzVDLG9CQUFlLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFtRmhELGlCQUFZLEdBQUcsQ0FBQyxHQUFXLEVBQWMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBNk14RixDQUFDO0lBOVJRLFNBQVMsQ0FBQyxlQUF5QixFQUFFLG1CQUE2QjtRQUN2RSxPQUFPLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUVEOzs7OztPQUtHO0lB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XG4gIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIEJhc2VVdGlscyxcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIFBhcnNlVHJhbnNhY3Rpb25FcnJvcixcbiAgRW50cnksXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEJpblRvb2xzLCBCTiwgQnVmZmVyIGFzIEJ1ZmZlckF2YXggfSBmcm9tICdhdmFsYW5jaGUnO1xuaW1wb3J0IHsgTm9kZUlEU3RyaW5nVG9CdWZmZXIgfSBmcm9tICdhdmFsYW5jaGUvZGlzdC91dGlscyc7XG5pbXBvcnQgeyBlYyB9IGZyb20gJ2VsbGlwdGljJztcbmltcG9ydCB7IEFtb3VudE91dHB1dCwgQmFzZVR4LCBTZWxlY3RDcmVkZW50aWFsQ2xhc3MsIFRyYW5zZmVyYWJsZU91dHB1dCB9IGZyb20gJ2F2YWxhbmNoZS9kaXN0L2FwaXMvcGxhdGZvcm12bSc7XG5pbXBvcnQgeyBDcmVkZW50aWFsIH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvY29tbW9uL2NyZWRlbnRpYWxzJztcbmltcG9ydCB7IEtleVBhaXIgYXMgS2V5UGFpckF2YXggfSBmcm9tICdhdmFsYW5jaGUvZGlzdC9hcGlzL3BsYXRmb3Jtdm0va2V5Y2hhaW4nO1xuaW1wb3J0IHsgQXZhbGFuY2hlTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgU2lnbmF0dXJlIH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvY29tbW9uJztcbmltcG9ydCAqIGFzIGNyZWF0ZUhhc2ggZnJvbSAnY3JlYXRlLWhhc2gnO1xuaW1wb3J0IHsgRVZNT3V0cHV0IH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvYXBpcy9ldm0nO1xuaW1wb3J0IHsgT3V0cHV0LCBUeCB9IGZyb20gJy4vaWZhY2UnO1xuXG5leHBvcnQgY2xhc3MgVXRpbHMgaW1wbGVtZW50cyBCYXNlVXRpbHMge1xuICBwcml2YXRlIGJpblRvb2xzID0gQmluVG9vbHMuZ2V0SW5zdGFuY2UoKTtcbiAgcHVibGljIGNiNThEZWNvZGUgPSB0aGlzLmJpblRvb2xzLmNiNThEZWNvZGU7XG4gIHB1YmxpYyBjYjU4RW5jb2RlID0gdGhpcy5iaW5Ub29scy5jYjU4RW5jb2RlO1xuICBwdWJsaWMgc3RyaW5nVG9CdWZmZXIgPSB0aGlzLmJpblRvb2xzLnN0cmluZ1RvQnVmZmVyO1xuICBwdWJsaWMgYnVmZmVyVG9TdHJpbmcgPSB0aGlzLmJpblRvb2xzLmJ1ZmZlclRvU3RyaW5nO1xuICBwdWJsaWMgTm9kZUlEU3RyaW5nVG9CdWZmZXIgPSBOb2RlSURTdHJpbmdUb0J1ZmZlcjtcbiAgcHVibGljIGFkZHJlc3NUb1N0cmluZyA9IHRoaXMuYmluVG9vbHMuYWRkcmVzc1RvU3RyaW5nO1xuXG4gIHB1YmxpYyBpbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzOiBzdHJpbmdbXSwgb3R4b091dHB1dEFkZHJlc3Nlczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICByZXR1cm4gd2FsbGV0QWRkcmVzc2VzLm1hcCgoYSkgPT4gb3R4b091dHB1dEFkZHJlc3Nlcy5pbmNsdWRlcyhhKSkucmVkdWNlKChhLCBiKSA9PiBhICYmIGIsIHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBpdCBpcyBhIHZhbGlkIGFkZHJlc3Mgbm8gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gYWRkcmVzcyB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nIHwgc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICBjb25zdCBhZGRyZXNzQXJyOiBzdHJpbmdbXSA9IEFycmF5LmlzQXJyYXkoYWRkcmVzcykgPyBhZGRyZXNzIDogYWRkcmVzcy5zcGxpdCgnficpO1xuXG4gICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGFkZHJlc3NBcnIpIHtcbiAgICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzc1JlZ2V4KGFkZHJlc3MpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZEFkZHJlc3NSZWdleChhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gL14oXlB8fE5vZGVJRCktW2EtekEtWjAtOV0rJC8udGVzdChhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgaXQgaXMgYSB2YWxpZCBibG9ja0lkIHdpdGggbGVuZ3RoIDY2IGluY2x1ZGluZyAweFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGFzaCAtIGJsb2NrSWQgdG8gYmUgdmFsaWRhdGVkXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRCbG9ja0lkKGhhc2g6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmJpblRvb2xzLmlzQ0I1OChoYXNoKSAmJiB0aGlzLmJpblRvb2xzLmI1OFRvQnVmZmVyKGhhc2gpLmxlbmd0aCA9PT0gMzY7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBzdHJpbmcgaXMgYSB2YWxpZCBwcm90b2NvbCBwdWJsaWMga2V5IG9yXG4gICAqIGV4dGVuZGVkIHB1YmxpYyBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwdWIgLSB0aGUgIHB1YmxpYyBrZXkgdG8gYmUgdmFsaWRhdGVkXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFB1YmxpY0tleShwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChpc1ZhbGlkWHB1YihwdWIpKSByZXR1cm4gdHJ1ZTtcblxuICAgIGxldCBwdWJCdWY7XG4gICAgaWYgKHB1Yi5sZW5ndGggPT09IDUwKSB7XG4gICAgICB0cnkge1xuICAgICAgICBwdWJCdWYgPSB1dGlscy5jYjU4RGVjb2RlKHB1Yik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocHViLmxlbmd0aCAhPT0gNjYgJiYgcHViLmxlbmd0aCAhPT0gMTMwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGNvbnN0IGZpcnN0Qnl0ZSA9IHB1Yi5zbGljZSgwLCAyKTtcblxuICAgICAgLy8gdW5jb21wcmVzc2VkIHB1YmxpYyBrZXlcbiAgICAgIGlmIChwdWIubGVuZ3RoID09PSAxMzAgJiYgZmlyc3RCeXRlICE9PSAnMDQnKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIGNvbXByZXNzZWQgcHVibGljIGtleVxuICAgICAgaWYgKHB1Yi5sZW5ndGggPT09IDY2ICYmIGZpcnN0Qnl0ZSAhPT0gJzAyJyAmJiBmaXJzdEJ5dGUgIT09ICcwMycpIHJldHVybiBmYWxzZTtcblxuICAgICAgaWYgKCF0aGlzLmFsbEhleENoYXJzKHB1YikpIHJldHVybiBmYWxzZTtcblxuICAgICAgcHViQnVmID0gQnVmZmVyQXZheC5mcm9tKHB1YiwgJ2hleCcpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgcHVibGljIGtleVxuICAgIGNvbnN0IHNlY3AyNTZrMSA9IG5ldyBlYygnc2VjcDI1NmsxJyk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBzZWNwMjU2azEua2V5RnJvbVB1YmxpYyhwdWJCdWYpO1xuICAgICAgY29uc3QgeyByZXN1bHQgfSA9IGtleVBhaXIudmFsaWRhdGUoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBwYXJzZUFkZHJlc3MgPSAocHViOiBzdHJpbmcpOiBCdWZmZXJBdmF4ID0+IHRoaXMuYmluVG9vbHMuc3RyaW5nVG9BZGRyZXNzKHB1Yik7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHN0cmluZyBpcyBhIHZhbGlkIHByb3RvY29sIHByaXZhdGUga2V5LCBvciBleHRlbmRlZFxuICAgKiBwcml2YXRlIGtleS5cbiAgICpcbiAgICogVGhlIHByb3RvY29sIGtleSBmb3JtYXQgaXMgZGVzY3JpYmVkIGluIHRoZSBAc3RhY2tzL3RyYW5zYWN0aW9ucyBucG0gcGFja2FnZSwgaW4gdGhlXG4gICAqIGNyZWF0ZVN0YWNrc1ByaXZhdGVLZXkgZnVuY3Rpb246XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibG9ja3N0YWNrL3N0YWNrcy5qcy9ibG9iL21hc3Rlci9wYWNrYWdlcy90cmFuc2FjdGlvbnMvc3JjL2tleXMudHMjTDEyNVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJ2IC0gdGhlIHByaXZhdGUga2V5IChvciBleHRlbmRlZCBwcml2YXRlIGtleSkgdG8gYmUgdmFsaWRhdGVkXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFByaXZhdGVLZXkocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoaXNWYWxpZFhwcnYocHJ2KSkgcmV0dXJuIHRydWU7XG5cbiAgICBpZiAocHJ2Lmxlbmd0aCAhPT0gNjQgJiYgcHJ2Lmxlbmd0aCAhPT0gNjYpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChwcnYubGVuZ3RoID09PSA2NiAmJiBwcnYuc2xpY2UoNjQpICE9PSAnMDEnKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gdGhpcy5hbGxIZXhDaGFycyhwcnYpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHN0cmluZyBpcyBhIGNvbXBvc2VkIG9mIGhleCBjaGFycyBvbmx5XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtYXliZSAtIHRoZSAgc3RyaW5nIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGFsbEhleENoYXJzKG1heWJlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gL14oWzAtOWEtZl0pKyQvaS50ZXN0KG1heWJlKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkU2lnbmF0dXJlKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoJ2lzVmFsaWRTaWduYXR1cmUgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFRyYW5zYWN0aW9uSWQodHhJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoJ2lzVmFsaWRUcmFuc2FjdGlvbklkIG5vdCBpbXBsZW1lbnRlZCcpO1xuICB9XG5cbiAgZ2V0Q3JlZGVudGlhbHModHg6IEJhc2VUeCk6IENyZWRlbnRpYWxbXSB7XG4gICAgcmV0dXJuIHR4LmdldElucygpLm1hcCgoaW5zKSA9PiBTZWxlY3RDcmVkZW50aWFsQ2xhc3MoaW5zLmdldElucHV0KCkuZ2V0Q3JlZGVudGlhbElEKCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdmF4cCB3cmFwcGVyIHRvIGNyZWF0ZSBzaWduYXR1cmUgYW5kIHJldHVybiBpdCBmb3IgY3JlZGVudGlhbHMgdXNpbmcgQXZhbGFuY2hlJ3MgYnVmZmVyXG4gICAqIEBwYXJhbSBuZXR3b3JrXG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqIEBwYXJhbSBwcnZcbiAgICogQHJldHVybiBzaWduYXR1cmVcbiAgICovXG4gIGNyZWF0ZVNpZ25hdHVyZUF2YXhCdWZmZXIobmV0d29yazogQXZhbGFuY2hlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyQXZheCwgcHJ2OiBCdWZmZXJBdmF4KTogQnVmZmVyQXZheCB7XG4gICAgY29uc3Qga3kgPSBuZXcgS2V5UGFpckF2YXgobmV0d29yay5ocnAsIG5ldHdvcmsubmV0d29ya0lELnRvU3RyaW5nKCkpO1xuICAgIGt5LmltcG9ydEtleShwcnYpO1xuICAgIHJldHVybiBreS5zaWduKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF2YXhwIHdyYXBwZXIgdG8gY3JlYXRlIHNpZ25hdHVyZSBhbmQgcmV0dXJuIGl0IGZvciBjcmVkZW50aWFsc1xuICAgKiBAcGFyYW0gbmV0d29ya1xuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcGFyYW0gcHJ2XG4gICAqIEByZXR1cm4gc2lnbmF0dXJlXG4gICAqL1xuICBjcmVhdGVTaWduYXR1cmUobmV0d29yazogQXZhbGFuY2hlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBwcnY6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMuY3JlYXRlU2lnbmF0dXJlQXZheEJ1ZmZlcihuZXR3b3JrLCBCdWZmZXJBdmF4LmZyb20obWVzc2FnZSksIEJ1ZmZlckF2YXguZnJvbShwcnYpKSk7XG4gIH1cblxuICAvKipcbiAgICogQXZheHAgd3JhcHBlciB0byB2ZXJpZnkgc2lnbmF0dXJlIHVzaW5nIEF2YWxhbmNoZSdzIGJ1ZmZlclxuICAgKiBAcGFyYW0gbmV0d29ya1xuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcGFyYW0gc2lnbmF0dXJlXG4gICAqIEBwYXJhbSBwcnZcbiAgICogQHJldHVybiB0cnVlIGlmIGl0J3MgdmVyaWZ5IHN1Y2Nlc3NmdWxcbiAgICovXG4gIHZlcmlmeVNpZ25hdHVyZUF2YXhCdWZmZXIoXG4gICAgbmV0d29yazogQXZhbGFuY2hlTmV0d29yayxcbiAgICBtZXNzYWdlOiBCdWZmZXJBdmF4LFxuICAgIHNpZ25hdHVyZTogQnVmZmVyQXZheCxcbiAgICBwcnY6IEJ1ZmZlckF2YXhcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga3kgPSBuZXcgS2V5UGFpckF2YXgobmV0d29yay5ocnAsIG5ldHdvcmsubmV0d29ya0lELnRvU3RyaW5nKCkpO1xuICAgIGt5LmltcG9ydEtleShwcnYpO1xuICAgIHJldHVybiBreS52ZXJpZnkobWVzc2FnZSwgc2lnbmF0dXJlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdmF4cCB3cmFwcGVyIHRvIHZlcmlmeSBzaWduYXR1cmVcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHNpZ25hdHVyZVxuICAgKiBAcGFyYW0gcHJ2XG4gICAqIEByZXR1cm4gdHJ1ZSBpZiBpdCdzIHZlcmlmeSBzdWNjZXNzZnVsXG4gICAqL1xuICB2ZXJpZnlTaWduYXR1cmUobmV0d29yazogQXZhbGFuY2hlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBzaWduYXR1cmU6IEJ1ZmZlciwgcHJ2OiBCdWZmZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52ZXJpZnlTaWduYXR1cmVBdmF4QnVmZmVyKFxuICAgICAgbmV0d29yayxcbiAgICAgIEJ1ZmZlckF2YXguZnJvbShtZXNzYWdlKSxcbiAgICAgIEJ1ZmZlckF2YXguZnJvbShzaWduYXR1cmUpLFxuICAgICAgQnVmZmVyQXZheC5mcm9tKHBydilcbiAgICApO1xuICB9XG5cbiAgY3JlYXRlU2lnKHNpZ0hleDogc3RyaW5nKTogU2lnbmF0dXJlIHtcbiAgICBjb25zdCBzaWcgPSBuZXcgU2lnbmF0dXJlKCk7XG4gICAgc2lnLmZyb21CdWZmZXIoQnVmZmVyQXZheC5mcm9tKHNpZ0hleC5wYWRTdGFydCgxMzAsICcwJyksICdoZXgnKSk7XG4gICAgcmV0dXJuIHNpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBBdmF4cCB3cmFwcGVyIHRvIHJlY292ZXJ5IHNpZ25hdHVyZSB1c2luZyBBdmFsYW5jaGUncyBidWZmZXJcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuXG4gICAqL1xuICByZWNvdmVyeVNpZ25hdHVyZUF2YXhCdWZmZXIobmV0d29yazogQXZhbGFuY2hlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyQXZheCwgc2lnbmF0dXJlOiBCdWZmZXJBdmF4KTogQnVmZmVyQXZheCB7XG4gICAgY29uc3Qga3kgPSBuZXcgS2V5UGFpckF2YXgobmV0d29yay5ocnAsIG5ldHdvcmsubmV0d29ya0lELnRvU3RyaW5nKCkpO1xuICAgIHJldHVybiBreS5yZWNvdmVyKG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG4gIH1cblxuICAvKipcbiAgICogQXZheHAgd3JhcHBlciB0byB2ZXJpZnkgc2lnbmF0dXJlXG4gICAqIEBwYXJhbSBuZXR3b3JrXG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqIEBwYXJhbSBzaWduYXR1cmVcbiAgICogQHJldHVybiB0cnVlIGlmIGl0J3MgdmVyaWZ5IHN1Y2Nlc3NmdWxcbiAgICovXG4gIHJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcms6IEF2YWxhbmNoZU5ldHdvcmssIG1lc3NhZ2U6IEJ1ZmZlciwgc2lnbmF0dXJlOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbSh0aGlzLnJlY292ZXJ5U2lnbmF0dXJlQXZheEJ1ZmZlcihuZXR3b3JrLCBCdWZmZXJBdmF4LmZyb20obWVzc2FnZSksIEJ1ZmZlckF2YXguZnJvbShzaWduYXR1cmUpKSk7XG4gIH1cblxuICBzaGEyNTYoYnVmOiBVaW50OEFycmF5KTogQnVmZmVyIHtcbiAgICByZXR1cm4gY3JlYXRlSGFzaC5kZWZhdWx0KCdzaGEyNTYnKS51cGRhdGUoYnVmKS5kaWdlc3QoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB0aGUgcmF3IHRyYW5zYWN0aW9uIGhhcyBhIHZhbGlkIGZvcm1hdCBpbiB0aGUgYmxvY2tjaGFpbiBjb250ZXh0LCB0aHJvdyBvdGhlcndpc2UuXG4gICAqIEl0J3MgdG8gcmV1c2UgaW4gVHJhbnNhY3Rpb25CdWlsZGVyIGFuZCBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5XG4gICAqXG4gICAqIEBwYXJhbSByYXdUcmFuc2FjdGlvbiBUcmFuc2FjdGlvbiBhcyBoZXggc3RyaW5nXG4gICAqL1xuICB2YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXJhd1RyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ1JhdyB0cmFuc2FjdGlvbiBpcyBlbXB0eScpO1xuICAgIH1cbiAgICBpZiAoIXV0aWxzLmFsbEhleENoYXJzKHJhd1RyYW5zYWN0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlVHJhbnNhY3Rpb25FcnJvcignUmF3IHRyYW5zYWN0aW9uIGlzIG5vdCBoZXggc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHR4IGlzIGZvciB0aGUgYmxvY2tjaGFpbklkXG4gICAqXG4gICAqIEBwYXJhbSB7VHh9IHR4XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBibG9ja2NoYWluSWRcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0eCBpcyBmb3IgYmxvY2tjaGFpbklkXG4gICAqL1xuICBpc1RyYW5zYWN0aW9uT2YodHg6IFR4LCBibG9ja2NoYWluSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5jYjU4RW5jb2RlKHR4LmdldFVuc2lnbmVkVHgoKS5nZXRUcmFuc2FjdGlvbigpLmdldEJsb2NrY2hhaW5JRCgpKSA9PT0gYmxvY2tjaGFpbklkO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIE91dHB1dCBpcyBmcm9tIFBWTS5cbiAgICogT3V0cHV0IGNvdWxkIGJlIEVWTSBvciBQVk0gb3V0cHV0LlxuICAgKiBAcGFyYW0ge091dHB1dH0gb3V0cHV0XG4gICAqIEByZXR1cm5zIHtib29sZWFufSBvdXRwdXQgaXMgVHJhbnNmZXJhYmxlT3V0cHV0XG4gICAqL1xuICBpc1RyYW5zZmVyYWJsZU91dHB1dChvdXRwdXQ6IE91dHB1dCk6IG91dHB1dCBpcyBUcmFuc2ZlcmFibGVPdXRwdXQge1xuICAgIHJldHVybiAnZ2V0T3V0cHV0JyBpbiBvdXRwdXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgbWFwcGVyIGZ1bmN0aW9uIHRvIHRoYXQgbmV0d29yayBhZGRyZXNzIHJlcHJlc2VudGF0aW9uLlxuICAgKiBAcGFyYW0gbmV0d29yayByZXF1aXJlZCB0byBzdHJpbmdpZnkgYWRkcmVzc2VzXG4gICAqIEByZXR1cm4gbWFwcGVyIGZ1bmN0aW9uXG4gICAqL1xuICBtYXBPdXRwdXRUb0VudHJ5KG5ldHdvcms6IEF2YWxhbmNoZU5ldHdvcmspOiAoT3V0cHV0KSA9PiBFbnRyeSB7XG4gICAgcmV0dXJuIChvdXRwdXQ6IE91dHB1dCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNUcmFuc2ZlcmFibGVPdXRwdXQob3V0cHV0KSkge1xuICAgICAgICBjb25zdCBhbW91bnRPdXRwdXQgPSBvdXRwdXQuZ2V0T3V0cHV0KCkgYXMgQW1vdW50T3V0cHV0O1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gYW1vdW50T3V0cHV0XG4gICAgICAgICAgLmdldEFkZHJlc3NlcygpXG4gICAgICAgICAgLm1hcCgoYSkgPT4gdGhpcy5hZGRyZXNzVG9TdHJpbmcobmV0d29yay5ocnAsIG5ldHdvcmsuYWxpYXMsIGEpKVxuICAgICAgICAgIC5zb3J0KClcbiAgICAgICAgICAuam9pbignficpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHZhbHVlOiBhbW91bnRPdXRwdXQuZ2V0QW1vdW50KCkudG9TdHJpbmcoKSxcbiAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZXZtT3V0cHV0ID0gb3V0cHV0IGFzIEVWTU91dHB1dDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAvLyBpdCBzaG91bGQgYmUgZXZtT3VwdXQuZ2V0QW1vdW50KCksIGJ1dCBpdCByZXR1cm5zIGEgMC5cbiAgICAgICAgICB2YWx1ZTogbmV3IEJOKChldm1PdXRwdXQgYXMgYW55KS5hbW91bnQpLnRvU3RyaW5nKCksXG4gICAgICAgICAgLy8gQy1DaGFpbiBhZGRyZXNzLlxuICAgICAgICAgIGFkZHJlc3M6ICcweCcgKyBldm1PdXRwdXQuZ2V0QWRkcmVzc1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH07XG4gIH1cbn1cblxuY29uc3QgdXRpbHMgPSBuZXcgVXRpbHMoKTtcblxuZXhwb3J0IGRlZmF1bHQgdXRpbHM7XG4iXX0=
@@ -0,0 +1,45 @@
1
+ /// <reference types="bn.js" />
2
+ import { DecodedUtxoObj } from './iface';
3
+ import { BN, Buffer as BufferAvax } from 'avalanche';
4
+ import { Signature } from 'avalanche/dist/common';
5
+ import { StandardTransferableInput } from 'avalanche/dist/common/input';
6
+ export interface InputData {
7
+ amount: BN;
8
+ txidBuf: BufferAvax;
9
+ outputIdx: BufferAvax;
10
+ signaturesIdx: number[];
11
+ signatures: Signature[];
12
+ }
13
+ /**
14
+ * Inputs can be controlled but outputs get reordered in transactions
15
+ * In order to make sure that the mapping is always correct we create an addressIndex which matches to the appropriate
16
+ * signatureIdx
17
+ * @param {StandardTransferableInput[]} utxos as transaction ins.
18
+ * @returns the list of UTXOs
19
+ */
20
+ export declare function recoverUtxos(utxos: StandardTransferableInput[]): DecodedUtxoObj[];
21
+ /**
22
+ * Convert Utxos into inputs data. Input Objects changes regarding chains. This method return a plain object to be mapped late in chain input.
23
+ * Sender is a list of owners address and utxo address must contains all of them.
24
+ * Signers is a list of sender cut it in threshold size. Firsts senders are the signers.
25
+ *
26
+ * Output always get reordered we want to make sure we can always add signatures in the correct location.
27
+ * Signatures array store signers address of the expected signature. Tx sign replace the address for the signature.
28
+ * So the location of the signatures is guaranteed.
29
+ *
30
+ * To find the correct location for the signature, we use the output's addresses to create the signatureIdx in the order that we desire
31
+ * 0: user key, 1: hsm key, 2: recovery key
32
+ *
33
+ * @param utxos
34
+ * @param sender array of addresses
35
+ * @param threshold number of signatures required
36
+ * @return {
37
+ * inputs: InputData[];
38
+ * amount: BN;
39
+ * } as total amount and inputs with signatures as signers address to be replaced.
40
+ */
41
+ export declare function utxoToInput(utxos: DecodedUtxoObj[], sender: BufferAvax[], threshold?: number): {
42
+ inputs: InputData[];
43
+ amount: BN;
44
+ };
45
+ //# sourceMappingURL=utxoEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utxoEngine.d.ts","sourceRoot":"","sources":["../../../src/lib/utxoEngine.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAA6B,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,OAAO,EAAuB,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAE7F,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE,CAiBjF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,UAAU,EAAE,EACpB,SAAS,SAAI,GACZ;IACD,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,EAAE,CAAC;CACZ,CAuCA"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.utxoToInput = exports.recoverUtxos = void 0;
7
+ const iface_1 = require("./iface");
8
+ const avalanche_1 = require("avalanche");
9
+ const utils_1 = __importDefault(require("./utils"));
10
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
11
+ /**
12
+ * Inputs can be controlled but outputs get reordered in transactions
13
+ * In order to make sure that the mapping is always correct we create an addressIndex which matches to the appropriate
14
+ * signatureIdx
15
+ * @param {StandardTransferableInput[]} utxos as transaction ins.
16
+ * @returns the list of UTXOs
17
+ */
18
+ function recoverUtxos(utxos) {
19
+ return utxos.map((utxo) => {
20
+ const secpInput = utxo.getInput();
21
+ // use the same addressesIndex as existing ones in the inputs
22
+ const addressesIndex = secpInput.getSigIdxs().map((s) => s.toBuffer().readUInt32BE(0));
23
+ return {
24
+ outputID: iface_1.SECP256K1_Transfer_Output,
25
+ outputidx: utils_1.default.cb58Encode(utxo.getOutputIdx()),
26
+ txid: utils_1.default.cb58Encode(utxo.getTxID()),
27
+ amount: secpInput.getAmount().toString(),
28
+ threshold: addressesIndex.length,
29
+ addresses: [],
30
+ addressesIndex,
31
+ };
32
+ });
33
+ }
34
+ exports.recoverUtxos = recoverUtxos;
35
+ /**
36
+ * Convert Utxos into inputs data. Input Objects changes regarding chains. This method return a plain object to be mapped late in chain input.
37
+ * Sender is a list of owners address and utxo address must contains all of them.
38
+ * Signers is a list of sender cut it in threshold size. Firsts senders are the signers.
39
+ *
40
+ * Output always get reordered we want to make sure we can always add signatures in the correct location.
41
+ * Signatures array store signers address of the expected signature. Tx sign replace the address for the signature.
42
+ * So the location of the signatures is guaranteed.
43
+ *
44
+ * To find the correct location for the signature, we use the output's addresses to create the signatureIdx in the order that we desire
45
+ * 0: user key, 1: hsm key, 2: recovery key
46
+ *
47
+ * @param utxos
48
+ * @param sender array of addresses
49
+ * @param threshold number of signatures required
50
+ * @return {
51
+ * inputs: InputData[];
52
+ * amount: BN;
53
+ * } as total amount and inputs with signatures as signers address to be replaced.
54
+ */
55
+ function utxoToInput(utxos, sender, threshold = 2) {
56
+ // amount spent so far
57
+ let currentTotal = new avalanche_1.BN(0);
58
+ const inputs = utxos
59
+ .filter((utxo) => utxo && utxo.outputID === iface_1.SECP256K1_Transfer_Output)
60
+ .map((utxo) => {
61
+ // validate the utxos
62
+ const utxoAddresses = utxo.addresses.map((a) => utils_1.default.parseAddress(a));
63
+ const addressesIndex = sender.map((a) => utxoAddresses.findIndex((u) => a.equals(u)));
64
+ // addressesIndex should never have a mismatch
65
+ if (addressesIndex.includes(-1)) {
66
+ throw new sdk_core_1.BuildTransactionError('Addresses are inconsistent: ' + utxo.txid);
67
+ }
68
+ if (utxo.threshold !== threshold) {
69
+ throw new sdk_core_1.BuildTransactionError('Threshold is inconsistent');
70
+ }
71
+ const txidBuf = utils_1.default.cb58Decode(utxo.txid);
72
+ const amount = new avalanche_1.BN(utxo.amount);
73
+ const outputIdx = utils_1.default.cb58Decode(utxo.outputidx);
74
+ currentTotal = currentTotal.add(amount);
75
+ const signers = addressesIndex
76
+ .slice(0, threshold)
77
+ .map((utxoIndex, senderIndex) => ({ utxoIndex, senderIndex }))
78
+ .sort((a, b) => a.utxoIndex - b.utxoIndex);
79
+ const signatures = signers.map(({ senderIndex }) =>
80
+ // TODO(BG-56700): Improve canSign by check in addresses in empty credentials match signer
81
+ // HSM require empty signature.
82
+ utils_1.default.createSig(senderIndex == 1 ? '' : sender[senderIndex].toString('hex')));
83
+ const signaturesIdx = signers.map(({ utxoIndex }) => utxoIndex);
84
+ return { amount, txidBuf, outputIdx, signaturesIdx, signatures };
85
+ });
86
+ return { inputs, amount: currentTotal };
87
+ }
88
+ exports.utxoToInput = utxoToInput;
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXR4b0VuZ2luZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvdXR4b0VuZ2luZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxtQ0FBb0U7QUFDcEUseUNBQXFEO0FBRXJELG9EQUE0QjtBQUM1QixtREFBNkQ7QUFXN0Q7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsWUFBWSxDQUFDLEtBQWtDO0lBQzdELE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3hCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQXlCLENBQUM7UUFFekQsNkRBQTZEO1FBQzdELE1BQU0sY0FBYyxHQUFhLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqRyxPQUFPO1lBQ0wsUUFBUSxFQUFFLGlDQUF5QjtZQUNuQyxTQUFTLEVBQUUsZUFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDaEQsSUFBSSxFQUFFLGVBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RDLE1BQU0sRUFBRSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxFQUFFO1lBQ3hDLFNBQVMsRUFBRSxjQUFjLENBQUMsTUFBTTtZQUNoQyxTQUFTLEVBQUUsRUFBRTtZQUNiLGNBQWM7U0FDZixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBakJELG9DQWlCQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsU0FBZ0IsV0FBVyxDQUN6QixLQUF1QixFQUN2QixNQUFvQixFQUNwQixTQUFTLEdBQUcsQ0FBQztJQUtiLHNCQUFzQjtJQUN0QixJQUFJLFlBQVksR0FBTyxJQUFJLGNBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVqQyxNQUFNLE1BQU0sR0FBRyxLQUFLO1NBQ2pCLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssaUNBQXlCLENBQUM7U0FDckUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDWixxQkFBcUI7UUFDckIsTUFBTSxhQUFhLEdBQWlCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckYsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEYsOENBQThDO1FBQzlDLElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyw4QkFBOEIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDN0U7UUFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFO1lBQ2hDLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1NBQzlEO1FBRUQsTUFBTSxPQUFPLEdBQWUsZUFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQU8sSUFBSSxjQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sU0FBUyxHQUFlLGVBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRS9ELFlBQVksR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXhDLE1BQU0sT0FBTyxHQUFHLGNBQWM7YUFDM0IsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUM7YUFDbkIsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO2FBQzdELElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUU7UUFDakQsMkZBQTJGO1FBQzNGLCtCQUErQjtRQUMvQixlQUFLLENBQUMsU0FBUyxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUM3RSxDQUFDO1FBQ0YsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWhFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLENBQUM7SUFDbkUsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUMxQyxDQUFDO0FBOUNELGtDQThDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlY29kZWRVdHhvT2JqLCBTRUNQMjU2SzFfVHJhbnNmZXJfT3V0cHV0IH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgeyBCTiwgQnVmZmVyIGFzIEJ1ZmZlckF2YXggfSBmcm9tICdhdmFsYW5jaGUnO1xuaW1wb3J0IHsgU2lnbmF0dXJlIH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvY29tbW9uJztcbmltcG9ydCB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IEJ1aWxkVHJhbnNhY3Rpb25FcnJvciB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IFN0YW5kYXJkQW1vdW50SW5wdXQsIFN0YW5kYXJkVHJhbnNmZXJhYmxlSW5wdXQgfSBmcm9tICdhdmFsYW5jaGUvZGlzdC9jb21tb24vaW5wdXQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElucHV0RGF0YSB7XG4gIGFtb3VudDogQk47XG4gIHR4aWRCdWY6IEJ1ZmZlckF2YXg7XG4gIG91dHB1dElkeDogQnVmZmVyQXZheDtcbiAgc2lnbmF0dXJlc0lkeDogbnVtYmVyW107XG4gIHNpZ25hdHVyZXM6IFNpZ25hdHVyZVtdO1xufVxuXG4vKipcbiAqIElucHV0cyBjYW4gYmUgY29udHJvbGxlZCBidXQgb3V0cHV0cyBnZXQgcmVvcmRlcmVkIGluIHRyYW5zYWN0aW9uc1xuICogSW4gb3JkZXIgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG1hcHBpbmcgaXMgYWx3YXlzIGNvcnJlY3Qgd2UgY3JlYXRlIGFuIGFkZHJlc3NJbmRleCB3aGljaCBtYXRjaGVzIHRvIHRoZSBhcHByb3ByaWF0ZVxuICogc2lnbmF0dXJlSWR4XG4gKiBAcGFyYW0ge1N0YW5kYXJkVHJhbnNmZXJhYmxlSW5wdXRbXX0gdXR4b3MgYXMgdHJhbnNhY3Rpb24gaW5zLlxuICogQHJldHVybnMgdGhlIGxpc3Qgb2YgVVRYT3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY292ZXJVdHhvcyh1dHhvczogU3RhbmRhcmRUcmFuc2ZlcmFibGVJbnB1dFtdKTogRGVjb2RlZFV0eG9PYmpbXSB7XG4gIHJldHVybiB1dHhvcy5tYXAoKHV0eG8pID0+IHtcbiAgICBjb25zdCBzZWNwSW5wdXQgPSB1dHhvLmdldElucHV0KCkgYXMgU3RhbmRhcmRBbW91bnRJbnB1dDtcblxuICAgIC8vIHVzZSB0aGUgc2FtZSBhZGRyZXNzZXNJbmRleCBhcyBleGlzdGluZyBvbmVzIGluIHRoZSBpbnB1dHNcbiAgICBjb25zdCBhZGRyZXNzZXNJbmRleDogbnVtYmVyW10gPSBzZWNwSW5wdXQuZ2V0U2lnSWR4cygpLm1hcCgocykgPT4gcy50b0J1ZmZlcigpLnJlYWRVSW50MzJCRSgwKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3V0cHV0SUQ6IFNFQ1AyNTZLMV9UcmFuc2Zlcl9PdXRwdXQsXG4gICAgICBvdXRwdXRpZHg6IHV0aWxzLmNiNThFbmNvZGUodXR4by5nZXRPdXRwdXRJZHgoKSksXG4gICAgICB0eGlkOiB1dGlscy5jYjU4RW5jb2RlKHV0eG8uZ2V0VHhJRCgpKSxcbiAgICAgIGFtb3VudDogc2VjcElucHV0LmdldEFtb3VudCgpLnRvU3RyaW5nKCksXG4gICAgICB0aHJlc2hvbGQ6IGFkZHJlc3Nlc0luZGV4Lmxlbmd0aCxcbiAgICAgIGFkZHJlc3NlczogW10sIC8vIHRoaXMgaXMgZW1wdHkgc2luY2UgdGhlIGlucHV0cyBmcm9tIGRlc2VyaWFsaXplZCB0cmFuc2FjdGlvbiBkb24ndCBjb250YWluIGFkZHJlc3Nlc1xuICAgICAgYWRkcmVzc2VzSW5kZXgsXG4gICAgfTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ29udmVydCBVdHhvcyBpbnRvIGlucHV0cyBkYXRhLiBJbnB1dCBPYmplY3RzIGNoYW5nZXMgcmVnYXJkaW5nIGNoYWlucy4gVGhpcyBtZXRob2QgcmV0dXJuIGEgcGxhaW4gb2JqZWN0IHRvIGJlIG1hcHBlZCBsYXRlIGluIGNoYWluIGlucHV0LlxuICogU2VuZGVyIGlzIGEgbGlzdCBvZiBvd25lcnMgYWRkcmVzcyBhbmQgdXR4byBhZGRyZXNzIG11c3QgY29udGFpbnMgYWxsIG9mIHRoZW0uXG4gKiBTaWduZXJzIGlzIGEgbGlzdCBvZiBzZW5kZXIgY3V0IGl0IGluIHRocmVzaG9sZCBzaXplLiBGaXJzdHMgc2VuZGVycyBhcmUgdGhlIHNpZ25lcnMuXG4gKlxuICogT3V0cHV0IGFsd2F5cyBnZXQgcmVvcmRlcmVkIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGNhbiBhbHdheXMgYWRkIHNpZ25hdHVyZXMgaW4gdGhlIGNvcnJlY3QgbG9jYXRpb24uXG4gKiBTaWduYXR1cmVzIGFycmF5IHN0b3JlIHNpZ25lcnMgYWRkcmVzcyBvZiB0aGUgZXhwZWN0ZWQgc2lnbmF0dXJlLiBUeCBzaWduIHJlcGxhY2UgdGhlIGFkZHJlc3MgZm9yIHRoZSBzaWduYXR1cmUuXG4gKiBTbyB0aGUgbG9jYXRpb24gb2YgdGhlIHNpZ25hdHVyZXMgaXMgZ3VhcmFudGVlZC5cbiAqXG4gKiBUbyBmaW5kIHRoZSBjb3JyZWN0IGxvY2F0aW9uIGZvciB0aGUgc2lnbmF0dXJlLCB3ZSB1c2UgdGhlIG91dHB1dCdzIGFkZHJlc3NlcyB0byBjcmVhdGUgdGhlIHNpZ25hdHVyZUlkeCBpbiB0aGUgb3JkZXIgdGhhdCB3ZSBkZXNpcmVcbiAqIDA6IHVzZXIga2V5LCAxOiBoc20ga2V5LCAyOiByZWNvdmVyeSBrZXlcbiAqXG4gKiBAcGFyYW0gdXR4b3NcbiAqIEBwYXJhbSBzZW5kZXIgYXJyYXkgb2YgYWRkcmVzc2VzXG4gKiBAcGFyYW0gdGhyZXNob2xkIG51bWJlciBvZiBzaWduYXR1cmVzIHJlcXVpcmVkXG4gKiBAcmV0dXJuIHtcbiAqICAgaW5wdXRzOiBJbnB1dERhdGFbXTtcbiAqICAgYW1vdW50OiBCTjtcbiAqIH0gYXMgdG90YWwgYW1vdW50IGFuZCBpbnB1dHMgd2l0aCBzaWduYXR1cmVzIGFzIHNpZ25lcnMgYWRkcmVzcyB0byBiZSByZXBsYWNlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHV0eG9Ub0lucHV0KFxuICB1dHhvczogRGVjb2RlZFV0eG9PYmpbXSxcbiAgc2VuZGVyOiBCdWZmZXJBdmF4W10sXG4gIHRocmVzaG9sZCA9IDJcbik6IHtcbiAgaW5wdXRzOiBJbnB1dERhdGFbXTtcbiAgYW1vdW50OiBCTjtcbn0ge1xuICAvLyBhbW91bnQgc3BlbnQgc28gZmFyXG4gIGxldCBjdXJyZW50VG90YWw6IEJOID0gbmV3IEJOKDApO1xuXG4gIGNvbnN0IGlucHV0cyA9IHV0eG9zXG4gICAgLmZpbHRlcigodXR4bykgPT4gdXR4byAmJiB1dHhvLm91dHB1dElEID09PSBTRUNQMjU2SzFfVHJhbnNmZXJfT3V0cHV0KVxuICAgIC5tYXAoKHV0eG8pID0+IHtcbiAgICAgIC8vIHZhbGlkYXRlIHRoZSB1dHhvc1xuICAgICAgY29uc3QgdXR4b0FkZHJlc3NlczogQnVmZmVyQXZheFtdID0gdXR4by5hZGRyZXNzZXMubWFwKChhKSA9PiB1dGlscy5wYXJzZUFkZHJlc3MoYSkpO1xuICAgICAgY29uc3QgYWRkcmVzc2VzSW5kZXggPSBzZW5kZXIubWFwKChhKSA9PiB1dHhvQWRkcmVzc2VzLmZpbmRJbmRleCgodSkgPT4gYS5lcXVhbHModSkpKTtcbiAgICAgIC8vIGFkZHJlc3Nlc0luZGV4IHNob3VsZCBuZXZlciBoYXZlIGEgbWlzbWF0Y2hcbiAgICAgIGlmIChhZGRyZXNzZXNJbmRleC5pbmNsdWRlcygtMSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignQWRkcmVzc2VzIGFyZSBpbmNvbnNpc3RlbnQ6ICcgKyB1dHhvLnR4aWQpO1xuICAgICAgfVxuICAgICAgaWYgKHV0eG8udGhyZXNob2xkICE9PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVGhyZXNob2xkIGlzIGluY29uc2lzdGVudCcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0eGlkQnVmOiBCdWZmZXJBdmF4ID0gdXRpbHMuY2I1OERlY29kZSh1dHhvLnR4aWQpO1xuICAgICAgY29uc3QgYW1vdW50OiBCTiA9IG5ldyBCTih1dHhvLmFtb3VudCk7XG4gICAgICBjb25zdCBvdXRwdXRJZHg6IEJ1ZmZlckF2YXggPSB1dGlscy5jYjU4RGVjb2RlKHV0eG8ub3V0cHV0aWR4KTtcblxuICAgICAgY3VycmVudFRvdGFsID0gY3VycmVudFRvdGFsLmFkZChhbW91bnQpO1xuXG4gICAgICBjb25zdCBzaWduZXJzID0gYWRkcmVzc2VzSW5kZXhcbiAgICAgICAgLnNsaWNlKDAsIHRocmVzaG9sZClcbiAgICAgICAgLm1hcCgodXR4b0luZGV4LCBzZW5kZXJJbmRleCkgPT4gKHsgdXR4b0luZGV4LCBzZW5kZXJJbmRleCB9KSlcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEudXR4b0luZGV4IC0gYi51dHhvSW5kZXgpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IHNpZ25lcnMubWFwKCh7IHNlbmRlckluZGV4IH0pID0+XG4gICAgICAgIC8vIFRPRE8oQkctNTY3MDApOiAgSW1wcm92ZSBjYW5TaWduIGJ5IGNoZWNrIGluIGFkZHJlc3NlcyBpbiBlbXB0eSBjcmVkZW50aWFscyBtYXRjaCBzaWduZXJcbiAgICAgICAgLy8gSFNNIHJlcXVpcmUgZW1wdHkgc2lnbmF0dXJlLlxuICAgICAgICB1dGlscy5jcmVhdGVTaWcoc2VuZGVySW5kZXggPT0gMSA/ICcnIDogc2VuZGVyW3NlbmRlckluZGV4XS50b1N0cmluZygnaGV4JykpXG4gICAgICApO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlc0lkeCA9IHNpZ25lcnMubWFwKCh7IHV0eG9JbmRleCB9KSA9PiB1dHhvSW5kZXgpO1xuXG4gICAgICByZXR1cm4geyBhbW91bnQsIHR4aWRCdWYsIG91dHB1dElkeCwgc2lnbmF0dXJlc0lkeCwgc2lnbmF0dXJlcyB9O1xuICAgIH0pO1xuXG4gIHJldHVybiB7IGlucHV0cywgYW1vdW50OiBjdXJyZW50VG90YWwgfTtcbn1cbiJdfQ==