Skip to content

Commit e40a0e2

Browse files
chore(utxo-lib): tests and helper functions + deprecated old methods
TICKET: BTC-2183 chore(utxo-lib): moved tests and removed console logs TICKET: BTC-2183 chore(utxo-lib): spelling error for delete test TICKET: BTC-2183
1 parent 959bf98 commit e40a0e2

File tree

4 files changed

+261
-80
lines changed

4 files changed

+261
-80
lines changed

modules/utxo-lib/src/bitgo/PsbtUtil.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { decodeProprietaryKey, ProprietaryKey } from 'bip174/src/lib/proprietaryKeyVal';
2-
import { PsbtInput, PsbtOutput, KeyValue } from 'bip174/src/lib/interfaces';
1+
import { ProprietaryKey } from 'bip174/src/lib/proprietaryKeyVal';
2+
import { PsbtInput, PsbtOutput } from 'bip174/src/lib/interfaces';
33
import { Psbt } from 'bitcoinjs-lib/src/psbt';
4+
import { getProprietaryKeyValuesFromUnknownKeyValues } from './psbt/ProprietaryKeyValUtils';
45

56
/**
67
* bitgo proprietary key identifier
@@ -38,26 +39,6 @@ export interface ProprietaryKeySearch {
3839
identifierEncoding?: BufferEncoding;
3940
}
4041

41-
function getProprietaryKeyValuesFromUnknownKeyValues(
42-
unknownKeyVals: KeyValue[],
43-
keySearch?: ProprietaryKeySearch
44-
): ProprietaryKeyValue[] {
45-
if (keySearch && keySearch.subtype === undefined && Buffer.isBuffer(keySearch.keydata)) {
46-
throw new Error('invalid proprietary key search filter combination. subtype is required');
47-
}
48-
const keyVals = unknownKeyVals.map(({ key, value }, i) => {
49-
return { key: decodeProprietaryKey(key), value };
50-
});
51-
return keyVals.filter((keyVal) => {
52-
return (
53-
keySearch === undefined ||
54-
(keySearch.identifier === keyVal.key.identifier &&
55-
(keySearch.subtype === undefined ||
56-
(keySearch.subtype === keyVal.key.subtype &&
57-
(!Buffer.isBuffer(keySearch.keydata) || keySearch.keydata.equals(keyVal.key.keydata)))))
58-
);
59-
});
60-
}
6142
/**
6243
* Search any data from psbt proprietary key value against keydata.
6344
* Default identifierEncoding is utf-8 for identifier.
@@ -71,6 +52,7 @@ export function getPsbtInputProprietaryKeyVals(
7152
}
7253
return getProprietaryKeyValuesFromUnknownKeyValues(input.unknownKeyVals, keySearch);
7354
}
55+
7456
export function getPsbtOutputProprietaryKeyVals(
7557
output: PsbtOutput,
7658
keySearch?: ProprietaryKeySearch
@@ -80,6 +62,7 @@ export function getPsbtOutputProprietaryKeyVals(
8062
}
8163
return getProprietaryKeyValuesFromUnknownKeyValues(output.unknownKeyVals, keySearch);
8264
}
65+
8366
/**
8467
* @return partialSig/tapScriptSig/MUSIG2_PARTIAL_SIG count iff input is not finalized
8568
*/

modules/utxo-lib/src/bitgo/UtxoPsbt.ts

Lines changed: 94 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ import {
6363
ProprietaryKeyValue,
6464
PSBT_PROPRIETARY_IDENTIFIER,
6565
} from './PsbtUtil';
66+
import {
67+
deleteProprietaryKeyValuesFromUnknownKeyValues,
68+
UnknownKeyValsType,
69+
updateProprietaryKeyValuesToUnknownKeyValues,
70+
} from './psbt/ProprietaryKeyValUtils';
6671

6772
type SignatureParams = {
6873
/** When true, and add the second (last) nonce and signature for a taproot key
@@ -1077,6 +1082,8 @@ export class UtxoPsbt<Tx extends UtxoTransaction<bigint> = UtxoTransaction<bigin
10771082
}
10781083

10791084
/**
1085+
* @deprecated Please use the new method addProprietaryKeyVals(type, index, keyValueData)
1086+
*
10801087
* Adds proprietary key value pair to PSBT input.
10811088
* Default identifierEncoding is utf-8 for identifier.
10821089
*/
@@ -1088,6 +1095,8 @@ export class UtxoPsbt<Tx extends UtxoTransaction<bigint> = UtxoTransaction<bigin
10881095
}
10891096

10901097
/**
1098+
* @deprecated Please use the new method addOrUpdateProprietaryKeyVal(type, index, keyValueData)
1099+
*
10911100
* Adds or updates (if exists) proprietary key value pair to PSBT input.
10921101
* Default identifierEncoding is utf-8 for identifier.
10931102
*/
@@ -1110,6 +1119,9 @@ export class UtxoPsbt<Tx extends UtxoTransaction<bigint> = UtxoTransaction<bigin
11101119
}
11111120

11121121
/**
1122+
* @deprecated Please use getProprietaryKeyValues(type, index, keySearch). The new method
1123+
* allows for the retrieval of either input or output proprietary key values.
1124+
*
11131125
* To search any data from proprietary key value against keydata in the inputs.
11141126
* Default identifierEncoding is utf-8 for identifier.
11151127
*/
@@ -1119,6 +1131,9 @@ export class UtxoPsbt<Tx extends UtxoTransaction<bigint> = UtxoTransaction<bigin
11191131
}
11201132

11211133
/**
1134+
* @deprecated Please use deleteProprietaryKeyValues(type, index, keysToDelete?). The new method
1135+
* allows for the deletion of either input or output proprietary key values.
1136+
*
11221137
* To delete any data from proprietary key value in PSBT input.
11231138
* Default identifierEncoding is utf-8 for identifier.
11241139
*/
@@ -1143,73 +1158,94 @@ export class UtxoPsbt<Tx extends UtxoTransaction<bigint> = UtxoTransaction<bigin
11431158
return this;
11441159
}
11451160

1146-
/**
1147-
* Adds a proprietary key value pair to PSBT output
1148-
* Default identifier is utf-8 for identifier
1149-
*/
1150-
addProprietaryKeyValToOutput(outputIndex: number, keyValueData: ProprietaryKeyValue): this {
1151-
const output = checkForOutput(this.data.outputs, outputIndex);
1152-
assert(output.unknownKeyVals);
1153-
return this.addUnknownKeyValToOutput(outputIndex, {
1154-
key: encodeProprietaryKey(keyValueData.key),
1155-
value: keyValueData.value,
1156-
});
1157-
}
1158-
1159-
/**
1160-
* To search any data from proprietary key value against keydata in the PSBT outputs.
1161-
* Default identifierEncoding is utf-8 for identifier.
1162-
*/
1163-
getOutputProprietaryKeyVals(outputIndex: number, keySearch?: ProprietaryKeySearch): ProprietaryKeyValue[] {
1164-
const output = checkForOutput(this.data.outputs, outputIndex);
1165-
return getPsbtOutputProprietaryKeyVals(output, keySearch);
1161+
addProprietaryKeyValues(type: UnknownKeyValsType, index: number, keyValueData: ProprietaryKeyValue): this {
1162+
switch (type) {
1163+
case 'input':
1164+
const input = checkForInput(this.data.inputs, index);
1165+
assert(input);
1166+
return this.addUnknownKeyValToInput(index, {
1167+
key: encodeProprietaryKey(keyValueData.key),
1168+
value: keyValueData.value,
1169+
});
1170+
case 'output':
1171+
const output = checkForOutput(this.data.outputs, index);
1172+
assert(output);
1173+
return this.addUnknownKeyValToOutput(index, {
1174+
key: encodeProprietaryKey(keyValueData.key),
1175+
value: keyValueData.value,
1176+
});
1177+
default:
1178+
throw new Error('There is no such type, something went wrong.');
1179+
}
11661180
}
11671181

1168-
/**
1169-
* Adds or updates (if exists) proprietary key value pair to PSBT output.
1170-
* Default identifierEncoding is utf-8 for identifier.
1171-
*/
1172-
addOrUpdateProprietaryKeyValsToOutput(outputIndex: number, keyValueData: ProprietaryKeyValue): this {
1173-
const output = checkForOutput(this.data.outputs, outputIndex);
1182+
addOrUpdateProprietaryKeyValues(type: UnknownKeyValsType, index: number, keyValueData: ProprietaryKeyValue): this {
11741183
const key = encodeProprietaryKey(keyValueData.key);
11751184
const { value } = keyValueData;
1176-
if (output.unknownKeyVals?.length) {
1177-
const ukvIndex = output.unknownKeyVals.findIndex((ukv) => ukv.key.equals(key));
1178-
if (ukvIndex > -1) {
1179-
output.unknownKeyVals[ukvIndex] = { key, value };
1180-
return this;
1181-
}
1185+
switch (type) {
1186+
case 'output':
1187+
const output = checkForOutput(this.data.outputs, index);
1188+
assert(output);
1189+
if (output.unknownKeyVals?.length) {
1190+
updateProprietaryKeyValuesToUnknownKeyValues(keyValueData, output.unknownKeyVals);
1191+
return this;
1192+
}
1193+
return this.addUnknownKeyValToOutput(index, {
1194+
key,
1195+
value,
1196+
});
1197+
case 'input':
1198+
const input = checkForInput(this.data.inputs, index);
1199+
assert(input);
1200+
if (input.unknownKeyVals?.length) {
1201+
updateProprietaryKeyValuesToUnknownKeyValues(keyValueData, input.unknownKeyVals);
1202+
return this;
1203+
}
1204+
return this.addUnknownKeyValToInput(index, {
1205+
key,
1206+
value,
1207+
});
1208+
default:
1209+
throw new Error('There is no such type. Something went wrong.');
11821210
}
1183-
this.addUnknownKeyValToOutput(outputIndex, {
1184-
key,
1185-
value,
1186-
});
1187-
return this;
11881211
}
11891212

1190-
/**
1191-
* To delete any data from proprietary key value in PSBT output.
1192-
* Default identifierEncoding is utf-8 for identifier.
1193-
*/
1194-
deleteProprietaryKeyValsInOutput(outputIndex: number, keysToDelete?: ProprietaryKeySearch): this {
1195-
const output = checkForOutput(this.data.outputs, outputIndex);
1196-
if (!output.unknownKeyVals?.length) {
1197-
return this;
1213+
getProprietaryKeyValues(
1214+
type: UnknownKeyValsType,
1215+
index: number,
1216+
keySearch?: ProprietaryKeySearch
1217+
): ProprietaryKeyValue[] {
1218+
switch (type) {
1219+
case 'input':
1220+
const input = checkForInput(this.data.inputs, index);
1221+
return getPsbtInputProprietaryKeyVals(input, keySearch);
1222+
case 'output':
1223+
const output = checkForOutput(this.data.outputs, index);
1224+
return getPsbtOutputProprietaryKeyVals(output, keySearch);
1225+
default:
1226+
throw new Error('There is no such type. Something went wrong.');
11981227
}
1199-
if (keysToDelete && keysToDelete.subtype === undefined && Buffer.isBuffer(keysToDelete.keydata)) {
1200-
throw new Error('invalid proprietary key search filter combination. subtype is required');
1228+
}
1229+
1230+
deleteProprietaryKeyValues(type: UnknownKeyValsType, index: number, keysToDelete?: ProprietaryKeySearch): this {
1231+
switch (type) {
1232+
case 'input':
1233+
const input = checkForInput(this.data.inputs, index);
1234+
if (!input.unknownKeyVals?.length) {
1235+
return this;
1236+
}
1237+
input.unknownKeyVals = deleteProprietaryKeyValuesFromUnknownKeyValues(input.unknownKeyVals, keysToDelete);
1238+
return this;
1239+
case 'output':
1240+
const output = checkForOutput(this.data.outputs, index);
1241+
if (!output.unknownKeyVals?.length) {
1242+
return this;
1243+
}
1244+
output.unknownKeyVals = deleteProprietaryKeyValuesFromUnknownKeyValues(output.unknownKeyVals, keysToDelete);
1245+
return this;
1246+
default:
1247+
throw new Error('There is no such type. Something went wrong.');
12011248
}
1202-
output.unknownKeyVals = output.unknownKeyVals.filter((keyValue, i) => {
1203-
const key = decodeProprietaryKey(keyValue.key);
1204-
return !(
1205-
keysToDelete === undefined ||
1206-
(keysToDelete.identifier === key.identifier &&
1207-
(keysToDelete.subtype === undefined ||
1208-
(keysToDelete.subtype === key.subtype &&
1209-
(!Buffer.isBuffer(keysToDelete.keydata) || keysToDelete.keydata.equals(key.keydata)))))
1210-
);
1211-
});
1212-
return this;
12131249
}
12141250

12151251
private createMusig2NonceForInput(
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { KeyValue } from 'bip174/src/lib/interfaces';
2+
import { decodeProprietaryKey, encodeProprietaryKey } from 'bip174/src/lib/proprietaryKeyVal';
3+
import { ProprietaryKeySearch, ProprietaryKeyValue } from '../PsbtUtil';
4+
5+
export type UnknownKeyValsType = 'output' | 'input';
6+
7+
export function getProprietaryKeyValuesFromUnknownKeyValues(
8+
unknownKeyVals: KeyValue[],
9+
keySearch?: ProprietaryKeySearch
10+
): ProprietaryKeyValue[] {
11+
if (keySearch && keySearch.subtype === undefined && Buffer.isBuffer(keySearch.keydata)) {
12+
throw new Error('invalid proprietary key search filter combination. subtype is required');
13+
}
14+
const keyVals = unknownKeyVals.map(({ key, value }, i) => {
15+
return { key: decodeProprietaryKey(key), value };
16+
});
17+
return keyVals.filter((keyVal) => {
18+
return (
19+
keySearch === undefined ||
20+
(keySearch.identifier === keyVal.key.identifier &&
21+
(keySearch.subtype === undefined ||
22+
(keySearch.subtype === keyVal.key.subtype &&
23+
(!Buffer.isBuffer(keySearch.keydata) || keySearch.keydata.equals(keyVal.key.keydata)))))
24+
);
25+
});
26+
}
27+
28+
export function deleteProprietaryKeyValuesFromUnknownKeyValues(
29+
unknownKeyVals: KeyValue[],
30+
keysToDelete?: ProprietaryKeySearch
31+
): KeyValue[] {
32+
if (keysToDelete && keysToDelete.subtype === undefined && Buffer.isBuffer(keysToDelete.keydata)) {
33+
throw new Error('invalid proprietary key search filter combination. subtype is required');
34+
}
35+
return unknownKeyVals.filter((keyValue, i) => {
36+
const key = decodeProprietaryKey(keyValue.key);
37+
return !(
38+
keysToDelete === undefined ||
39+
(keysToDelete.identifier === key.identifier &&
40+
(keysToDelete.subtype === undefined ||
41+
(keysToDelete.subtype === key.subtype &&
42+
(!Buffer.isBuffer(keysToDelete.keydata) || keysToDelete.keydata.equals(key.keydata)))))
43+
);
44+
});
45+
}
46+
47+
export function updateProprietaryKeyValuesToUnknownKeyValues(
48+
keyValueData: ProprietaryKeyValue,
49+
unknownKeyVals: KeyValue[]
50+
): void {
51+
const key = encodeProprietaryKey(keyValueData.key);
52+
const { value } = keyValueData;
53+
const ukvIndex = unknownKeyVals.findIndex((ukv) => ukv.key.equals(key));
54+
if (ukvIndex > -1) {
55+
unknownKeyVals[ukvIndex] = { key, value };
56+
}
57+
}

0 commit comments

Comments
 (0)