@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.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/package.json +66 -0
- package/src/cjs/lib/combiner/index.js +67 -0
- package/src/cjs/lib/converter/global/globalXpub.js +83 -0
- package/src/cjs/lib/converter/global/unsignedTx.js +10 -0
- package/src/cjs/lib/converter/index.js +72 -0
- package/src/cjs/lib/converter/input/finalScriptSig.js +36 -0
- package/src/cjs/lib/converter/input/finalScriptWitness.js +36 -0
- package/src/cjs/lib/converter/input/nonWitnessUtxo.js +35 -0
- package/src/cjs/lib/converter/input/opcatUtxo.js +74 -0
- package/src/cjs/lib/converter/input/partialSig.js +74 -0
- package/src/cjs/lib/converter/input/porCommitment.js +36 -0
- package/src/cjs/lib/converter/input/sighashType.js +38 -0
- package/src/cjs/lib/converter/input/tapKeySig.js +36 -0
- package/src/cjs/lib/converter/input/tapLeafScript.js +56 -0
- package/src/cjs/lib/converter/input/tapMerkleRoot.js +36 -0
- package/src/cjs/lib/converter/input/tapScriptSig.js +59 -0
- package/src/cjs/lib/converter/input/witnessUtxo.js +53 -0
- package/src/cjs/lib/converter/output/tapTree.js +60 -0
- package/src/cjs/lib/converter/shared/bip32Derivation.js +84 -0
- package/src/cjs/lib/converter/shared/checkPubkey.js +25 -0
- package/src/cjs/lib/converter/shared/redeemScript.js +41 -0
- package/src/cjs/lib/converter/shared/tapBip32Derivation.js +55 -0
- package/src/cjs/lib/converter/shared/tapInternalKey.js +41 -0
- package/src/cjs/lib/converter/shared/witnessScript.js +41 -0
- package/src/cjs/lib/converter/tools.js +45 -0
- package/src/cjs/lib/interfaces.js +2 -0
- package/src/cjs/lib/parser/fromBuffer.js +325 -0
- package/src/cjs/lib/parser/index.js +7 -0
- package/src/cjs/lib/parser/toBuffer.js +69 -0
- package/src/cjs/lib/psbt.js +145 -0
- package/src/cjs/lib/typeFields.js +64 -0
- package/src/cjs/lib/utils.js +141 -0
- package/src/esm/lib/combiner/index.d.ts +2 -0
- package/src/esm/lib/combiner/index.js +57 -0
- package/src/esm/lib/converter/global/globalXpub.d.ts +6 -0
- package/src/esm/lib/converter/global/globalXpub.js +70 -0
- package/src/esm/lib/converter/global/unsignedTx.d.ts +2 -0
- package/src/esm/lib/converter/global/unsignedTx.js +7 -0
- package/src/esm/lib/converter/index.d.ts +110 -0
- package/src/esm/lib/converter/index.js +61 -0
- package/src/esm/lib/converter/input/finalScriptSig.d.ts +6 -0
- package/src/esm/lib/converter/input/finalScriptSig.js +23 -0
- package/src/esm/lib/converter/input/finalScriptWitness.d.ts +6 -0
- package/src/esm/lib/converter/input/finalScriptWitness.js +23 -0
- package/src/esm/lib/converter/input/nonWitnessUtxo.d.ts +6 -0
- package/src/esm/lib/converter/input/nonWitnessUtxo.js +22 -0
- package/src/esm/lib/converter/input/opcatUtxo.d.ts +6 -0
- package/src/esm/lib/converter/input/opcatUtxo.js +61 -0
- package/src/esm/lib/converter/input/partialSig.d.ts +6 -0
- package/src/esm/lib/converter/input/partialSig.js +61 -0
- package/src/esm/lib/converter/input/porCommitment.d.ts +6 -0
- package/src/esm/lib/converter/input/porCommitment.js +23 -0
- package/src/esm/lib/converter/input/sighashType.d.ts +6 -0
- package/src/esm/lib/converter/input/sighashType.js +25 -0
- package/src/esm/lib/converter/input/tapKeySig.d.ts +6 -0
- package/src/esm/lib/converter/input/tapKeySig.js +23 -0
- package/src/esm/lib/converter/input/tapLeafScript.d.ts +6 -0
- package/src/esm/lib/converter/input/tapLeafScript.js +43 -0
- package/src/esm/lib/converter/input/tapMerkleRoot.d.ts +6 -0
- package/src/esm/lib/converter/input/tapMerkleRoot.js +23 -0
- package/src/esm/lib/converter/input/tapScriptSig.d.ts +6 -0
- package/src/esm/lib/converter/input/tapScriptSig.js +46 -0
- package/src/esm/lib/converter/input/witnessUtxo.d.ts +6 -0
- package/src/esm/lib/converter/input/witnessUtxo.js +40 -0
- package/src/esm/lib/converter/output/tapTree.d.ts +6 -0
- package/src/esm/lib/converter/output/tapTree.js +47 -0
- package/src/esm/lib/converter/shared/bip32Derivation.d.ts +8 -0
- package/src/esm/lib/converter/shared/bip32Derivation.js +74 -0
- package/src/esm/lib/converter/shared/checkPubkey.d.ts +2 -0
- package/src/esm/lib/converter/shared/checkPubkey.js +15 -0
- package/src/esm/lib/converter/shared/redeemScript.d.ts +8 -0
- package/src/esm/lib/converter/shared/redeemScript.js +31 -0
- package/src/esm/lib/converter/shared/tapBip32Derivation.d.ts +8 -0
- package/src/esm/lib/converter/shared/tapBip32Derivation.js +45 -0
- package/src/esm/lib/converter/shared/tapInternalKey.d.ts +8 -0
- package/src/esm/lib/converter/shared/tapInternalKey.js +31 -0
- package/src/esm/lib/converter/shared/witnessScript.d.ts +8 -0
- package/src/esm/lib/converter/shared/witnessScript.js +31 -0
- package/src/esm/lib/converter/tools.d.ts +5 -0
- package/src/esm/lib/converter/tools.js +33 -0
- package/src/esm/lib/interfaces.d.ts +120 -0
- package/src/esm/lib/interfaces.js +0 -0
- package/src/esm/lib/parser/fromBuffer.d.ts +11 -0
- package/src/esm/lib/parser/fromBuffer.js +313 -0
- package/src/esm/lib/parser/index.d.ts +8 -0
- package/src/esm/lib/parser/index.js +2 -0
- package/src/esm/lib/parser/toBuffer.d.ts +8 -0
- package/src/esm/lib/parser/toBuffer.js +58 -0
- package/src/esm/lib/psbt.d.ts +26 -0
- package/src/esm/lib/psbt.js +133 -0
- package/src/esm/lib/typeFields.d.ts +34 -0
- package/src/esm/lib/typeFields.js +62 -0
- package/src/esm/lib/utils.d.ts +13 -0
- 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
|
+
}
|