Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/cjs/lib/converter/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,22 @@ const tapLeafScript = __importStar(require('./input/tapLeafScript.cjs'));
const tapMerkleRoot = __importStar(require('./input/tapMerkleRoot.cjs'));
const tapScriptSig = __importStar(require('./input/tapScriptSig.cjs'));
const witnessUtxo = __importStar(require('./input/witnessUtxo.cjs'));
const silentPaymentOutputLabel = __importStar(
require('./output/silentPaymentOutputLabel.cjs'),
);
const silentPaymentV0Info = __importStar(
require('./output/silentPaymentV0Info.cjs'),
);
const tapTree = __importStar(require('./output/tapTree.cjs'));
const bip32Derivation = __importStar(require('./shared/bip32Derivation.cjs'));
const checkPubkey = __importStar(require('./shared/checkPubkey.cjs'));
const redeemScript = __importStar(require('./shared/redeemScript.cjs'));
const silentPaymentDleq = __importStar(
require('./shared/silentPaymentDleq.cjs'),
);
const silentPaymentEcdhShare = __importStar(
require('./shared/silentPaymentEcdhShare.cjs'),
);
const tapBip32Derivation = __importStar(
require('./shared/tapBip32Derivation.cjs'),
);
Expand All @@ -41,6 +53,12 @@ const globals = {
globalXpub,
// pass an Array of key bytes that require pubkey beside the key
checkPubkey: checkPubkey.makeChecker([]),
silentPaymentEcdhShare: silentPaymentEcdhShare.makeConverter(
typeFields_js_1.GlobalTypes.GLOBAL_SP_ECDH_SHARE,
),
silentPaymentDleq: silentPaymentDleq.makeConverter(
typeFields_js_1.GlobalTypes.GLOBAL_SP_DLEQ,
),
};
exports.globals = globals;
const inputs = {
Expand Down Expand Up @@ -74,6 +92,12 @@ const inputs = {
typeFields_js_1.InputTypes.TAP_INTERNAL_KEY,
),
tapMerkleRoot,
silentPaymentEcdhShare: silentPaymentEcdhShare.makeConverter(
typeFields_js_1.InputTypes.SP_ECDH_SHARE,
),
silentPaymentDleq: silentPaymentDleq.makeConverter(
typeFields_js_1.InputTypes.SP_DLEQ,
),
};
exports.inputs = inputs;
const outputs = {
Expand All @@ -96,5 +120,7 @@ const outputs = {
tapInternalKey: tapInternalKey.makeConverter(
typeFields_js_1.OutputTypes.TAP_INTERNAL_KEY,
),
silentPaymentV0Info,
silentPaymentOutputLabel,
};
exports.outputs = outputs;
48 changes: 48 additions & 0 deletions src/cjs/lib/converter/output/silentPaymentOutputLabel.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';
var __importStar =
(this && this.__importStar) ||
function(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result['default'] = mod;
return result;
};
Object.defineProperty(exports, '__esModule', { value: true });
const typeFields_js_1 = require('../../typeFields.cjs');
const tools = __importStar(require('uint8array-tools'));
function decode(keyVal) {
if (keyVal.key[0] !== typeFields_js_1.OutputTypes.SP_V0_LABEL) {
throw new Error(
'Decode Error: could not decode silentPaymentOutputLabel with key 0x' +
tools.toHex(keyVal.key),
);
}
return Number(tools.readUInt32(keyVal.value, 0, 'LE'));
}
exports.decode = decode;
function encode(data) {
const key = Uint8Array.from([typeFields_js_1.OutputTypes.SP_V0_LABEL]);
const value = new Uint8Array(4);
tools.writeUInt32(value, 0, data, 'LE');
return {
key,
value,
};
}
exports.encode = encode;
exports.expected = 'number';
function check(data) {
return typeof data === 'number';
}
exports.check = check;
function canAdd(currentData, newData) {
return (
!!currentData &&
!!newData &&
currentData.silentPaymentOutputLabel === undefined
);
}
exports.canAdd = canAdd;
65 changes: 65 additions & 0 deletions src/cjs/lib/converter/output/silentPaymentV0Info.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict';
var __importStar =
(this && this.__importStar) ||
function(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result['default'] = mod;
return result;
};
Object.defineProperty(exports, '__esModule', { value: true });
const typeFields_js_1 = require('../../typeFields.cjs');
const tools = __importStar(require('uint8array-tools'));
const isValidPubKey = pubkey =>
pubkey.length === 33 && [2, 3].includes(pubkey[0]);
function decode(keyVal) {
if (keyVal.key[0] !== typeFields_js_1.OutputTypes.SP_V0_INFO) {
throw new Error(
'Decode Error: could not decode silentPaymentV0Info with key 0x' +
tools.toHex(keyVal.key),
);
}
if (keyVal.value.length !== 66) {
throw new Error('Decode Error: SP_V0_INFO is not proper length');
}
const scanKey = keyVal.value.slice(0, 33);
if (!isValidPubKey(scanKey)) {
throw new Error('Decode Error: SP_V0_INFO scanKey is not a valid pubkey');
}
const spendKey = keyVal.value.slice(33);
if (!isValidPubKey(spendKey)) {
throw new Error('Decode Error: SP_V0_INFO spendKey is not a valid pubkey');
}
return {
scanKey,
spendKey,
};
}
exports.decode = decode;
function encode(data) {
const key = new Uint8Array([typeFields_js_1.OutputTypes.SP_V0_INFO]);
return {
key,
value: Uint8Array.from([...data.scanKey, ...data.spendKey]),
};
}
exports.encode = encode;
exports.expected = '{ scanKey: Uint8Array; spendKey: Uint8Array; }';
function check(data) {
return (
data.scanKey instanceof Uint8Array &&
data.spendKey instanceof Uint8Array &&
isValidPubKey(data.scanKey) &&
isValidPubKey(data.spendKey)
);
}
exports.check = check;
function canAdd(currentData, newData) {
return (
!!currentData && !!newData && currentData.silentPaymentV0Info === undefined
);
}
exports.canAdd = canAdd;
74 changes: 74 additions & 0 deletions src/cjs/lib/converter/shared/silentPaymentDleq.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use strict';
var __importStar =
(this && this.__importStar) ||
function(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result['default'] = mod;
return result;
};
Object.defineProperty(exports, '__esModule', { value: true });
const tools = __importStar(require('uint8array-tools'));
const isValidPubKey = pubkey =>
pubkey.length === 33 && [2, 3].includes(pubkey[0]);
function makeConverter(TYPE_BYTE, isValidPubkey = isValidPubKey) {
function decode(keyVal) {
if (keyVal.key[0] !== TYPE_BYTE) {
throw new Error(
'Decode Error: could not decode silentPaymentDleq with key 0x' +
tools.toHex(keyVal.key),
);
}
const scanKey = keyVal.key.slice(1);
if (!isValidPubkey(scanKey)) {
throw new Error(
'Decode Error: silentPaymentDleq has invalid scanKey in key 0x' +
tools.toHex(keyVal.key),
);
}
if (keyVal.value.length !== 64) {
throw new Error('Decode Error: silentPaymentDleq not a 64-byte proof');
}
return {
scanKey,
proof: keyVal.value,
};
}
function encode(data) {
const head = Uint8Array.from([TYPE_BYTE]);
const key = tools.concat([head, data.scanKey]);
return {
key,
value: data.proof,
};
}
const expected = '{ scanKey: Uint8Array; proof: Uint8Array; }';
function check(data) {
return (
data.scanKey instanceof Uint8Array &&
data.proof instanceof Uint8Array &&
isValidPubkey(data.scanKey) &&
data.proof.length === 64
);
}
function canAddToArray(array, item, dupeSet) {
const dupeString = tools.toHex(item.scanKey);
if (dupeSet.has(dupeString)) return false;
dupeSet.add(dupeString);
return (
array.filter(v => tools.compare(v.scanKey, item.scanKey) === 0).length ===
0
);
}
return {
decode,
encode,
check,
expected,
canAddToArray,
};
}
exports.makeConverter = makeConverter;
77 changes: 77 additions & 0 deletions src/cjs/lib/converter/shared/silentPaymentEcdhShare.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict';
var __importStar =
(this && this.__importStar) ||
function(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result['default'] = mod;
return result;
};
Object.defineProperty(exports, '__esModule', { value: true });
const tools = __importStar(require('uint8array-tools'));
const isValidDERKey = pubkey =>
(pubkey.length === 33 && [2, 3].includes(pubkey[0])) ||
(pubkey.length === 65 && 4 === pubkey[0]);
function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) {
function decode(keyVal) {
if (keyVal.key[0] !== TYPE_BYTE) {
throw new Error(
'Decode Error: could not decode silentPaymentEcdhShare with key 0x' +
tools.toHex(keyVal.key),
);
}
const scanKey = keyVal.key.slice(1);
if (!isValidPubkey(scanKey)) {
throw new Error(
'Decode Error: silentPaymentEcdhShare has invalid scanKey in key 0x' +
tools.toHex(keyVal.key),
);
}
if (!isValidPubkey(keyVal.value)) {
throw new Error(
'Decode Error: silentPaymentEcdhShare not a 33-byte pubkey',
);
}
return {
scanKey,
share: keyVal.value,
};
}
function encode(data) {
const head = Uint8Array.from([TYPE_BYTE]);
const key = tools.concat([head, data.scanKey]);
return {
key,
value: data.share,
};
}
const expected = '{ scanKey: Uint8Array; share: Uint8Array; }';
function check(data) {
return (
data.scanKey instanceof Uint8Array &&
data.share instanceof Uint8Array &&
isValidPubkey(data.scanKey) &&
isValidPubkey(data.share)
);
}
function canAddToArray(array, item, dupeSet) {
const dupeString = tools.toHex(item.scanKey);
if (dupeSet.has(dupeString)) return false;
dupeSet.add(dupeString);
return (
array.filter(v => tools.compare(v.scanKey, item.scanKey) === 0).length ===
0
);
}
return {
decode,
encode,
check,
expected,
canAddToArray,
};
}
exports.makeConverter = makeConverter;
52 changes: 52 additions & 0 deletions src/cjs/lib/parser/fromBuffer.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ function psbtFromKeyVals(
}
globalMap.globalXpub.push(convert.globals.globalXpub.decode(keyVal));
break;
case typeFields_js_1.GlobalTypes.GLOBAL_SP_ECDH_SHARE:
if (globalMap.silentPaymentEcdhShare === undefined) {
globalMap.silentPaymentEcdhShare = [];
}
globalMap.silentPaymentEcdhShare.push(
convert.globals.silentPaymentEcdhShare.decode(keyVal),
);
break;
case typeFields_js_1.GlobalTypes.GLOBAL_SP_DLEQ:
if (globalMap.silentPaymentDleq === undefined) {
globalMap.silentPaymentDleq = [];
}
globalMap.silentPaymentDleq.push(
convert.globals.silentPaymentDleq.decode(keyVal),
);
break;
default:
// This will allow inclusion during serialization.
if (!globalMap.unknownKeyVals) globalMap.unknownKeyVals = [];
Expand Down Expand Up @@ -330,6 +346,22 @@ function psbtFromKeyVals(
);
input.tapMerkleRoot = convert.inputs.tapMerkleRoot.decode(keyVal);
break;
case typeFields_js_1.InputTypes.SP_ECDH_SHARE:
if (input.silentPaymentEcdhShare === undefined) {
input.silentPaymentEcdhShare = [];
}
input.silentPaymentEcdhShare.push(
convert.inputs.silentPaymentEcdhShare.decode(keyVal),
);
break;
case typeFields_js_1.InputTypes.SP_DLEQ:
if (input.silentPaymentDleq === undefined) {
input.silentPaymentDleq = [];
}
input.silentPaymentDleq.push(
convert.inputs.silentPaymentDleq.decode(keyVal),
);
break;
default:
// This will allow inclusion during serialization.
if (!input.unknownKeyVals) input.unknownKeyVals = [];
Expand Down Expand Up @@ -397,6 +429,26 @@ function psbtFromKeyVals(
convert.outputs.tapBip32Derivation.decode(keyVal),
);
break;
case typeFields_js_1.OutputTypes.SP_V0_INFO:
checkKeyBuffer(
'output',
keyVal.key,
typeFields_js_1.OutputTypes.SP_V0_INFO,
);
output.silentPaymentV0Info = convert.outputs.silentPaymentV0Info.decode(
keyVal,
);
break;
case typeFields_js_1.OutputTypes.SP_V0_LABEL:
checkKeyBuffer(
'output',
keyVal.key,
typeFields_js_1.OutputTypes.SP_V0_LABEL,
);
output.silentPaymentOutputLabel = convert.outputs.silentPaymentOutputLabel.decode(
keyVal,
);
break;
default:
if (!output.unknownKeyVals) output.unknownKeyVals = [];
output.unknownKeyVals.push(keyVal);
Expand Down
Loading