@caravan/psbt 1.1.0 → 1.2.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @caravan/psbt@1.1.0 build
2
+ > @caravan/psbt@1.2.0 build
3
3
  > tsup src/index.ts --format cjs,esm --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,11 +9,11 @@
9
9
  CLI Target: esnext
10
10
  CJS Build start
11
11
  ESM Build start
12
- CJS dist/index.js 36.78 KB
13
- CJS ⚡️ Build success in 59ms
14
- ESM dist/index.mjs 35.12 KB
15
- ESM ⚡️ Build success in 60ms
12
+ ESM dist/index.mjs 37.44 KB
13
+ ESM ⚡️ Build success in 58ms
14
+ CJS dist/index.js 39.13 KB
15
+ CJS ⚡️ Build success in 58ms
16
16
  DTS Build start
17
- DTS ⚡️ Build success in 2379ms
18
- DTS dist/index.d.ts 11.83 KB
19
- DTS dist/index.d.mts 11.83 KB
17
+ DTS ⚡️ Build success in 2355ms
18
+ DTS dist/index.d.ts 13.38 KB
19
+ DTS dist/index.d.mts 13.38 KB
@@ -1,5 +1,5 @@
1
1
 
2
- > @caravan/psbt@1.1.0 lint
2
+ > @caravan/psbt@1.2.0 lint
3
3
  > eslint src
4
4
 
5
5
 
@@ -23,13 +23,20 @@
23
23
  1169:53 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
24
24
  1231:45 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
25
25
  1231:56 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
26
+ 1450:19 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
27
+ 1456:21 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
28
+ 1457:21 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
29
+ 1467:23 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
30
+ 1479:29 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
31
+ 1491:24 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
32
+ 1503:30 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
26
33
 
27
34
  /home/runner/work/caravan/caravan/packages/caravan-psbt/src/psbtv2/psbtv2.ts
28
- 132:9 warning 'modifiable' is never reassigned. Use 'const' instead prefer-const
29
- 676:9 warning 'heights' is never reassigned. Use 'const' instead prefer-const
30
- 677:9 warning 'times' is never reassigned. Use 'const' instead prefer-const
31
- 1189:21 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
32
- 1211:22 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
35
+ 133:9 warning 'modifiable' is never reassigned. Use 'const' instead prefer-const
36
+ 677:9 warning 'heights' is never reassigned. Use 'const' instead prefer-const
37
+ 678:9 warning 'times' is never reassigned. Use 'const' instead prefer-const
38
+ 1256:21 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
39
+ 1278:22 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
33
40
 
34
41
  /home/runner/work/caravan/caravan/packages/caravan-psbt/src/psbtv2/types.ts
35
42
  32:3 warning Duplicate enum member value 01 @typescript-eslint/no-duplicate-enum-values
@@ -49,6 +56,6 @@
49
56
  65:3 warning Duplicate enum member value 07 @typescript-eslint/no-duplicate-enum-values
50
57
  66:3 warning Duplicate enum member value fc @typescript-eslint/no-duplicate-enum-values
51
58
 
52
- 38 problems (0 errors, 38 warnings)
59
+ 45 problems (0 errors, 45 warnings)
53
60
  0 errors and 7 warnings potentially fixable with the `--fix` option.
54
61
 
@@ -1,5 +1,5 @@
1
1
 
2
- > @caravan/psbt@1.1.0 test
2
+ > @caravan/psbt@1.2.0 test
3
3
  > jest src
4
4
 
5
5
  PASS src/psbt.test.ts
@@ -9,16 +9,16 @@ PASS src/psbtv2/psbtv2.test.ts
9
9
  console.warn
10
10
  Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!
11
11
 
12
- 805 | );
13
- 806 | }
14
- > 807 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
12
+ 806 | );
13
+ 807 | }
14
+ > 808 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
15
15
  | ^
16
- 808 | const bw = new BufferWriter();
17
- 809 | bw.writeI32(1);
18
- 810 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
16
+ 809 | const bw = new BufferWriter();
17
+ 810 | bw.writeI32(1);
18
+ 811 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
19
19
 
20
- at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:807:13)
21
- at Function.FromV0 (src/psbtv2/psbtv2.ts:1173:14)
20
+ at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:808:13)
21
+ at Function.FromV0 (src/psbtv2/psbtv2.ts:1240:14)
22
22
  at t (src/psbtv2/psbtv2.test.ts:1091:34)
23
23
  at Object.<anonymous> (../../node_modules/expect/build/toThrowMatchers.js:74:11)
24
24
  at Object.throwingMatcher [as toThrow] (../../node_modules/expect/build/index.js:320:21)
@@ -27,16 +27,16 @@ PASS src/psbtv2/psbtv2.test.ts
27
27
  console.warn
28
28
  Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!
29
29
 
30
- 805 | );
31
- 806 | }
32
- > 807 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
30
+ 806 | );
31
+ 807 | }
32
+ > 808 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
33
33
  | ^
34
- 808 | const bw = new BufferWriter();
35
- 809 | bw.writeI32(1);
36
- 810 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
34
+ 809 | const bw = new BufferWriter();
35
+ 810 | bw.writeI32(1);
36
+ 811 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
37
37
 
38
- at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:807:13)
39
- at Function.FromV0 (src/psbtv2/psbtv2.ts:1173:14)
38
+ at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:808:13)
39
+ at Function.FromV0 (src/psbtv2/psbtv2.ts:1240:14)
40
40
  at t (src/psbtv2/psbtv2.test.ts:1091:34)
41
41
  at Object.<anonymous> (../../node_modules/expect/build/toThrowMatchers.js:74:11)
42
42
  at Object.throwingMatcher [as toThrow] (../../node_modules/expect/build/index.js:320:21)
@@ -45,16 +45,16 @@ PASS src/psbtv2/psbtv2.test.ts
45
45
  console.warn
46
46
  Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!
47
47
 
48
- 805 | );
49
- 806 | }
50
- > 807 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
48
+ 806 | );
49
+ 807 | }
50
+ > 808 | console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
51
51
  | ^
52
- 808 | const bw = new BufferWriter();
53
- 809 | bw.writeI32(1);
54
- 810 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
52
+ 809 | const bw = new BufferWriter();
53
+ 810 | bw.writeI32(1);
54
+ 811 | this.globalMap.set(KeyType.PSBT_GLOBAL_TX_VERSION, bw.render());
55
55
 
56
- at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:807:13)
57
- at Function.FromV0 (src/psbtv2/psbtv2.ts:1173:14)
56
+ at PsbtV2.dangerouslySetGlobalTxVersion1 (src/psbtv2/psbtv2.ts:808:13)
57
+ at Function.FromV0 (src/psbtv2/psbtv2.ts:1240:14)
58
58
  at src/psbtv2/psbtv2.test.ts:1103:25
59
59
 
60
60
  console.error
@@ -63,7 +63,7 @@ PASS src/psbtv2/psbtv2.test.ts
63
63
  at /home/runner/work/caravan/caravan/node_modules/jest-mock/build/index.js:397:39
64
64
  at PsbtV2.<anonymous> (/home/runner/work/caravan/caravan/node_modules/jest-mock/build/index.js:404:13)
65
65
  at PsbtV2.mockConstructor [as handleSighashType] (/home/runner/work/caravan/caravan/node_modules/jest-mock/build/index.js:148:19)
66
- at PsbtV2.addPartialSig (/home/runner/work/caravan/caravan/packages/caravan-psbt/src/psbtv2/psbtv2.ts:1077:12)
66
+ at PsbtV2.addPartialSig (/home/runner/work/caravan/caravan/packages/caravan-psbt/src/psbtv2/psbtv2.ts:1078:12)
67
67
  at Object.<anonymous> (/home/runner/work/caravan/caravan/packages/caravan-psbt/src/psbtv2/psbtv2.test.ts:1198:10)
68
68
  at Promise.then.completed (/home/runner/work/caravan/caravan/node_modules/jest-circus/build/utils.js:298:28)
69
69
  at new Promise (<anonymous>)
@@ -80,20 +80,20 @@ PASS src/psbtv2/psbtv2.test.ts
80
80
  at runTest (/home/runner/work/caravan/caravan/node_modules/jest-runner/build/runTest.js:444:34)
81
81
  at Object.worker (/home/runner/work/caravan/caravan/node_modules/jest-runner/build/testWorker.js:106:12)
82
82
 
83
- 1077 | this.handleSighashType(sig);
84
- 1078 | } catch (err) {
85
- > 1079 | console.error(err);
83
+ 1078 | this.handleSighashType(sig);
84
+ 1079 | } catch (err) {
85
+ > 1080 | console.error(err);
86
86
  | ^
87
- 1080 | // To remain atomic, attempt to reset everything to the way it was.
88
- 1081 | this.inputMaps[inputIndex].delete(key);
89
- 1082 | this.PSBT_GLOBAL_TX_MODIFIABLE = modBackup;
87
+ 1081 | // To remain atomic, attempt to reset everything to the way it was.
88
+ 1082 | this.inputMaps[inputIndex].delete(key);
89
+ 1083 | this.PSBT_GLOBAL_TX_MODIFIABLE = modBackup;
90
90
 
91
- at PsbtV2.addPartialSig (src/psbtv2/psbtv2.ts:1079:15)
91
+ at PsbtV2.addPartialSig (src/psbtv2/psbtv2.ts:1080:15)
92
92
  at Object.<anonymous> (src/psbtv2/psbtv2.test.ts:1198:10)
93
93
 
94
94
 
95
95
  Test Suites: 2 passed, 2 total
96
- Tests: 192 passed, 192 total
96
+ Tests: 197 passed, 197 total
97
97
  Snapshots: 0 total
98
- Time: 5.211 s
98
+ Time: 5.325 s
99
99
  Ran all test suites matching /src/i.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @caravan/psbt
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#73](https://github.com/caravan-bitcoin/caravan/pull/73) [`c58f786`](https://github.com/caravan-bitcoin/caravan/commit/c58f786c3409795e12a17a4fe9a3ff4fbf7c6517) Thanks [@Shadouts](https://github.com/Shadouts)! - PsbtV2 public setProprietaryValue allows for proprietary value mapping on the psbt.
8
+
3
9
  ## 1.1.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -34,6 +34,7 @@ A set of utilities for working with PSBTs.
34
34
  - [`public deleteOutput`](#public-deleteoutput)
35
35
  - [`public addPartialSig`](#public-addpartialsig)
36
36
  - [`public removePartialSig`](#public-removepartialsig)
37
+ - [`public setProprietaryValue`](#public-setproprietaryvalue)
37
38
  - [`static PsbtV2.FromV0`](#static-psbtv2fromv0)
38
39
  - [`function getPsbtVersionNumber`](#function-getpsbtversionnumber)
39
40
  - [Concepts](#concepts)
@@ -217,6 +218,20 @@ The Signer, when it creates a signature, must add the partial sig keypair to the
217
218
 
218
219
  Removes all sigs for an input unless a pubkey is specified. Validates that the input exists. When providing a pubkey, this validates that a sig for the pubkey exists.
219
220
 
221
+ ##### `public setProprietaryValue`
222
+
223
+ Sets values on the proprietary keytype for a global, input, or output map. BIP 174 allows for proprietary values to be set on all maps with the keytype `0xFC`. This method sets byte data to key values defined by the args.
224
+
225
+ Args:
226
+
227
+ - `mapSelector` selects which map to set the proprietary value. If this value is not `"global"`, then a tuple must be provided with `"inputs"` or `"outputs"` as the first element and the index `number` on the second element representing which input or output map to set the value to. An example looks like `["inputs", 0]`. If the map name doesn't match, the values will be set to the global map. If the index is missing on `"inputs"` or `"outputs"`, then it will throw.
228
+ - `identifier` should be the bytes identifier for the set of proprietary keytypes.
229
+ - `subkeyType` accepts bytes proprietary keytype.
230
+ - `subkeyData` accepts bytes proprietary keydata.
231
+ - `valueData` accepts bytes which will be written as the proprietary value.
232
+
233
+ From the provided args, a key with the following format will be generated: `0xFC<compact uint identifier length><bytes identifier><bytes subtype><bytes subkeydata>`
234
+
220
235
  ##### `static PsbtV2.FromV0`
221
236
 
222
237
  Attempts to return a `PsbtV2` by converting from a PSBTv0 string or Buffer
package/dist/index.d.mts CHANGED
@@ -24,6 +24,8 @@ declare enum PsbtGlobalTxModifiableBits {
24
24
  OUTPUTS = "OUTPUTS",// 0b00000010
25
25
  SIGHASH_SINGLE = "SIGHASH_SINGLE"
26
26
  }
27
+ type InputOutputIndexType = number;
28
+ type MapSelectorType = "global" | ["inputs", InputOutputIndexType] | ["outputs", InputOutputIndexType];
27
29
 
28
30
  /**
29
31
  * Attempts to extract the version number as uint32LE from raw psbt regardless
@@ -279,6 +281,31 @@ declare class PsbtV2 extends PsbtV2Maps {
279
281
  * the pubkey exists.
280
282
  */
281
283
  removePartialSig(inputIndex: number, pubkey?: Buffer): void;
284
+ /**
285
+ * Sets values on the proprietary keytype for a global, input, or output map.
286
+ * BIP 174 allows for proprietary values to be set on all maps with the
287
+ * keytype `0xFC`. This method sets byte data to key values defined by the
288
+ * args.
289
+ *
290
+ * Args:
291
+ * - `mapSelector` selects which map to set the proprietary value. If this
292
+ * value is not `"global"`, then a tuple must be provided with `"inputs"` or
293
+ * `"outputs"` as the first element and the index `number` on the second
294
+ * element representing which input or output map to set the value to. An
295
+ * example looks like `["inputs", 0]`. If the map name doesn't match, the
296
+ * values will be set to the global map. If the index is missing on
297
+ * `"inputs"` or `"outputs"`, then it will throw.
298
+ * - `identifier` should be the bytes identifier for the set of proprietary
299
+ * keytypes.
300
+ * - `subkeyType` accepts bytes proprietary keytype.
301
+ * - `subkeyData` accepts bytes proprietary keydata.
302
+ * - `valueData` accepts bytes which will be written as the proprietary value.
303
+ *
304
+ * From the provided args, a key with the following format will be generated:
305
+ * `0xFC<compact uint identifier length><bytes identifier><bytes
306
+ * subtype><bytes subkeydata>`
307
+ */
308
+ setProprietaryValue(mapSelector: MapSelectorType, identifier: Buffer, subkeyType: Buffer, subkeyData: Buffer, valueData: Buffer): void;
282
309
  /**
283
310
  * Ensures the PSBT is in the proper state when adding a partial sig keypair.
284
311
  * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ declare enum PsbtGlobalTxModifiableBits {
24
24
  OUTPUTS = "OUTPUTS",// 0b00000010
25
25
  SIGHASH_SINGLE = "SIGHASH_SINGLE"
26
26
  }
27
+ type InputOutputIndexType = number;
28
+ type MapSelectorType = "global" | ["inputs", InputOutputIndexType] | ["outputs", InputOutputIndexType];
27
29
 
28
30
  /**
29
31
  * Attempts to extract the version number as uint32LE from raw psbt regardless
@@ -279,6 +281,31 @@ declare class PsbtV2 extends PsbtV2Maps {
279
281
  * the pubkey exists.
280
282
  */
281
283
  removePartialSig(inputIndex: number, pubkey?: Buffer): void;
284
+ /**
285
+ * Sets values on the proprietary keytype for a global, input, or output map.
286
+ * BIP 174 allows for proprietary values to be set on all maps with the
287
+ * keytype `0xFC`. This method sets byte data to key values defined by the
288
+ * args.
289
+ *
290
+ * Args:
291
+ * - `mapSelector` selects which map to set the proprietary value. If this
292
+ * value is not `"global"`, then a tuple must be provided with `"inputs"` or
293
+ * `"outputs"` as the first element and the index `number` on the second
294
+ * element representing which input or output map to set the value to. An
295
+ * example looks like `["inputs", 0]`. If the map name doesn't match, the
296
+ * values will be set to the global map. If the index is missing on
297
+ * `"inputs"` or `"outputs"`, then it will throw.
298
+ * - `identifier` should be the bytes identifier for the set of proprietary
299
+ * keytypes.
300
+ * - `subkeyType` accepts bytes proprietary keytype.
301
+ * - `subkeyData` accepts bytes proprietary keydata.
302
+ * - `valueData` accepts bytes which will be written as the proprietary value.
303
+ *
304
+ * From the provided args, a key with the following format will be generated:
305
+ * `0xFC<compact uint identifier length><bytes identifier><bytes
306
+ * subtype><bytes subkeydata>`
307
+ */
308
+ setProprietaryValue(mapSelector: MapSelectorType, identifier: Buffer, subkeyType: Buffer, subkeyData: Buffer, valueData: Buffer): void;
282
309
  /**
283
310
  * Ensures the PSBT is in the proper state when adding a partial sig keypair.
284
311
  * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
package/dist/index.js CHANGED
@@ -1043,6 +1043,58 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
1043
1043
  }
1044
1044
  }
1045
1045
  }
1046
+ /**
1047
+ * Sets values on the proprietary keytype for a global, input, or output map.
1048
+ * BIP 174 allows for proprietary values to be set on all maps with the
1049
+ * keytype `0xFC`. This method sets byte data to key values defined by the
1050
+ * args.
1051
+ *
1052
+ * Args:
1053
+ * - `mapSelector` selects which map to set the proprietary value. If this
1054
+ * value is not `"global"`, then a tuple must be provided with `"inputs"` or
1055
+ * `"outputs"` as the first element and the index `number` on the second
1056
+ * element representing which input or output map to set the value to. An
1057
+ * example looks like `["inputs", 0]`. If the map name doesn't match, the
1058
+ * values will be set to the global map. If the index is missing on
1059
+ * `"inputs"` or `"outputs"`, then it will throw.
1060
+ * - `identifier` should be the bytes identifier for the set of proprietary
1061
+ * keytypes.
1062
+ * - `subkeyType` accepts bytes proprietary keytype.
1063
+ * - `subkeyData` accepts bytes proprietary keydata.
1064
+ * - `valueData` accepts bytes which will be written as the proprietary value.
1065
+ *
1066
+ * From the provided args, a key with the following format will be generated:
1067
+ * `0xFC<compact uint identifier length><bytes identifier><bytes
1068
+ * subtype><bytes subkeydata>`
1069
+ */
1070
+ setProprietaryValue(mapSelector, identifier, subkeyType, subkeyData, valueData) {
1071
+ if ((mapSelector[0] === "inputs" || mapSelector[0] === "outputs") && typeof mapSelector[1] !== "number") {
1072
+ throw Error(
1073
+ "Must specify an index when setting proprietary values to inputs or outputs."
1074
+ );
1075
+ }
1076
+ let classMap = this.globalMap, keyType = "fc" /* PSBT_GLOBAL_PROPRIETARY */;
1077
+ if (mapSelector[0] === "inputs") {
1078
+ classMap = this.inputMaps[mapSelector[1]];
1079
+ keyType = "fc" /* PSBT_IN_PROPRIETARY */;
1080
+ } else if (mapSelector[0] === "outputs") {
1081
+ classMap = this.outputMaps[mapSelector[1]];
1082
+ keyType = "fc" /* PSBT_OUT_PROPRIETARY */;
1083
+ }
1084
+ if (!classMap) {
1085
+ throw Error("Map does not exist at that index.");
1086
+ }
1087
+ const bw = new import_bufio3.BufferWriter();
1088
+ bw.writeBytes(import_buffer.Buffer.from(keyType, "hex"));
1089
+ bw.writeU8(identifier.length);
1090
+ bw.writeBytes(identifier);
1091
+ bw.writeBytes(subkeyType);
1092
+ bw.writeBytes(subkeyData);
1093
+ const key = bw.render().toString("hex");
1094
+ bw.writeBytes(valueData);
1095
+ const value = bw.render();
1096
+ classMap.set(key, value);
1097
+ }
1046
1098
  /**
1047
1099
  * Ensures the PSBT is in the proper state when adding a partial sig keypair.
1048
1100
  * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
package/dist/index.mjs CHANGED
@@ -1024,6 +1024,58 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
1024
1024
  }
1025
1025
  }
1026
1026
  }
1027
+ /**
1028
+ * Sets values on the proprietary keytype for a global, input, or output map.
1029
+ * BIP 174 allows for proprietary values to be set on all maps with the
1030
+ * keytype `0xFC`. This method sets byte data to key values defined by the
1031
+ * args.
1032
+ *
1033
+ * Args:
1034
+ * - `mapSelector` selects which map to set the proprietary value. If this
1035
+ * value is not `"global"`, then a tuple must be provided with `"inputs"` or
1036
+ * `"outputs"` as the first element and the index `number` on the second
1037
+ * element representing which input or output map to set the value to. An
1038
+ * example looks like `["inputs", 0]`. If the map name doesn't match, the
1039
+ * values will be set to the global map. If the index is missing on
1040
+ * `"inputs"` or `"outputs"`, then it will throw.
1041
+ * - `identifier` should be the bytes identifier for the set of proprietary
1042
+ * keytypes.
1043
+ * - `subkeyType` accepts bytes proprietary keytype.
1044
+ * - `subkeyData` accepts bytes proprietary keydata.
1045
+ * - `valueData` accepts bytes which will be written as the proprietary value.
1046
+ *
1047
+ * From the provided args, a key with the following format will be generated:
1048
+ * `0xFC<compact uint identifier length><bytes identifier><bytes
1049
+ * subtype><bytes subkeydata>`
1050
+ */
1051
+ setProprietaryValue(mapSelector, identifier, subkeyType, subkeyData, valueData) {
1052
+ if ((mapSelector[0] === "inputs" || mapSelector[0] === "outputs") && typeof mapSelector[1] !== "number") {
1053
+ throw Error(
1054
+ "Must specify an index when setting proprietary values to inputs or outputs."
1055
+ );
1056
+ }
1057
+ let classMap = this.globalMap, keyType = "fc" /* PSBT_GLOBAL_PROPRIETARY */;
1058
+ if (mapSelector[0] === "inputs") {
1059
+ classMap = this.inputMaps[mapSelector[1]];
1060
+ keyType = "fc" /* PSBT_IN_PROPRIETARY */;
1061
+ } else if (mapSelector[0] === "outputs") {
1062
+ classMap = this.outputMaps[mapSelector[1]];
1063
+ keyType = "fc" /* PSBT_OUT_PROPRIETARY */;
1064
+ }
1065
+ if (!classMap) {
1066
+ throw Error("Map does not exist at that index.");
1067
+ }
1068
+ const bw = new BufferWriter3();
1069
+ bw.writeBytes(Buffer.from(keyType, "hex"));
1070
+ bw.writeU8(identifier.length);
1071
+ bw.writeBytes(identifier);
1072
+ bw.writeBytes(subkeyType);
1073
+ bw.writeBytes(subkeyData);
1074
+ const key = bw.render().toString("hex");
1075
+ bw.writeBytes(valueData);
1076
+ const value = bw.render();
1077
+ classMap.set(key, value);
1078
+ }
1027
1079
  /**
1028
1080
  * Ensures the PSBT is in the proper state when adding a partial sig keypair.
1029
1081
  * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caravan/psbt",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "typescript library for working with PSBTs",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1388,3 +1388,200 @@ describe("PsbtV2.isModifiable (private)", () => {
1388
1388
  },
1389
1389
  );
1390
1390
  });
1391
+
1392
+ describe("PsbtV2.setProprietaryValue", () => {
1393
+ const identifier = Buffer.from("satoshi");
1394
+ const idLength = Buffer.from([identifier.length]);
1395
+ const keytype1 = Buffer.from("00", "hex");
1396
+ const keytype2 = Buffer.from("01", "hex");
1397
+ const keydata1 = Buffer.from("0001", "hex");
1398
+ const keydata2 = Buffer.from("0002", "hex");
1399
+ const valuedata1 = Buffer.from("000001", "hex");
1400
+ const valuedata2 = Buffer.from("000002", "hex");
1401
+
1402
+ const key1 = Buffer.from([
1403
+ 0xfc,
1404
+ ...idLength,
1405
+ ...identifier,
1406
+ ...keytype1,
1407
+ ...keydata1,
1408
+ ]).toString("hex");
1409
+ const key2 = Buffer.from([
1410
+ 0xfc,
1411
+ ...idLength,
1412
+ ...identifier,
1413
+ ...keytype2,
1414
+ ...keydata2,
1415
+ ]).toString("hex");
1416
+
1417
+ let psbt: PsbtV2;
1418
+
1419
+ beforeEach(() => {
1420
+ psbt = new PsbtV2();
1421
+ });
1422
+
1423
+ it("sets values to the global map", () => {
1424
+ psbt.setProprietaryValue(
1425
+ "global",
1426
+ identifier,
1427
+ keytype1,
1428
+ keydata1,
1429
+ valuedata1,
1430
+ );
1431
+ psbt.setProprietaryValue(
1432
+ "global",
1433
+ identifier,
1434
+ keytype2,
1435
+ keydata2,
1436
+ valuedata2,
1437
+ );
1438
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[0].key).toBe(key1);
1439
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[0].value).toBe(
1440
+ valuedata1.toString("hex"),
1441
+ );
1442
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[1].key).toBe(key2);
1443
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[1].value).toBe(
1444
+ valuedata2.toString("hex"),
1445
+ );
1446
+ });
1447
+
1448
+ it("defaults to setting global maps when the map selector is malformed", () => {
1449
+ psbt.setProprietaryValue(
1450
+ "inputs" as any,
1451
+ identifier,
1452
+ keytype1,
1453
+ keydata1,
1454
+ valuedata1,
1455
+ );
1456
+ expect((psbt as any).inputMaps.length).toBe(0);
1457
+ expect((psbt as any).outputMaps.length).toBe(0);
1458
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[0].key).toBe(key1);
1459
+ expect(psbt.PSBT_GLOBAL_PROPRIETARY[0].value).toBe(
1460
+ valuedata1.toString("hex"),
1461
+ );
1462
+ });
1463
+
1464
+ it("throws when input or output map are missing an index", () => {
1465
+ expect(() =>
1466
+ psbt.setProprietaryValue(
1467
+ ["inputs"] as any,
1468
+ identifier,
1469
+ keytype1,
1470
+ keydata1,
1471
+ valuedata1,
1472
+ ),
1473
+ ).toThrow(
1474
+ "Must specify an index when setting proprietary values to inputs or outputs.",
1475
+ );
1476
+
1477
+ expect(() =>
1478
+ psbt.setProprietaryValue(
1479
+ ["inputs", null] as any,
1480
+ identifier,
1481
+ keytype1,
1482
+ keydata1,
1483
+ valuedata1,
1484
+ ),
1485
+ ).toThrow(
1486
+ "Must specify an index when setting proprietary values to inputs or outputs.",
1487
+ );
1488
+
1489
+ expect(() =>
1490
+ psbt.setProprietaryValue(
1491
+ ["outputs"] as any,
1492
+ identifier,
1493
+ keytype1,
1494
+ keydata1,
1495
+ valuedata1,
1496
+ ),
1497
+ ).toThrow(
1498
+ "Must specify an index when setting proprietary values to inputs or outputs.",
1499
+ );
1500
+
1501
+ expect(() =>
1502
+ psbt.setProprietaryValue(
1503
+ ["outputs", null] as any,
1504
+ identifier,
1505
+ keytype1,
1506
+ keydata1,
1507
+ valuedata1,
1508
+ ),
1509
+ ).toThrow(
1510
+ "Must specify an index when setting proprietary values to inputs or outputs.",
1511
+ );
1512
+ });
1513
+
1514
+ it("throws when input or output map is uninitialized", () => {
1515
+ expect(() =>
1516
+ psbt.setProprietaryValue(
1517
+ ["inputs", 0],
1518
+ identifier,
1519
+ keytype1,
1520
+ keydata1,
1521
+ valuedata1,
1522
+ ),
1523
+ ).toThrow("Map does not exist at that index.");
1524
+
1525
+ expect(() =>
1526
+ psbt.setProprietaryValue(
1527
+ ["outputs", 0],
1528
+ identifier,
1529
+ keytype1,
1530
+ keydata1,
1531
+ valuedata1,
1532
+ ),
1533
+ ).toThrow("Map does not exist at that index.");
1534
+ });
1535
+
1536
+ it("sets values to input and output maps", () => {
1537
+ psbt.addInput({ previousTxId: Buffer.from([0x00]), outputIndex: 0 });
1538
+ psbt.addInput({ previousTxId: Buffer.from([0x01]), outputIndex: 1 });
1539
+ psbt.addOutput({ amount: 1, script: Buffer.from([0x00]) });
1540
+ psbt.addOutput({ amount: 2, script: Buffer.from([0x01]) });
1541
+ psbt.setProprietaryValue(
1542
+ ["inputs", 0],
1543
+ identifier,
1544
+ keytype1,
1545
+ keydata1,
1546
+ valuedata1,
1547
+ );
1548
+ psbt.setProprietaryValue(
1549
+ ["inputs", 1],
1550
+ identifier,
1551
+ keytype2,
1552
+ keydata2,
1553
+ valuedata2,
1554
+ );
1555
+ psbt.setProprietaryValue(
1556
+ ["outputs", 0],
1557
+ identifier,
1558
+ keytype1,
1559
+ keydata1,
1560
+ valuedata1,
1561
+ );
1562
+ psbt.setProprietaryValue(
1563
+ ["outputs", 1],
1564
+ identifier,
1565
+ keytype2,
1566
+ keydata2,
1567
+ valuedata2,
1568
+ );
1569
+
1570
+ expect(psbt.PSBT_IN_PROPRIETARY[0][0].key).toBe(key1);
1571
+ expect(psbt.PSBT_IN_PROPRIETARY[0][0].value).toBe(
1572
+ valuedata1.toString("hex"),
1573
+ );
1574
+ expect(psbt.PSBT_IN_PROPRIETARY[1][0].key).toBe(key2);
1575
+ expect(psbt.PSBT_IN_PROPRIETARY[1][0].value).toBe(
1576
+ valuedata2.toString("hex"),
1577
+ );
1578
+ expect(psbt.PSBT_OUT_PROPRIETARY[0][0].key).toBe(key1);
1579
+ expect(psbt.PSBT_OUT_PROPRIETARY[0][0].value).toBe(
1580
+ valuedata1.toString("hex"),
1581
+ );
1582
+ expect(psbt.PSBT_OUT_PROPRIETARY[1][0].key).toBe(key2);
1583
+ expect(psbt.PSBT_OUT_PROPRIETARY[1][0].value).toBe(
1584
+ valuedata2.toString("hex"),
1585
+ );
1586
+ });
1587
+ });
@@ -8,6 +8,7 @@ import {
8
8
  KeyType,
9
9
  PsbtGlobalTxModifiableBits,
10
10
  SighashType,
11
+ MapSelectorType,
11
12
  } from "./types";
12
13
  import {
13
14
  bufferize,
@@ -1120,6 +1121,72 @@ export class PsbtV2 extends PsbtV2Maps {
1120
1121
  }
1121
1122
  }
1122
1123
 
1124
+ /**
1125
+ * Sets values on the proprietary keytype for a global, input, or output map.
1126
+ * BIP 174 allows for proprietary values to be set on all maps with the
1127
+ * keytype `0xFC`. This method sets byte data to key values defined by the
1128
+ * args.
1129
+ *
1130
+ * Args:
1131
+ * - `mapSelector` selects which map to set the proprietary value. If this
1132
+ * value is not `"global"`, then a tuple must be provided with `"inputs"` or
1133
+ * `"outputs"` as the first element and the index `number` on the second
1134
+ * element representing which input or output map to set the value to. An
1135
+ * example looks like `["inputs", 0]`. If the map name doesn't match, the
1136
+ * values will be set to the global map. If the index is missing on
1137
+ * `"inputs"` or `"outputs"`, then it will throw.
1138
+ * - `identifier` should be the bytes identifier for the set of proprietary
1139
+ * keytypes.
1140
+ * - `subkeyType` accepts bytes proprietary keytype.
1141
+ * - `subkeyData` accepts bytes proprietary keydata.
1142
+ * - `valueData` accepts bytes which will be written as the proprietary value.
1143
+ *
1144
+ * From the provided args, a key with the following format will be generated:
1145
+ * `0xFC<compact uint identifier length><bytes identifier><bytes
1146
+ * subtype><bytes subkeydata>`
1147
+ */
1148
+ public setProprietaryValue(
1149
+ mapSelector: MapSelectorType,
1150
+ identifier: Buffer,
1151
+ subkeyType: Buffer,
1152
+ subkeyData: Buffer,
1153
+ valueData: Buffer,
1154
+ ) {
1155
+ if (
1156
+ (mapSelector[0] === "inputs" || mapSelector[0] === "outputs") &&
1157
+ typeof mapSelector[1] !== "number"
1158
+ ) {
1159
+ throw Error(
1160
+ "Must specify an index when setting proprietary values to inputs or outputs.",
1161
+ );
1162
+ }
1163
+
1164
+ let classMap: Map<string, Buffer> = this.globalMap,
1165
+ keyType = KeyType.PSBT_GLOBAL_PROPRIETARY;
1166
+ if (mapSelector[0] === "inputs") {
1167
+ classMap = this.inputMaps[mapSelector[1]];
1168
+ keyType = KeyType.PSBT_IN_PROPRIETARY;
1169
+ } else if (mapSelector[0] === "outputs") {
1170
+ classMap = this.outputMaps[mapSelector[1]];
1171
+ keyType = KeyType.PSBT_OUT_PROPRIETARY;
1172
+ }
1173
+
1174
+ if (!classMap) {
1175
+ throw Error("Map does not exist at that index.");
1176
+ }
1177
+
1178
+ const bw = new BufferWriter();
1179
+ bw.writeBytes(Buffer.from(keyType, "hex"));
1180
+ bw.writeU8(identifier.length);
1181
+ bw.writeBytes(identifier);
1182
+ bw.writeBytes(subkeyType);
1183
+ bw.writeBytes(subkeyData);
1184
+ const key = bw.render().toString("hex");
1185
+ bw.writeBytes(valueData);
1186
+ const value = bw.render();
1187
+ classMap.set(key, value);
1188
+ }
1189
+
1123
1190
  /**
1124
1191
  * Ensures the PSBT is in the proper state when adding a partial sig keypair.
1125
1192
  * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
@@ -83,3 +83,9 @@ export enum SighashType {
83
83
  SIGHASH_SINGLE = 0x03,
84
84
  SIGHASH_ANYONECANPAY = 0x80,
85
85
  }
86
+
87
+ type InputOutputIndexType = number;
88
+ export type MapSelectorType =
89
+ | "global"
90
+ | ["inputs", InputOutputIndexType]
91
+ | ["outputs", InputOutputIndexType];