@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,64 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
var GlobalTypes;
|
4
|
+
(function (GlobalTypes) {
|
5
|
+
GlobalTypes[GlobalTypes["UNSIGNED_TX"] = 0] = "UNSIGNED_TX";
|
6
|
+
GlobalTypes[GlobalTypes["GLOBAL_XPUB"] = 1] = "GLOBAL_XPUB";
|
7
|
+
})(GlobalTypes = exports.GlobalTypes || (exports.GlobalTypes = {}));
|
8
|
+
exports.GLOBAL_TYPE_NAMES = ['unsignedTx', 'globalXpub'];
|
9
|
+
var InputTypes;
|
10
|
+
(function (InputTypes) {
|
11
|
+
InputTypes[InputTypes["NON_WITNESS_UTXO"] = 0] = "NON_WITNESS_UTXO";
|
12
|
+
InputTypes[InputTypes["WITNESS_UTXO"] = 1] = "WITNESS_UTXO";
|
13
|
+
InputTypes[InputTypes["PARTIAL_SIG"] = 2] = "PARTIAL_SIG";
|
14
|
+
InputTypes[InputTypes["SIGHASH_TYPE"] = 3] = "SIGHASH_TYPE";
|
15
|
+
InputTypes[InputTypes["REDEEM_SCRIPT"] = 4] = "REDEEM_SCRIPT";
|
16
|
+
InputTypes[InputTypes["WITNESS_SCRIPT"] = 5] = "WITNESS_SCRIPT";
|
17
|
+
InputTypes[InputTypes["BIP32_DERIVATION"] = 6] = "BIP32_DERIVATION";
|
18
|
+
InputTypes[InputTypes["FINAL_SCRIPTSIG"] = 7] = "FINAL_SCRIPTSIG";
|
19
|
+
InputTypes[InputTypes["FINAL_SCRIPTWITNESS"] = 8] = "FINAL_SCRIPTWITNESS";
|
20
|
+
InputTypes[InputTypes["POR_COMMITMENT"] = 9] = "POR_COMMITMENT";
|
21
|
+
InputTypes[InputTypes["TAP_KEY_SIG"] = 19] = "TAP_KEY_SIG";
|
22
|
+
InputTypes[InputTypes["TAP_SCRIPT_SIG"] = 20] = "TAP_SCRIPT_SIG";
|
23
|
+
InputTypes[InputTypes["TAP_LEAF_SCRIPT"] = 21] = "TAP_LEAF_SCRIPT";
|
24
|
+
InputTypes[InputTypes["TAP_BIP32_DERIVATION"] = 22] = "TAP_BIP32_DERIVATION";
|
25
|
+
InputTypes[InputTypes["TAP_INTERNAL_KEY"] = 23] = "TAP_INTERNAL_KEY";
|
26
|
+
InputTypes[InputTypes["TAP_MERKLE_ROOT"] = 24] = "TAP_MERKLE_ROOT";
|
27
|
+
InputTypes[InputTypes["OPCAT_UTXO"] = 25] = "OPCAT_UTXO";
|
28
|
+
})(InputTypes = exports.InputTypes || (exports.InputTypes = {}));
|
29
|
+
exports.INPUT_TYPE_NAMES = [
|
30
|
+
'nonWitnessUtxo',
|
31
|
+
'witnessUtxo',
|
32
|
+
'partialSig',
|
33
|
+
'sighashType',
|
34
|
+
'redeemScript',
|
35
|
+
'witnessScript',
|
36
|
+
'bip32Derivation',
|
37
|
+
'finalScriptSig',
|
38
|
+
'finalScriptWitness',
|
39
|
+
'porCommitment',
|
40
|
+
'tapKeySig',
|
41
|
+
'tapScriptSig',
|
42
|
+
'tapLeafScript',
|
43
|
+
'tapBip32Derivation',
|
44
|
+
'tapInternalKey',
|
45
|
+
'tapMerkleRoot',
|
46
|
+
'opcatUtxo',
|
47
|
+
];
|
48
|
+
var OutputTypes;
|
49
|
+
(function (OutputTypes) {
|
50
|
+
OutputTypes[OutputTypes["REDEEM_SCRIPT"] = 0] = "REDEEM_SCRIPT";
|
51
|
+
OutputTypes[OutputTypes["WITNESS_SCRIPT"] = 1] = "WITNESS_SCRIPT";
|
52
|
+
OutputTypes[OutputTypes["BIP32_DERIVATION"] = 2] = "BIP32_DERIVATION";
|
53
|
+
OutputTypes[OutputTypes["TAP_INTERNAL_KEY"] = 5] = "TAP_INTERNAL_KEY";
|
54
|
+
OutputTypes[OutputTypes["TAP_TREE"] = 6] = "TAP_TREE";
|
55
|
+
OutputTypes[OutputTypes["TAP_BIP32_DERIVATION"] = 7] = "TAP_BIP32_DERIVATION";
|
56
|
+
})(OutputTypes = exports.OutputTypes || (exports.OutputTypes = {}));
|
57
|
+
exports.OUTPUT_TYPE_NAMES = [
|
58
|
+
'redeemScript',
|
59
|
+
'witnessScript',
|
60
|
+
'bip32Derivation',
|
61
|
+
'tapInternalKey',
|
62
|
+
'tapTree',
|
63
|
+
'tapBip32Derivation',
|
64
|
+
];
|
@@ -0,0 +1,141 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
3
|
+
if (mod && mod.__esModule) return mod;
|
4
|
+
var result = {};
|
5
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
6
|
+
result["default"] = mod;
|
7
|
+
return result;
|
8
|
+
};
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
const converter = __importStar(require("./converter/index.js"));
|
11
|
+
const tools = __importStar(require("uint8array-tools"));
|
12
|
+
function checkForInput(inputs, inputIndex) {
|
13
|
+
const input = inputs[inputIndex];
|
14
|
+
if (input === undefined)
|
15
|
+
throw new Error(`No input #${inputIndex}`);
|
16
|
+
return input;
|
17
|
+
}
|
18
|
+
exports.checkForInput = checkForInput;
|
19
|
+
function checkForOutput(outputs, outputIndex) {
|
20
|
+
const output = outputs[outputIndex];
|
21
|
+
if (output === undefined)
|
22
|
+
throw new Error(`No output #${outputIndex}`);
|
23
|
+
return output;
|
24
|
+
}
|
25
|
+
exports.checkForOutput = checkForOutput;
|
26
|
+
function checkHasKey(checkKeyVal, keyVals, enumLength) {
|
27
|
+
if (checkKeyVal.key[0] < enumLength) {
|
28
|
+
throw new Error(`Use the method for your specific key instead of addUnknownKeyVal*`);
|
29
|
+
}
|
30
|
+
if (keyVals &&
|
31
|
+
keyVals.filter(kv => tools.compare(kv.key, checkKeyVal.key) === 0)
|
32
|
+
.length !== 0) {
|
33
|
+
throw new Error(`Duplicate Key: ${tools.toHex(checkKeyVal.key)}`);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
exports.checkHasKey = checkHasKey;
|
37
|
+
function getEnumLength(myenum) {
|
38
|
+
let count = 0;
|
39
|
+
Object.keys(myenum).forEach(val => {
|
40
|
+
if (Number(isNaN(Number(val)))) {
|
41
|
+
count++;
|
42
|
+
}
|
43
|
+
});
|
44
|
+
return count;
|
45
|
+
}
|
46
|
+
exports.getEnumLength = getEnumLength;
|
47
|
+
function inputCheckUncleanFinalized(inputIndex, input) {
|
48
|
+
let result = false;
|
49
|
+
if (input.nonWitnessUtxo || input.witnessUtxo || input.opcatUtxo) {
|
50
|
+
const needScriptSig = !!input.redeemScript;
|
51
|
+
const needWitnessScript = !!input.witnessScript;
|
52
|
+
const scriptSigOK = !needScriptSig || !!input.finalScriptSig;
|
53
|
+
const witnessScriptOK = !needWitnessScript || !!input.finalScriptWitness;
|
54
|
+
const hasOneFinal = !!input.finalScriptSig || !!input.finalScriptWitness;
|
55
|
+
result = scriptSigOK && witnessScriptOK && hasOneFinal;
|
56
|
+
}
|
57
|
+
if (result === false) {
|
58
|
+
throw new Error(`Input #${inputIndex} has too much or too little data to clean`);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
exports.inputCheckUncleanFinalized = inputCheckUncleanFinalized;
|
62
|
+
function throwForUpdateMaker(typeName, name, expected, data) {
|
63
|
+
throw new Error(`Data for ${typeName} key ${name} is incorrect: Expected ` +
|
64
|
+
`${expected} and got ${JSON.stringify(data)}`);
|
65
|
+
}
|
66
|
+
function updateMaker(typeName) {
|
67
|
+
return (updateData, mainData) => {
|
68
|
+
// @ts-ignore
|
69
|
+
for (const name of Object.keys(updateData)) {
|
70
|
+
// @ts-ignore
|
71
|
+
const data = updateData[name];
|
72
|
+
// @ts-ignore
|
73
|
+
const { canAdd, canAddToArray, check, expected } =
|
74
|
+
// @ts-ignore
|
75
|
+
converter[typeName + 's'][name] || {};
|
76
|
+
const isArray = !!canAddToArray;
|
77
|
+
// If unknown data. ignore and do not add
|
78
|
+
if (check) {
|
79
|
+
if (isArray) {
|
80
|
+
if (!Array.isArray(data) ||
|
81
|
+
// @ts-ignore
|
82
|
+
(mainData[name] && !Array.isArray(mainData[name]))) {
|
83
|
+
throw new Error(`Key type ${name} must be an array`);
|
84
|
+
}
|
85
|
+
if (!data.every(check)) {
|
86
|
+
throwForUpdateMaker(typeName, name, expected, data);
|
87
|
+
}
|
88
|
+
// @ts-ignore
|
89
|
+
const arr = mainData[name] || [];
|
90
|
+
const dupeCheckSet = new Set();
|
91
|
+
if (!data.every(v => canAddToArray(arr, v, dupeCheckSet))) {
|
92
|
+
throw new Error('Can not add duplicate data to array');
|
93
|
+
}
|
94
|
+
// @ts-ignore
|
95
|
+
mainData[name] = arr.concat(data);
|
96
|
+
}
|
97
|
+
else {
|
98
|
+
if (!check(data)) {
|
99
|
+
throwForUpdateMaker(typeName, name, expected, data);
|
100
|
+
}
|
101
|
+
if (!canAdd(mainData, data)) {
|
102
|
+
throw new Error(`Can not add duplicate data to ${typeName}`);
|
103
|
+
}
|
104
|
+
// @ts-ignore
|
105
|
+
mainData[name] = data;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
};
|
110
|
+
}
|
111
|
+
exports.updateGlobal = updateMaker('global');
|
112
|
+
exports.updateInput = updateMaker('input');
|
113
|
+
exports.updateOutput = updateMaker('output');
|
114
|
+
function addInputAttributes(inputs, data) {
|
115
|
+
const index = inputs.length - 1;
|
116
|
+
const input = checkForInput(inputs, index);
|
117
|
+
exports.updateInput(data, input);
|
118
|
+
}
|
119
|
+
exports.addInputAttributes = addInputAttributes;
|
120
|
+
function addOutputAttributes(outputs, data) {
|
121
|
+
const index = outputs.length - 1;
|
122
|
+
const output = checkForOutput(outputs, index);
|
123
|
+
exports.updateOutput(data, output);
|
124
|
+
}
|
125
|
+
exports.addOutputAttributes = addOutputAttributes;
|
126
|
+
function defaultVersionSetter(version, txBuf) {
|
127
|
+
if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) {
|
128
|
+
throw new Error('Set Version: Invalid Transaction');
|
129
|
+
}
|
130
|
+
tools.writeUInt32(txBuf, 0, version, 'LE');
|
131
|
+
return txBuf;
|
132
|
+
}
|
133
|
+
exports.defaultVersionSetter = defaultVersionSetter;
|
134
|
+
function defaultLocktimeSetter(locktime, txBuf) {
|
135
|
+
if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) {
|
136
|
+
throw new Error('Set Locktime: Invalid Transaction');
|
137
|
+
}
|
138
|
+
tools.writeUInt32(txBuf, txBuf.length - 4, locktime, 'LE');
|
139
|
+
return txBuf;
|
140
|
+
}
|
141
|
+
exports.defaultLocktimeSetter = defaultLocktimeSetter;
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { psbtFromKeyVals, psbtToKeyVals, } from '../parser/index.js';
|
2
|
+
import * as tools from 'uint8array-tools';
|
3
|
+
export function combine(psbts) {
|
4
|
+
const self = psbts[0];
|
5
|
+
const selfKeyVals = psbtToKeyVals(self);
|
6
|
+
const others = psbts.slice(1);
|
7
|
+
if (others.length === 0)
|
8
|
+
throw new Error('Combine: Nothing to combine');
|
9
|
+
const selfTx = getTx(self);
|
10
|
+
if (selfTx === undefined) {
|
11
|
+
throw new Error('Combine: Self missing transaction');
|
12
|
+
}
|
13
|
+
const selfGlobalSet = getKeySet(selfKeyVals.globalKeyVals);
|
14
|
+
const selfInputSets = selfKeyVals.inputKeyVals.map(getKeySet);
|
15
|
+
const selfOutputSets = selfKeyVals.outputKeyVals.map(getKeySet);
|
16
|
+
for (const other of others) {
|
17
|
+
const otherTx = getTx(other);
|
18
|
+
if (otherTx === undefined ||
|
19
|
+
tools.compare(otherTx.toBuffer(), selfTx.toBuffer()) !== 0) {
|
20
|
+
throw new Error('Combine: One of the Psbts does not have the same transaction.');
|
21
|
+
}
|
22
|
+
const otherKeyVals = psbtToKeyVals(other);
|
23
|
+
const otherGlobalSet = getKeySet(otherKeyVals.globalKeyVals);
|
24
|
+
otherGlobalSet.forEach(keyPusher(selfGlobalSet, selfKeyVals.globalKeyVals, otherKeyVals.globalKeyVals));
|
25
|
+
const otherInputSets = otherKeyVals.inputKeyVals.map(getKeySet);
|
26
|
+
otherInputSets.forEach((inputSet, idx) => inputSet.forEach(keyPusher(selfInputSets[idx], selfKeyVals.inputKeyVals[idx], otherKeyVals.inputKeyVals[idx])));
|
27
|
+
const otherOutputSets = otherKeyVals.outputKeyVals.map(getKeySet);
|
28
|
+
otherOutputSets.forEach((outputSet, idx) => outputSet.forEach(keyPusher(selfOutputSets[idx], selfKeyVals.outputKeyVals[idx], otherKeyVals.outputKeyVals[idx])));
|
29
|
+
}
|
30
|
+
return psbtFromKeyVals(selfTx, {
|
31
|
+
globalMapKeyVals: selfKeyVals.globalKeyVals,
|
32
|
+
inputKeyVals: selfKeyVals.inputKeyVals,
|
33
|
+
outputKeyVals: selfKeyVals.outputKeyVals,
|
34
|
+
});
|
35
|
+
}
|
36
|
+
function keyPusher(selfSet, selfKeyVals, otherKeyVals) {
|
37
|
+
return (key) => {
|
38
|
+
if (selfSet.has(key))
|
39
|
+
return;
|
40
|
+
const newKv = otherKeyVals.filter(kv => tools.toHex(kv.key) === key)[0];
|
41
|
+
selfKeyVals.push(newKv);
|
42
|
+
selfSet.add(key);
|
43
|
+
};
|
44
|
+
}
|
45
|
+
function getTx(psbt) {
|
46
|
+
return psbt.globalMap.unsignedTx;
|
47
|
+
}
|
48
|
+
function getKeySet(keyVals) {
|
49
|
+
const set = new Set();
|
50
|
+
keyVals.forEach(keyVal => {
|
51
|
+
const hex = tools.toHex(keyVal.key);
|
52
|
+
if (set.has(hex))
|
53
|
+
throw new Error('Combine: KeyValue Map keys should be unique');
|
54
|
+
set.add(hex);
|
55
|
+
});
|
56
|
+
return set;
|
57
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { GlobalXpub, KeyValue } from '../../interfaces';
|
2
|
+
export declare function decode(keyVal: KeyValue): GlobalXpub;
|
3
|
+
export declare function encode(data: GlobalXpub): KeyValue;
|
4
|
+
export declare const expected = "{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }";
|
5
|
+
export declare function check(data: any): data is GlobalXpub;
|
6
|
+
export declare function canAddToArray(array: GlobalXpub[], item: GlobalXpub, dupeSet: Set<string>): boolean;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import { GlobalTypes } from '../../typeFields.js';
|
2
|
+
import * as tools from 'uint8array-tools';
|
3
|
+
const range = (n) => [...Array(n).keys()];
|
4
|
+
export function decode(keyVal) {
|
5
|
+
if (keyVal.key[0] !== GlobalTypes.GLOBAL_XPUB) {
|
6
|
+
throw new Error('Decode Error: could not decode globalXpub with key 0x' +
|
7
|
+
tools.toHex(keyVal.key));
|
8
|
+
}
|
9
|
+
if (keyVal.key.length !== 79 || ![2, 3].includes(keyVal.key[46])) {
|
10
|
+
throw new Error('Decode Error: globalXpub has invalid extended pubkey in key 0x' +
|
11
|
+
tools.toHex(keyVal.key));
|
12
|
+
}
|
13
|
+
if ((keyVal.value.length / 4) % 1 !== 0) {
|
14
|
+
throw new Error('Decode Error: Global GLOBAL_XPUB value length should be multiple of 4');
|
15
|
+
}
|
16
|
+
const extendedPubkey = keyVal.key.slice(1);
|
17
|
+
const data = {
|
18
|
+
masterFingerprint: keyVal.value.slice(0, 4),
|
19
|
+
extendedPubkey,
|
20
|
+
path: 'm',
|
21
|
+
};
|
22
|
+
for (const i of range(keyVal.value.length / 4 - 1)) {
|
23
|
+
const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE');
|
24
|
+
const isHard = !!(val & 0x80000000);
|
25
|
+
const idx = val & 0x7fffffff;
|
26
|
+
data.path += '/' + idx.toString(10) + (isHard ? "'" : '');
|
27
|
+
}
|
28
|
+
return data;
|
29
|
+
}
|
30
|
+
export function encode(data) {
|
31
|
+
const head = new Uint8Array([GlobalTypes.GLOBAL_XPUB]);
|
32
|
+
const key = tools.concat([head, data.extendedPubkey]);
|
33
|
+
const splitPath = data.path.split('/');
|
34
|
+
const value = new Uint8Array(splitPath.length * 4);
|
35
|
+
value.set(data.masterFingerprint, 0);
|
36
|
+
let offset = 4;
|
37
|
+
splitPath.slice(1).forEach(level => {
|
38
|
+
const isHard = level.slice(-1) === "'";
|
39
|
+
let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10);
|
40
|
+
if (isHard)
|
41
|
+
num += 0x80000000;
|
42
|
+
tools.writeUInt32(value, offset, num, 'LE');
|
43
|
+
offset += 4;
|
44
|
+
});
|
45
|
+
return {
|
46
|
+
key,
|
47
|
+
value,
|
48
|
+
};
|
49
|
+
}
|
50
|
+
export const expected = '{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }';
|
51
|
+
export function check(data) {
|
52
|
+
const epk = data.extendedPubkey;
|
53
|
+
const mfp = data.masterFingerprint;
|
54
|
+
const p = data.path;
|
55
|
+
return (epk instanceof Uint8Array &&
|
56
|
+
epk.length === 78 &&
|
57
|
+
[2, 3].indexOf(epk[45]) > -1 &&
|
58
|
+
mfp instanceof Uint8Array &&
|
59
|
+
mfp.length === 4 &&
|
60
|
+
typeof p === 'string' &&
|
61
|
+
!!p.match(/^m(\/\d+'?)*$/));
|
62
|
+
}
|
63
|
+
export function canAddToArray(array, item, dupeSet) {
|
64
|
+
const dupeString = tools.toHex(item.extendedPubkey);
|
65
|
+
if (dupeSet.has(dupeString))
|
66
|
+
return false;
|
67
|
+
dupeSet.add(dupeString);
|
68
|
+
return (array.filter(v => tools.compare(v.extendedPubkey, item.extendedPubkey))
|
69
|
+
.length === 0);
|
70
|
+
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import * as globalXpub from './global/globalXpub.js';
|
2
|
+
import * as unsignedTx from './global/unsignedTx.js';
|
3
|
+
import * as finalScriptSig from './input/finalScriptSig.js';
|
4
|
+
import * as finalScriptWitness from './input/finalScriptWitness.js';
|
5
|
+
import * as nonWitnessUtxo from './input/nonWitnessUtxo.js';
|
6
|
+
import * as partialSig from './input/partialSig.js';
|
7
|
+
import * as porCommitment from './input/porCommitment.js';
|
8
|
+
import * as sighashType from './input/sighashType.js';
|
9
|
+
import * as tapKeySig from './input/tapKeySig.js';
|
10
|
+
import * as tapLeafScript from './input/tapLeafScript.js';
|
11
|
+
import * as tapMerkleRoot from './input/tapMerkleRoot.js';
|
12
|
+
import * as tapScriptSig from './input/tapScriptSig.js';
|
13
|
+
import * as witnessUtxo from './input/witnessUtxo.js';
|
14
|
+
import * as opcatUtxo from './input/opcatUtxo.js';
|
15
|
+
import * as tapTree from './output/tapTree.js';
|
16
|
+
declare const globals: {
|
17
|
+
unsignedTx: typeof unsignedTx;
|
18
|
+
globalXpub: typeof globalXpub;
|
19
|
+
checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined;
|
20
|
+
};
|
21
|
+
declare const inputs: {
|
22
|
+
nonWitnessUtxo: typeof nonWitnessUtxo;
|
23
|
+
partialSig: typeof partialSig;
|
24
|
+
sighashType: typeof sighashType;
|
25
|
+
finalScriptSig: typeof finalScriptSig;
|
26
|
+
finalScriptWitness: typeof finalScriptWitness;
|
27
|
+
porCommitment: typeof porCommitment;
|
28
|
+
witnessUtxo: typeof witnessUtxo;
|
29
|
+
opcatUtxo: typeof opcatUtxo;
|
30
|
+
bip32Derivation: {
|
31
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation;
|
32
|
+
encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue;
|
33
|
+
check: (data: any) => data is import("../interfaces.js").Bip32Derivation;
|
34
|
+
expected: string;
|
35
|
+
canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set<string>) => boolean;
|
36
|
+
};
|
37
|
+
redeemScript: {
|
38
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
39
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
40
|
+
check: (data: any) => data is Uint8Array;
|
41
|
+
expected: string;
|
42
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
43
|
+
};
|
44
|
+
witnessScript: {
|
45
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
46
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
47
|
+
check: (data: any) => data is Uint8Array;
|
48
|
+
expected: string;
|
49
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
50
|
+
};
|
51
|
+
checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined;
|
52
|
+
tapKeySig: typeof tapKeySig;
|
53
|
+
tapScriptSig: typeof tapScriptSig;
|
54
|
+
tapLeafScript: typeof tapLeafScript;
|
55
|
+
tapBip32Derivation: {
|
56
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation;
|
57
|
+
encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue;
|
58
|
+
check: (data: any) => data is import("../interfaces.js").TapBip32Derivation;
|
59
|
+
expected: string;
|
60
|
+
canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set<string>) => boolean;
|
61
|
+
};
|
62
|
+
tapInternalKey: {
|
63
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
64
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
65
|
+
check: (data: any) => data is Uint8Array;
|
66
|
+
expected: string;
|
67
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
68
|
+
};
|
69
|
+
tapMerkleRoot: typeof tapMerkleRoot;
|
70
|
+
};
|
71
|
+
declare const outputs: {
|
72
|
+
bip32Derivation: {
|
73
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation;
|
74
|
+
encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue;
|
75
|
+
check: (data: any) => data is import("../interfaces.js").Bip32Derivation;
|
76
|
+
expected: string;
|
77
|
+
canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set<string>) => boolean;
|
78
|
+
};
|
79
|
+
redeemScript: {
|
80
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
81
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
82
|
+
check: (data: any) => data is Uint8Array;
|
83
|
+
expected: string;
|
84
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
85
|
+
};
|
86
|
+
witnessScript: {
|
87
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
88
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
89
|
+
check: (data: any) => data is Uint8Array;
|
90
|
+
expected: string;
|
91
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
92
|
+
};
|
93
|
+
checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined;
|
94
|
+
tapBip32Derivation: {
|
95
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation;
|
96
|
+
encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue;
|
97
|
+
check: (data: any) => data is import("../interfaces.js").TapBip32Derivation;
|
98
|
+
expected: string;
|
99
|
+
canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set<string>) => boolean;
|
100
|
+
};
|
101
|
+
tapTree: typeof tapTree;
|
102
|
+
tapInternalKey: {
|
103
|
+
decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array;
|
104
|
+
encode: (data: Uint8Array) => import("../interfaces.js").KeyValue;
|
105
|
+
check: (data: any) => data is Uint8Array;
|
106
|
+
expected: string;
|
107
|
+
canAdd: (currentData: any, newData: any) => boolean;
|
108
|
+
};
|
109
|
+
};
|
110
|
+
export { globals, inputs, outputs };
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { InputTypes, OutputTypes } from '../typeFields.js';
|
2
|
+
import * as globalXpub from './global/globalXpub.js';
|
3
|
+
import * as unsignedTx from './global/unsignedTx.js';
|
4
|
+
import * as finalScriptSig from './input/finalScriptSig.js';
|
5
|
+
import * as finalScriptWitness from './input/finalScriptWitness.js';
|
6
|
+
import * as nonWitnessUtxo from './input/nonWitnessUtxo.js';
|
7
|
+
import * as partialSig from './input/partialSig.js';
|
8
|
+
import * as porCommitment from './input/porCommitment.js';
|
9
|
+
import * as sighashType from './input/sighashType.js';
|
10
|
+
import * as tapKeySig from './input/tapKeySig.js';
|
11
|
+
import * as tapLeafScript from './input/tapLeafScript.js';
|
12
|
+
import * as tapMerkleRoot from './input/tapMerkleRoot.js';
|
13
|
+
import * as tapScriptSig from './input/tapScriptSig.js';
|
14
|
+
import * as witnessUtxo from './input/witnessUtxo.js';
|
15
|
+
import * as opcatUtxo from './input/opcatUtxo.js';
|
16
|
+
import * as tapTree from './output/tapTree.js';
|
17
|
+
import * as bip32Derivation from './shared/bip32Derivation.js';
|
18
|
+
import * as checkPubkey from './shared/checkPubkey.js';
|
19
|
+
import * as redeemScript from './shared/redeemScript.js';
|
20
|
+
import * as tapBip32Derivation from './shared/tapBip32Derivation.js';
|
21
|
+
import * as tapInternalKey from './shared/tapInternalKey.js';
|
22
|
+
import * as witnessScript from './shared/witnessScript.js';
|
23
|
+
const globals = {
|
24
|
+
unsignedTx,
|
25
|
+
globalXpub,
|
26
|
+
// pass an Array of key bytes that require pubkey beside the key
|
27
|
+
checkPubkey: checkPubkey.makeChecker([]),
|
28
|
+
};
|
29
|
+
const inputs = {
|
30
|
+
nonWitnessUtxo,
|
31
|
+
partialSig,
|
32
|
+
sighashType,
|
33
|
+
finalScriptSig,
|
34
|
+
finalScriptWitness,
|
35
|
+
porCommitment,
|
36
|
+
witnessUtxo,
|
37
|
+
opcatUtxo,
|
38
|
+
bip32Derivation: bip32Derivation.makeConverter(InputTypes.BIP32_DERIVATION),
|
39
|
+
redeemScript: redeemScript.makeConverter(InputTypes.REDEEM_SCRIPT),
|
40
|
+
witnessScript: witnessScript.makeConverter(InputTypes.WITNESS_SCRIPT),
|
41
|
+
checkPubkey: checkPubkey.makeChecker([
|
42
|
+
InputTypes.PARTIAL_SIG,
|
43
|
+
InputTypes.BIP32_DERIVATION,
|
44
|
+
]),
|
45
|
+
tapKeySig,
|
46
|
+
tapScriptSig,
|
47
|
+
tapLeafScript,
|
48
|
+
tapBip32Derivation: tapBip32Derivation.makeConverter(InputTypes.TAP_BIP32_DERIVATION),
|
49
|
+
tapInternalKey: tapInternalKey.makeConverter(InputTypes.TAP_INTERNAL_KEY),
|
50
|
+
tapMerkleRoot,
|
51
|
+
};
|
52
|
+
const outputs = {
|
53
|
+
bip32Derivation: bip32Derivation.makeConverter(OutputTypes.BIP32_DERIVATION),
|
54
|
+
redeemScript: redeemScript.makeConverter(OutputTypes.REDEEM_SCRIPT),
|
55
|
+
witnessScript: witnessScript.makeConverter(OutputTypes.WITNESS_SCRIPT),
|
56
|
+
checkPubkey: checkPubkey.makeChecker([OutputTypes.BIP32_DERIVATION]),
|
57
|
+
tapBip32Derivation: tapBip32Derivation.makeConverter(OutputTypes.TAP_BIP32_DERIVATION),
|
58
|
+
tapTree,
|
59
|
+
tapInternalKey: tapInternalKey.makeConverter(OutputTypes.TAP_INTERNAL_KEY),
|
60
|
+
};
|
61
|
+
export { globals, inputs, outputs };
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { FinalScriptSig, KeyValue } from '../../interfaces';
|
2
|
+
export declare function decode(keyVal: KeyValue): FinalScriptSig;
|
3
|
+
export declare function encode(data: FinalScriptSig): KeyValue;
|
4
|
+
export declare const expected = "Uint8Array";
|
5
|
+
export declare function check(data: any): data is FinalScriptSig;
|
6
|
+
export declare function canAdd(currentData: any, newData: any): boolean;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { InputTypes } from '../../typeFields.js';
|
2
|
+
import * as tools from 'uint8array-tools';
|
3
|
+
export function decode(keyVal) {
|
4
|
+
if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTSIG) {
|
5
|
+
throw new Error('Decode Error: could not decode finalScriptSig with key 0x' +
|
6
|
+
tools.toHex(keyVal.key));
|
7
|
+
}
|
8
|
+
return keyVal.value;
|
9
|
+
}
|
10
|
+
export function encode(data) {
|
11
|
+
const key = new Uint8Array([InputTypes.FINAL_SCRIPTSIG]);
|
12
|
+
return {
|
13
|
+
key,
|
14
|
+
value: data,
|
15
|
+
};
|
16
|
+
}
|
17
|
+
export const expected = 'Uint8Array';
|
18
|
+
export function check(data) {
|
19
|
+
return data instanceof Uint8Array;
|
20
|
+
}
|
21
|
+
export function canAdd(currentData, newData) {
|
22
|
+
return !!currentData && !!newData && currentData.finalScriptSig === undefined;
|
23
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { FinalScriptWitness, KeyValue } from '../../interfaces';
|
2
|
+
export declare function decode(keyVal: KeyValue): FinalScriptWitness;
|
3
|
+
export declare function encode(data: FinalScriptWitness): KeyValue;
|
4
|
+
export declare const expected = "Uint8Array";
|
5
|
+
export declare function check(data: any): data is FinalScriptWitness;
|
6
|
+
export declare function canAdd(currentData: any, newData: any): boolean;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { InputTypes } from '../../typeFields.js';
|
2
|
+
import * as tools from 'uint8array-tools';
|
3
|
+
export function decode(keyVal) {
|
4
|
+
if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTWITNESS) {
|
5
|
+
throw new Error('Decode Error: could not decode finalScriptWitness with key 0x' +
|
6
|
+
tools.toHex(keyVal.key));
|
7
|
+
}
|
8
|
+
return keyVal.value;
|
9
|
+
}
|
10
|
+
export function encode(data) {
|
11
|
+
const key = new Uint8Array([InputTypes.FINAL_SCRIPTWITNESS]);
|
12
|
+
return {
|
13
|
+
key,
|
14
|
+
value: data,
|
15
|
+
};
|
16
|
+
}
|
17
|
+
export const expected = 'Uint8Array';
|
18
|
+
export function check(data) {
|
19
|
+
return data instanceof Uint8Array;
|
20
|
+
}
|
21
|
+
export function canAdd(currentData, newData) {
|
22
|
+
return (!!currentData && !!newData && currentData.finalScriptWitness === undefined);
|
23
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { KeyValue, NonWitnessUtxo } from '../../interfaces';
|
2
|
+
export declare function decode(keyVal: KeyValue): NonWitnessUtxo;
|
3
|
+
export declare function encode(data: NonWitnessUtxo): KeyValue;
|
4
|
+
export declare const expected = "Uint8Array";
|
5
|
+
export declare function check(data: any): data is NonWitnessUtxo;
|
6
|
+
export declare function canAdd(currentData: any, newData: any): boolean;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { InputTypes } from '../../typeFields.js';
|
2
|
+
import * as tools from 'uint8array-tools';
|
3
|
+
export function decode(keyVal) {
|
4
|
+
if (keyVal.key[0] !== InputTypes.NON_WITNESS_UTXO) {
|
5
|
+
throw new Error('Decode Error: could not decode nonWitnessUtxo with key 0x' +
|
6
|
+
tools.toHex(keyVal.key));
|
7
|
+
}
|
8
|
+
return keyVal.value;
|
9
|
+
}
|
10
|
+
export function encode(data) {
|
11
|
+
return {
|
12
|
+
key: new Uint8Array([InputTypes.NON_WITNESS_UTXO]),
|
13
|
+
value: data,
|
14
|
+
};
|
15
|
+
}
|
16
|
+
export const expected = 'Uint8Array';
|
17
|
+
export function check(data) {
|
18
|
+
return data instanceof Uint8Array;
|
19
|
+
}
|
20
|
+
export function canAdd(currentData, newData) {
|
21
|
+
return !!currentData && !!newData && currentData.nonWitnessUtxo === undefined;
|
22
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { KeyValue, OpcatUtxo } from '../../interfaces';
|
2
|
+
export declare function decode(keyVal: KeyValue): OpcatUtxo;
|
3
|
+
export declare function encode(data: OpcatUtxo): KeyValue;
|
4
|
+
export declare const expected = "{ script: Uint8Array; data: Uint8Array; value: bigint; }";
|
5
|
+
export declare function check(data: any): data is OpcatUtxo;
|
6
|
+
export declare function canAdd(currentData: any, newData: any): boolean;
|