@opcat-labs/bip174 1.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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/package.json +66 -0
  4. package/src/cjs/lib/combiner/index.js +67 -0
  5. package/src/cjs/lib/converter/global/globalXpub.js +83 -0
  6. package/src/cjs/lib/converter/global/unsignedTx.js +10 -0
  7. package/src/cjs/lib/converter/index.js +72 -0
  8. package/src/cjs/lib/converter/input/finalScriptSig.js +36 -0
  9. package/src/cjs/lib/converter/input/finalScriptWitness.js +36 -0
  10. package/src/cjs/lib/converter/input/nonWitnessUtxo.js +35 -0
  11. package/src/cjs/lib/converter/input/opcatUtxo.js +74 -0
  12. package/src/cjs/lib/converter/input/partialSig.js +74 -0
  13. package/src/cjs/lib/converter/input/porCommitment.js +36 -0
  14. package/src/cjs/lib/converter/input/sighashType.js +38 -0
  15. package/src/cjs/lib/converter/input/tapKeySig.js +36 -0
  16. package/src/cjs/lib/converter/input/tapLeafScript.js +56 -0
  17. package/src/cjs/lib/converter/input/tapMerkleRoot.js +36 -0
  18. package/src/cjs/lib/converter/input/tapScriptSig.js +59 -0
  19. package/src/cjs/lib/converter/input/witnessUtxo.js +53 -0
  20. package/src/cjs/lib/converter/output/tapTree.js +60 -0
  21. package/src/cjs/lib/converter/shared/bip32Derivation.js +84 -0
  22. package/src/cjs/lib/converter/shared/checkPubkey.js +25 -0
  23. package/src/cjs/lib/converter/shared/redeemScript.js +41 -0
  24. package/src/cjs/lib/converter/shared/tapBip32Derivation.js +55 -0
  25. package/src/cjs/lib/converter/shared/tapInternalKey.js +41 -0
  26. package/src/cjs/lib/converter/shared/witnessScript.js +41 -0
  27. package/src/cjs/lib/converter/tools.js +45 -0
  28. package/src/cjs/lib/interfaces.js +2 -0
  29. package/src/cjs/lib/parser/fromBuffer.js +325 -0
  30. package/src/cjs/lib/parser/index.js +7 -0
  31. package/src/cjs/lib/parser/toBuffer.js +69 -0
  32. package/src/cjs/lib/psbt.js +145 -0
  33. package/src/cjs/lib/typeFields.js +64 -0
  34. package/src/cjs/lib/utils.js +141 -0
  35. package/src/esm/lib/combiner/index.d.ts +2 -0
  36. package/src/esm/lib/combiner/index.js +57 -0
  37. package/src/esm/lib/converter/global/globalXpub.d.ts +6 -0
  38. package/src/esm/lib/converter/global/globalXpub.js +70 -0
  39. package/src/esm/lib/converter/global/unsignedTx.d.ts +2 -0
  40. package/src/esm/lib/converter/global/unsignedTx.js +7 -0
  41. package/src/esm/lib/converter/index.d.ts +110 -0
  42. package/src/esm/lib/converter/index.js +61 -0
  43. package/src/esm/lib/converter/input/finalScriptSig.d.ts +6 -0
  44. package/src/esm/lib/converter/input/finalScriptSig.js +23 -0
  45. package/src/esm/lib/converter/input/finalScriptWitness.d.ts +6 -0
  46. package/src/esm/lib/converter/input/finalScriptWitness.js +23 -0
  47. package/src/esm/lib/converter/input/nonWitnessUtxo.d.ts +6 -0
  48. package/src/esm/lib/converter/input/nonWitnessUtxo.js +22 -0
  49. package/src/esm/lib/converter/input/opcatUtxo.d.ts +6 -0
  50. package/src/esm/lib/converter/input/opcatUtxo.js +61 -0
  51. package/src/esm/lib/converter/input/partialSig.d.ts +6 -0
  52. package/src/esm/lib/converter/input/partialSig.js +61 -0
  53. package/src/esm/lib/converter/input/porCommitment.d.ts +6 -0
  54. package/src/esm/lib/converter/input/porCommitment.js +23 -0
  55. package/src/esm/lib/converter/input/sighashType.d.ts +6 -0
  56. package/src/esm/lib/converter/input/sighashType.js +25 -0
  57. package/src/esm/lib/converter/input/tapKeySig.d.ts +6 -0
  58. package/src/esm/lib/converter/input/tapKeySig.js +23 -0
  59. package/src/esm/lib/converter/input/tapLeafScript.d.ts +6 -0
  60. package/src/esm/lib/converter/input/tapLeafScript.js +43 -0
  61. package/src/esm/lib/converter/input/tapMerkleRoot.d.ts +6 -0
  62. package/src/esm/lib/converter/input/tapMerkleRoot.js +23 -0
  63. package/src/esm/lib/converter/input/tapScriptSig.d.ts +6 -0
  64. package/src/esm/lib/converter/input/tapScriptSig.js +46 -0
  65. package/src/esm/lib/converter/input/witnessUtxo.d.ts +6 -0
  66. package/src/esm/lib/converter/input/witnessUtxo.js +40 -0
  67. package/src/esm/lib/converter/output/tapTree.d.ts +6 -0
  68. package/src/esm/lib/converter/output/tapTree.js +47 -0
  69. package/src/esm/lib/converter/shared/bip32Derivation.d.ts +8 -0
  70. package/src/esm/lib/converter/shared/bip32Derivation.js +74 -0
  71. package/src/esm/lib/converter/shared/checkPubkey.d.ts +2 -0
  72. package/src/esm/lib/converter/shared/checkPubkey.js +15 -0
  73. package/src/esm/lib/converter/shared/redeemScript.d.ts +8 -0
  74. package/src/esm/lib/converter/shared/redeemScript.js +31 -0
  75. package/src/esm/lib/converter/shared/tapBip32Derivation.d.ts +8 -0
  76. package/src/esm/lib/converter/shared/tapBip32Derivation.js +45 -0
  77. package/src/esm/lib/converter/shared/tapInternalKey.d.ts +8 -0
  78. package/src/esm/lib/converter/shared/tapInternalKey.js +31 -0
  79. package/src/esm/lib/converter/shared/witnessScript.d.ts +8 -0
  80. package/src/esm/lib/converter/shared/witnessScript.js +31 -0
  81. package/src/esm/lib/converter/tools.d.ts +5 -0
  82. package/src/esm/lib/converter/tools.js +33 -0
  83. package/src/esm/lib/interfaces.d.ts +120 -0
  84. package/src/esm/lib/interfaces.js +0 -0
  85. package/src/esm/lib/parser/fromBuffer.d.ts +11 -0
  86. package/src/esm/lib/parser/fromBuffer.js +313 -0
  87. package/src/esm/lib/parser/index.d.ts +8 -0
  88. package/src/esm/lib/parser/index.js +2 -0
  89. package/src/esm/lib/parser/toBuffer.d.ts +8 -0
  90. package/src/esm/lib/parser/toBuffer.js +58 -0
  91. package/src/esm/lib/psbt.d.ts +26 -0
  92. package/src/esm/lib/psbt.js +133 -0
  93. package/src/esm/lib/typeFields.d.ts +34 -0
  94. package/src/esm/lib/typeFields.js +62 -0
  95. package/src/esm/lib/utils.d.ts +13 -0
  96. package/src/esm/lib/utils.js +123 -0
@@ -0,0 +1,58 @@
1
+ import * as convert from '../converter/index.js';
2
+ import { keyValsToBuffer } from '../converter/tools.js';
3
+ import * as tools from 'uint8array-tools';
4
+ export function psbtToBuffer({ globalMap, inputs, outputs, }) {
5
+ const { globalKeyVals, inputKeyVals, outputKeyVals } = psbtToKeyVals({
6
+ globalMap,
7
+ inputs,
8
+ outputs,
9
+ });
10
+ const globalBuffer = keyValsToBuffer(globalKeyVals);
11
+ const keyValsOrEmptyToBuffer = (keyVals) => keyVals.length === 0
12
+ ? [Uint8Array.from([0])]
13
+ : keyVals.map(keyValsToBuffer);
14
+ const inputBuffers = keyValsOrEmptyToBuffer(inputKeyVals);
15
+ const outputBuffers = keyValsOrEmptyToBuffer(outputKeyVals);
16
+ const header = new Uint8Array(5);
17
+ header.set([0x70, 0x73, 0x62, 0x74, 0xff], 0);
18
+ return tools.concat([header, globalBuffer].concat(inputBuffers, outputBuffers));
19
+ }
20
+ const sortKeyVals = (a, b) => {
21
+ return tools.compare(a.key, b.key);
22
+ };
23
+ function keyValsFromMap(keyValMap, converterFactory) {
24
+ const keyHexSet = new Set();
25
+ const keyVals = Object.entries(keyValMap).reduce((result, [key, value]) => {
26
+ if (key === 'unknownKeyVals')
27
+ return result;
28
+ // We are checking for undefined anyways. So ignore TS error
29
+ // @ts-ignore
30
+ const converter = converterFactory[key];
31
+ if (converter === undefined)
32
+ return result;
33
+ const encodedKeyVals = (Array.isArray(value) ? value : [value]).map(converter.encode);
34
+ const keyHexes = encodedKeyVals.map(kv => tools.toHex(kv.key));
35
+ keyHexes.forEach(hex => {
36
+ if (keyHexSet.has(hex))
37
+ throw new Error('Serialize Error: Duplicate key: ' + hex);
38
+ keyHexSet.add(hex);
39
+ });
40
+ return result.concat(encodedKeyVals);
41
+ }, []);
42
+ // Get other keyVals that have not yet been gotten
43
+ const otherKeyVals = keyValMap.unknownKeyVals
44
+ ? keyValMap.unknownKeyVals.filter((keyVal) => {
45
+ return !keyHexSet.has(tools.toHex(keyVal.key));
46
+ })
47
+ : [];
48
+ return keyVals.concat(otherKeyVals).sort(sortKeyVals);
49
+ }
50
+ export function psbtToKeyVals({ globalMap, inputs, outputs, }) {
51
+ // First parse the global keyVals
52
+ // Get any extra keyvals to pass along
53
+ return {
54
+ globalKeyVals: keyValsFromMap(globalMap, convert.globals),
55
+ inputKeyVals: inputs.map(i => keyValsFromMap(i, convert.inputs)),
56
+ outputKeyVals: outputs.map(o => keyValsFromMap(o, convert.outputs)),
57
+ };
58
+ }
@@ -0,0 +1,26 @@
1
+ import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, Transaction, TransactionFromBuffer } from './interfaces.js';
2
+ export declare class Psbt {
3
+ static fromBase64<T extends typeof Psbt>(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
4
+ static fromHex<T extends typeof Psbt>(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
5
+ static fromBuffer<T extends typeof Psbt>(this: T, buffer: Uint8Array, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
6
+ readonly inputs: PsbtInput[];
7
+ readonly outputs: PsbtOutput[];
8
+ readonly globalMap: PsbtGlobal;
9
+ constructor(tx: Transaction);
10
+ toBase64(): string;
11
+ toHex(): string;
12
+ toBuffer(): Uint8Array;
13
+ updateGlobal(updateData: PsbtGlobalUpdate): this;
14
+ updateInput(inputIndex: number, updateData: PsbtInputUpdate): this;
15
+ updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this;
16
+ addUnknownKeyValToGlobal(keyVal: KeyValue): this;
17
+ addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
18
+ addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
19
+ addInput(inputData: PsbtInputExtended): this;
20
+ addOutput(outputData: PsbtOutputExtended): this;
21
+ clearFinalizedInput(inputIndex: number): this;
22
+ combine(...those: this[]): this;
23
+ getTransaction(): Uint8Array;
24
+ }
25
+ export { Bip32Derivation, NonWitnessUtxo, ControlBlock, FinalScriptSig, FinalScriptWitness, GlobalXpub, KeyValue, PartialSig, PorCommitment, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, RedeemScript, SighashType, TapBip32Derivation, TapInternalKey, TapKeySig, TapLeaf, TapLeafScript, TapMerkleRoot, TapScriptSig, TapTree, Transaction, TransactionFromBuffer, TransactionIOCountGetter, TransactionLocktimeSetter, TransactionVersionSetter, WitnessScript, WitnessUtxo, OpcatUtxo, } from './interfaces.js';
26
+ export { checkForInput, checkForOutput } from './utils.js';
@@ -0,0 +1,133 @@
1
+ import { combine } from './combiner/index.js';
2
+ import { psbtFromBuffer, psbtToBuffer } from './parser/index.js';
3
+ import { GlobalTypes, InputTypes, OutputTypes } from './typeFields.js';
4
+ import { addInputAttributes, addOutputAttributes, checkForInput, checkForOutput, checkHasKey, getEnumLength, inputCheckUncleanFinalized, updateGlobal, updateInput, updateOutput, } from './utils.js';
5
+ import * as tools from 'uint8array-tools';
6
+ export class Psbt {
7
+ constructor(tx) {
8
+ this.inputs = [];
9
+ this.outputs = [];
10
+ this.globalMap = {
11
+ unsignedTx: tx,
12
+ };
13
+ }
14
+ static fromBase64(data, txFromBuffer) {
15
+ const buffer = tools.fromBase64(data);
16
+ return this.fromBuffer(buffer, txFromBuffer);
17
+ }
18
+ static fromHex(data, txFromBuffer) {
19
+ const buffer = tools.fromHex(data);
20
+ return this.fromBuffer(buffer, txFromBuffer);
21
+ }
22
+ static fromBuffer(buffer, txFromBuffer) {
23
+ const results = psbtFromBuffer(buffer, txFromBuffer);
24
+ const psbt = new this(results.globalMap.unsignedTx);
25
+ Object.assign(psbt, results);
26
+ return psbt;
27
+ }
28
+ toBase64() {
29
+ const buffer = this.toBuffer();
30
+ return tools.toBase64(buffer);
31
+ }
32
+ toHex() {
33
+ const buffer = this.toBuffer();
34
+ return tools.toHex(buffer);
35
+ }
36
+ toBuffer() {
37
+ return psbtToBuffer(this);
38
+ }
39
+ updateGlobal(updateData) {
40
+ updateGlobal(updateData, this.globalMap);
41
+ return this;
42
+ }
43
+ updateInput(inputIndex, updateData) {
44
+ const input = checkForInput(this.inputs, inputIndex);
45
+ updateInput(updateData, input);
46
+ return this;
47
+ }
48
+ updateOutput(outputIndex, updateData) {
49
+ const output = checkForOutput(this.outputs, outputIndex);
50
+ updateOutput(updateData, output);
51
+ return this;
52
+ }
53
+ addUnknownKeyValToGlobal(keyVal) {
54
+ checkHasKey(keyVal, this.globalMap.unknownKeyVals, getEnumLength(GlobalTypes));
55
+ if (!this.globalMap.unknownKeyVals)
56
+ this.globalMap.unknownKeyVals = [];
57
+ this.globalMap.unknownKeyVals.push(keyVal);
58
+ return this;
59
+ }
60
+ addUnknownKeyValToInput(inputIndex, keyVal) {
61
+ const input = checkForInput(this.inputs, inputIndex);
62
+ checkHasKey(keyVal, input.unknownKeyVals, getEnumLength(InputTypes));
63
+ if (!input.unknownKeyVals)
64
+ input.unknownKeyVals = [];
65
+ input.unknownKeyVals.push(keyVal);
66
+ return this;
67
+ }
68
+ addUnknownKeyValToOutput(outputIndex, keyVal) {
69
+ const output = checkForOutput(this.outputs, outputIndex);
70
+ checkHasKey(keyVal, output.unknownKeyVals, getEnumLength(OutputTypes));
71
+ if (!output.unknownKeyVals)
72
+ output.unknownKeyVals = [];
73
+ output.unknownKeyVals.push(keyVal);
74
+ return this;
75
+ }
76
+ addInput(inputData) {
77
+ this.globalMap.unsignedTx.addInput(inputData);
78
+ this.inputs.push({
79
+ unknownKeyVals: [],
80
+ });
81
+ const addKeyVals = inputData.unknownKeyVals || [];
82
+ const inputIndex = this.inputs.length - 1;
83
+ if (!Array.isArray(addKeyVals)) {
84
+ throw new Error('unknownKeyVals must be an Array');
85
+ }
86
+ addKeyVals.forEach((keyVal) => this.addUnknownKeyValToInput(inputIndex, keyVal));
87
+ addInputAttributes(this.inputs, inputData);
88
+ return this;
89
+ }
90
+ addOutput(outputData) {
91
+ this.globalMap.unsignedTx.addOutput(outputData);
92
+ this.outputs.push({
93
+ unknownKeyVals: [],
94
+ });
95
+ const addKeyVals = outputData.unknownKeyVals || [];
96
+ const outputIndex = this.outputs.length - 1;
97
+ if (!Array.isArray(addKeyVals)) {
98
+ throw new Error('unknownKeyVals must be an Array');
99
+ }
100
+ addKeyVals.forEach((keyVal) => this.addUnknownKeyValToOutput(outputIndex, keyVal));
101
+ addOutputAttributes(this.outputs, outputData);
102
+ return this;
103
+ }
104
+ clearFinalizedInput(inputIndex) {
105
+ const input = checkForInput(this.inputs, inputIndex);
106
+ inputCheckUncleanFinalized(inputIndex, input);
107
+ for (const key of Object.keys(input)) {
108
+ if (![
109
+ 'witnessUtxo',
110
+ 'opcatUtxo',
111
+ 'nonWitnessUtxo',
112
+ 'finalScriptSig',
113
+ 'finalScriptWitness',
114
+ 'unknownKeyVals',
115
+ ].includes(key)) {
116
+ // @ts-ignore
117
+ delete input[key];
118
+ }
119
+ }
120
+ return this;
121
+ }
122
+ combine(...those) {
123
+ // Combine this with those.
124
+ // Return self for chaining.
125
+ const result = combine([this].concat(those));
126
+ Object.assign(this, result);
127
+ return this;
128
+ }
129
+ getTransaction() {
130
+ return this.globalMap.unsignedTx.toBuffer();
131
+ }
132
+ }
133
+ export { checkForInput, checkForOutput } from './utils.js';
@@ -0,0 +1,34 @@
1
+ export declare enum GlobalTypes {
2
+ UNSIGNED_TX = 0,
3
+ GLOBAL_XPUB = 1
4
+ }
5
+ export declare const GLOBAL_TYPE_NAMES: string[];
6
+ export declare enum InputTypes {
7
+ NON_WITNESS_UTXO = 0,
8
+ WITNESS_UTXO = 1,
9
+ PARTIAL_SIG = 2,
10
+ SIGHASH_TYPE = 3,
11
+ REDEEM_SCRIPT = 4,
12
+ WITNESS_SCRIPT = 5,
13
+ BIP32_DERIVATION = 6,
14
+ FINAL_SCRIPTSIG = 7,
15
+ FINAL_SCRIPTWITNESS = 8,
16
+ POR_COMMITMENT = 9,
17
+ TAP_KEY_SIG = 19,
18
+ TAP_SCRIPT_SIG = 20,
19
+ TAP_LEAF_SCRIPT = 21,
20
+ TAP_BIP32_DERIVATION = 22,
21
+ TAP_INTERNAL_KEY = 23,
22
+ TAP_MERKLE_ROOT = 24,
23
+ OPCAT_UTXO = 25
24
+ }
25
+ export declare const INPUT_TYPE_NAMES: string[];
26
+ export declare enum OutputTypes {
27
+ REDEEM_SCRIPT = 0,
28
+ WITNESS_SCRIPT = 1,
29
+ BIP32_DERIVATION = 2,
30
+ TAP_INTERNAL_KEY = 5,
31
+ TAP_TREE = 6,
32
+ TAP_BIP32_DERIVATION = 7
33
+ }
34
+ export declare const OUTPUT_TYPE_NAMES: string[];
@@ -0,0 +1,62 @@
1
+ export var GlobalTypes;
2
+ (function (GlobalTypes) {
3
+ GlobalTypes[GlobalTypes["UNSIGNED_TX"] = 0] = "UNSIGNED_TX";
4
+ GlobalTypes[GlobalTypes["GLOBAL_XPUB"] = 1] = "GLOBAL_XPUB";
5
+ })(GlobalTypes || (GlobalTypes = {}));
6
+ export const GLOBAL_TYPE_NAMES = ['unsignedTx', 'globalXpub'];
7
+ export var InputTypes;
8
+ (function (InputTypes) {
9
+ InputTypes[InputTypes["NON_WITNESS_UTXO"] = 0] = "NON_WITNESS_UTXO";
10
+ InputTypes[InputTypes["WITNESS_UTXO"] = 1] = "WITNESS_UTXO";
11
+ InputTypes[InputTypes["PARTIAL_SIG"] = 2] = "PARTIAL_SIG";
12
+ InputTypes[InputTypes["SIGHASH_TYPE"] = 3] = "SIGHASH_TYPE";
13
+ InputTypes[InputTypes["REDEEM_SCRIPT"] = 4] = "REDEEM_SCRIPT";
14
+ InputTypes[InputTypes["WITNESS_SCRIPT"] = 5] = "WITNESS_SCRIPT";
15
+ InputTypes[InputTypes["BIP32_DERIVATION"] = 6] = "BIP32_DERIVATION";
16
+ InputTypes[InputTypes["FINAL_SCRIPTSIG"] = 7] = "FINAL_SCRIPTSIG";
17
+ InputTypes[InputTypes["FINAL_SCRIPTWITNESS"] = 8] = "FINAL_SCRIPTWITNESS";
18
+ InputTypes[InputTypes["POR_COMMITMENT"] = 9] = "POR_COMMITMENT";
19
+ InputTypes[InputTypes["TAP_KEY_SIG"] = 19] = "TAP_KEY_SIG";
20
+ InputTypes[InputTypes["TAP_SCRIPT_SIG"] = 20] = "TAP_SCRIPT_SIG";
21
+ InputTypes[InputTypes["TAP_LEAF_SCRIPT"] = 21] = "TAP_LEAF_SCRIPT";
22
+ InputTypes[InputTypes["TAP_BIP32_DERIVATION"] = 22] = "TAP_BIP32_DERIVATION";
23
+ InputTypes[InputTypes["TAP_INTERNAL_KEY"] = 23] = "TAP_INTERNAL_KEY";
24
+ InputTypes[InputTypes["TAP_MERKLE_ROOT"] = 24] = "TAP_MERKLE_ROOT";
25
+ InputTypes[InputTypes["OPCAT_UTXO"] = 25] = "OPCAT_UTXO";
26
+ })(InputTypes || (InputTypes = {}));
27
+ export const INPUT_TYPE_NAMES = [
28
+ 'nonWitnessUtxo',
29
+ 'witnessUtxo',
30
+ 'partialSig',
31
+ 'sighashType',
32
+ 'redeemScript',
33
+ 'witnessScript',
34
+ 'bip32Derivation',
35
+ 'finalScriptSig',
36
+ 'finalScriptWitness',
37
+ 'porCommitment',
38
+ 'tapKeySig',
39
+ 'tapScriptSig',
40
+ 'tapLeafScript',
41
+ 'tapBip32Derivation',
42
+ 'tapInternalKey',
43
+ 'tapMerkleRoot',
44
+ 'opcatUtxo',
45
+ ];
46
+ export var OutputTypes;
47
+ (function (OutputTypes) {
48
+ OutputTypes[OutputTypes["REDEEM_SCRIPT"] = 0] = "REDEEM_SCRIPT";
49
+ OutputTypes[OutputTypes["WITNESS_SCRIPT"] = 1] = "WITNESS_SCRIPT";
50
+ OutputTypes[OutputTypes["BIP32_DERIVATION"] = 2] = "BIP32_DERIVATION";
51
+ OutputTypes[OutputTypes["TAP_INTERNAL_KEY"] = 5] = "TAP_INTERNAL_KEY";
52
+ OutputTypes[OutputTypes["TAP_TREE"] = 6] = "TAP_TREE";
53
+ OutputTypes[OutputTypes["TAP_BIP32_DERIVATION"] = 7] = "TAP_BIP32_DERIVATION";
54
+ })(OutputTypes || (OutputTypes = {}));
55
+ export const OUTPUT_TYPE_NAMES = [
56
+ 'redeemScript',
57
+ 'witnessScript',
58
+ 'bip32Derivation',
59
+ 'tapInternalKey',
60
+ 'tapTree',
61
+ 'tapBip32Derivation',
62
+ ];
@@ -0,0 +1,13 @@
1
+ import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from './interfaces.js';
2
+ export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput;
3
+ export declare function checkForOutput(outputs: PsbtOutput[], outputIndex: number): PsbtOutput;
4
+ export declare function checkHasKey(checkKeyVal: KeyValue, keyVals: KeyValue[] | undefined, enumLength: number): void;
5
+ export declare function getEnumLength(myenum: any): number;
6
+ export declare function inputCheckUncleanFinalized(inputIndex: number, input: PsbtInput): void;
7
+ export declare const updateGlobal: (updateData: PsbtGlobalUpdate, mainData: PsbtGlobal) => void;
8
+ export declare const updateInput: (updateData: PsbtInputUpdate, mainData: PsbtInput) => void;
9
+ export declare const updateOutput: (updateData: PsbtOutputUpdate, mainData: PsbtOutput) => void;
10
+ export declare function addInputAttributes(inputs: PsbtInput[], data: any): void;
11
+ export declare function addOutputAttributes(outputs: PsbtOutput[], data: any): void;
12
+ export declare function defaultVersionSetter(version: number, txBuf: Uint8Array): Uint8Array;
13
+ export declare function defaultLocktimeSetter(locktime: number, txBuf: Uint8Array): Uint8Array;
@@ -0,0 +1,123 @@
1
+ import * as converter from './converter/index.js';
2
+ import * as tools from 'uint8array-tools';
3
+ export function checkForInput(inputs, inputIndex) {
4
+ const input = inputs[inputIndex];
5
+ if (input === undefined)
6
+ throw new Error(`No input #${inputIndex}`);
7
+ return input;
8
+ }
9
+ export function checkForOutput(outputs, outputIndex) {
10
+ const output = outputs[outputIndex];
11
+ if (output === undefined)
12
+ throw new Error(`No output #${outputIndex}`);
13
+ return output;
14
+ }
15
+ export function checkHasKey(checkKeyVal, keyVals, enumLength) {
16
+ if (checkKeyVal.key[0] < enumLength) {
17
+ throw new Error(`Use the method for your specific key instead of addUnknownKeyVal*`);
18
+ }
19
+ if (keyVals &&
20
+ keyVals.filter(kv => tools.compare(kv.key, checkKeyVal.key) === 0)
21
+ .length !== 0) {
22
+ throw new Error(`Duplicate Key: ${tools.toHex(checkKeyVal.key)}`);
23
+ }
24
+ }
25
+ export function getEnumLength(myenum) {
26
+ let count = 0;
27
+ Object.keys(myenum).forEach(val => {
28
+ if (Number(isNaN(Number(val)))) {
29
+ count++;
30
+ }
31
+ });
32
+ return count;
33
+ }
34
+ export function inputCheckUncleanFinalized(inputIndex, input) {
35
+ let result = false;
36
+ if (input.nonWitnessUtxo || input.witnessUtxo || input.opcatUtxo) {
37
+ const needScriptSig = !!input.redeemScript;
38
+ const needWitnessScript = !!input.witnessScript;
39
+ const scriptSigOK = !needScriptSig || !!input.finalScriptSig;
40
+ const witnessScriptOK = !needWitnessScript || !!input.finalScriptWitness;
41
+ const hasOneFinal = !!input.finalScriptSig || !!input.finalScriptWitness;
42
+ result = scriptSigOK && witnessScriptOK && hasOneFinal;
43
+ }
44
+ if (result === false) {
45
+ throw new Error(`Input #${inputIndex} has too much or too little data to clean`);
46
+ }
47
+ }
48
+ function throwForUpdateMaker(typeName, name, expected, data) {
49
+ throw new Error(`Data for ${typeName} key ${name} is incorrect: Expected ` +
50
+ `${expected} and got ${JSON.stringify(data)}`);
51
+ }
52
+ function updateMaker(typeName) {
53
+ return (updateData, mainData) => {
54
+ // @ts-ignore
55
+ for (const name of Object.keys(updateData)) {
56
+ // @ts-ignore
57
+ const data = updateData[name];
58
+ // @ts-ignore
59
+ const { canAdd, canAddToArray, check, expected } =
60
+ // @ts-ignore
61
+ converter[typeName + 's'][name] || {};
62
+ const isArray = !!canAddToArray;
63
+ // If unknown data. ignore and do not add
64
+ if (check) {
65
+ if (isArray) {
66
+ if (!Array.isArray(data) ||
67
+ // @ts-ignore
68
+ (mainData[name] && !Array.isArray(mainData[name]))) {
69
+ throw new Error(`Key type ${name} must be an array`);
70
+ }
71
+ if (!data.every(check)) {
72
+ throwForUpdateMaker(typeName, name, expected, data);
73
+ }
74
+ // @ts-ignore
75
+ const arr = mainData[name] || [];
76
+ const dupeCheckSet = new Set();
77
+ if (!data.every(v => canAddToArray(arr, v, dupeCheckSet))) {
78
+ throw new Error('Can not add duplicate data to array');
79
+ }
80
+ // @ts-ignore
81
+ mainData[name] = arr.concat(data);
82
+ }
83
+ else {
84
+ if (!check(data)) {
85
+ throwForUpdateMaker(typeName, name, expected, data);
86
+ }
87
+ if (!canAdd(mainData, data)) {
88
+ throw new Error(`Can not add duplicate data to ${typeName}`);
89
+ }
90
+ // @ts-ignore
91
+ mainData[name] = data;
92
+ }
93
+ }
94
+ }
95
+ };
96
+ }
97
+ export const updateGlobal = updateMaker('global');
98
+ export const updateInput = updateMaker('input');
99
+ export const updateOutput = updateMaker('output');
100
+ export function addInputAttributes(inputs, data) {
101
+ const index = inputs.length - 1;
102
+ const input = checkForInput(inputs, index);
103
+ updateInput(data, input);
104
+ }
105
+ export function addOutputAttributes(outputs, data) {
106
+ const index = outputs.length - 1;
107
+ const output = checkForOutput(outputs, index);
108
+ updateOutput(data, output);
109
+ }
110
+ export function defaultVersionSetter(version, txBuf) {
111
+ if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) {
112
+ throw new Error('Set Version: Invalid Transaction');
113
+ }
114
+ tools.writeUInt32(txBuf, 0, version, 'LE');
115
+ return txBuf;
116
+ }
117
+ export function defaultLocktimeSetter(locktime, txBuf) {
118
+ if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) {
119
+ throw new Error('Set Locktime: Invalid Transaction');
120
+ }
121
+ tools.writeUInt32(txBuf, txBuf.length - 4, locktime, 'LE');
122
+ return txBuf;
123
+ }