@1sat/templates 0.0.22 → 0.0.24

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/dist/index.d.ts CHANGED
@@ -3,7 +3,13 @@ export type { Signer } from './signer.js';
3
3
  export { default as Inscription } from './inscription/inscription.js';
4
4
  export { default as BSV20 } from './bsv20/bsv20.js';
5
5
  export { default as BSV21 } from './bsv21/bsv21.js';
6
+ export { default as Shrug, SHRUG_TAG_HEX } from './shrug/shrug.js';
7
+ export type { ShrugData } from './shrug/shrug.js';
8
+ export { SHRUG_METADATA_CONTENT_TYPE, decodeShrugMetadata, encodeShrugMetadata, outpointFromBytes, outpointToBytes, } from './shrug/metadata.js';
9
+ export type { ShrugMetadata } from './shrug/metadata.js';
6
10
  export { default as OrdLock } from './ordlock/ordlock.js';
11
+ export { default as OpNS, OPNS_CONTRACT_BYTES, OPNS_GENESIS_BYTES, } from './opns/opns.js';
12
+ export type { OpNSData } from './opns/opns.js';
7
13
  export { default as Lock } from './lock/lock.js';
8
14
  export { default as Cosign } from './cosign/cosign.js';
9
15
  export type { CosignData } from './cosign/cosign.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,7 +4,10 @@ export { PrivateKeySigner, WalletSigner } from './signer.js';
4
4
  export { default as Inscription } from './inscription/inscription.js';
5
5
  export { default as BSV20 } from './bsv20/bsv20.js';
6
6
  export { default as BSV21 } from './bsv21/bsv21.js';
7
+ export { default as Shrug, SHRUG_TAG_HEX } from './shrug/shrug.js';
8
+ export { SHRUG_METADATA_CONTENT_TYPE, decodeShrugMetadata, encodeShrugMetadata, outpointFromBytes, outpointToBytes, } from './shrug/metadata.js';
7
9
  export { default as OrdLock } from './ordlock/ordlock.js';
10
+ export { default as OpNS, OPNS_CONTRACT_BYTES, OPNS_GENESIS_BYTES, } from './opns/opns.js';
8
11
  export { default as Lock } from './lock/lock.js';
9
12
  export { default as Cosign } from './cosign/cosign.js';
10
13
  export { default as P2MS } from './multisig/multisig.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG5D,mBAAmB;AACnB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAGxD,mBAAmB;AACnB,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAEhD,UAAU;AACV,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAEzD,qEAAqE;AACrE,kCAAkC;AAClC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAqCpD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAMrE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAezD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAM5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAM7D,OAAO,EACN,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,iBAAiB,CAAA;AAMxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAWxD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE1E,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAC/E,OAAO,EACN,iBAAiB,EACjB,cAAc,GACd,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG5D,mBAAmB;AACnB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAElE,OAAO,EACN,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,GACf,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EACN,OAAO,IAAI,IAAI,EACf,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAGxD,mBAAmB;AACnB,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAEhD,UAAU;AACV,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAEzD,qEAAqE;AACrE,kCAAkC;AAClC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAqCpD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAMrE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAezD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAM5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAM7D,OAAO,EACN,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,iBAAiB,CAAA;AAMxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAWxD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE1E,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAC/E,OAAO,EACN,iBAAiB,EACjB,cAAc,GACd,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,101 @@
1
+ import { Script, type Transaction, UnlockingScript } from '@bsv/sdk';
2
+ /** OpNS covenant contract as a byte array (the compiled sCrypt prefix). */
3
+ export declare const OPNS_CONTRACT_BYTES: any[];
4
+ /** Genesis outpoint bytes embedded in every node's state. */
5
+ export declare const OPNS_GENESIS_BYTES: any[];
6
+ /** Decoded OpNS node state. */
7
+ export interface OpNSData {
8
+ /** Claimed-character bitfield (little-endian). */
9
+ claimed: number[];
10
+ /** The name mined so far. */
11
+ domain: string;
12
+ /** Proof-of-work root: sha256d hash the node was mined to. */
13
+ pow: number[];
14
+ }
15
+ /**
16
+ * OpNS - Ordinals Name System covenant template.
17
+ *
18
+ * A node output locks the compiled covenant plus a stateful OP_RETURN trailer
19
+ * carrying {genesis, claimed, domain, pow}. Spending it mines one character:
20
+ * the keyless unlock pushes char + nonce + ownerScript + trailingOutputs +
21
+ * the BIP-143 preimage (SIGHASH_ALL | ANYONECANPAY | FORKID), and the covenant
22
+ * validates the three mandated outputs (restated parent, child node, name
23
+ * inscription) against its own introspected state.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const node = OpNS.decode(parentTx.outputs[1].lockingScript)
28
+ * const child = OpNS.lock([0], node.domain + 'h', solutionHash)
29
+ * ```
30
+ */
31
+ export default class OpNS {
32
+ /**
33
+ * Builds a node locking script: the compiled covenant followed by the
34
+ * stateful OP_RETURN trailer.
35
+ *
36
+ * @param claimed - Claimed-character bitfield (little-endian)
37
+ * @param domain - The name mined so far
38
+ * @param pow - The sha256d hash the node was mined to (32 bytes)
39
+ * @returns The node locking script
40
+ */
41
+ static lock(claimed: number[], domain: string, pow: number[]): Script;
42
+ /**
43
+ * Decodes a node's state from its locking script.
44
+ *
45
+ * @param script - The locking script to decode
46
+ * @returns Decoded node state, or null if not an OpNS node
47
+ */
48
+ static decode(script: Script): OpNSData | null;
49
+ /**
50
+ * Sets the bit for a claimed character in the node's bitfield.
51
+ *
52
+ * @param claimed - Current claimed bitfield (little-endian)
53
+ * @param char - Character byte to mark claimed
54
+ * @returns Updated claimed bitfield
55
+ */
56
+ static claimBit(claimed: number[], char: number): number[];
57
+ /**
58
+ * Builds the 1Sat ordinal inscription for a mined name, locked to
59
+ * ownerScript.
60
+ *
61
+ * @param domain - The mined name
62
+ * @param ownerScript - The owner's locking script (prefix)
63
+ * @returns The inscription locking script
64
+ */
65
+ static buildInscription(domain: string, ownerScript: Script): Script;
66
+ /**
67
+ * Tests whether a nonce solves the proof-of-work for a character: the
68
+ * top OPNS_DIFFICULTY bits of the reversed sha256d(pow ‖ char ‖ nonce)
69
+ * must be zero.
70
+ *
71
+ * @param pow - The node's pow root (32 bytes)
72
+ * @param char - Character byte being mined
73
+ * @param nonce - Candidate nonce (32 bytes)
74
+ * @returns The solution hash if valid, otherwise null
75
+ */
76
+ static testSolution(pow: number[], char: number, nonce: number[]): number[] | null;
77
+ /**
78
+ * Serializes a transaction output (8-byte LE value + varint length +
79
+ * script) as the covenant expects in trailingOutputs.
80
+ *
81
+ * @param satoshis - Output value
82
+ * @param script - Locking script bytes
83
+ * @returns Serialized output bytes
84
+ */
85
+ static buildOutput(satoshis: number, script: number[]): number[];
86
+ /**
87
+ * Builds the keyless covenant unlock for a mined character. The unlock
88
+ * pushes char, nonce, ownerScript, the serialized trailing outputs (those
89
+ * beyond the three mandated by the covenant), and the BIP-143 preimage.
90
+ *
91
+ * @param char - Character byte being mined
92
+ * @param nonce - The winning nonce (32 bytes)
93
+ * @param ownerScript - The owner's locking script for the name
94
+ * @returns Unlock template with sign and estimateLength methods
95
+ */
96
+ static unlock(char: number, nonce: number[], ownerScript: Script): {
97
+ sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>;
98
+ estimateLength: (tx: Transaction, inputIndex: number) => Promise<number>;
99
+ };
100
+ }
101
+ //# sourceMappingURL=opns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opns.d.ts","sourceRoot":"","sources":["../../src/opns/opns.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,MAAM,EACN,KAAK,WAAW,EAEhB,eAAe,EAEf,MAAM,UAAU,CAAA;AAEjB,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,OAAsC,CAAA;AAEtE,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,OAAqC,CAAA;AAQpE,+BAA+B;AAC/B,MAAM,WAAW,QAAQ;IACxB,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,GAAG,EAAE,MAAM,EAAE,CAAA;CACb;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IACxB;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM;IAkBrE;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAwB9C;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAY1D;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAgBpE;;;;;;;;;OASG;IACH,MAAM,CAAC,YAAY,CAClB,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,GACb,MAAM,EAAE,GAAG,IAAI;IAelB;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAQhE;;;;;;;;;OASG;IACH,MAAM,CAAC,MAAM,CACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,MAAM,GACjB;QACF,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;QACvE,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;KACxE;CA6DD"}
@@ -0,0 +1,224 @@
1
+ import { OPNS_CONTRACT, OPNS_DIFFICULTY, OPNS_GENESIS } from '@1sat/types';
2
+ import { BigNumber, Hash, OP, Script, TransactionSignature, UnlockingScript, Utils, } from '@bsv/sdk';
3
+ /** OpNS covenant contract as a byte array (the compiled sCrypt prefix). */
4
+ export const OPNS_CONTRACT_BYTES = Utils.toArray(OPNS_CONTRACT, 'hex');
5
+ /** Genesis outpoint bytes embedded in every node's state. */
6
+ export const OPNS_GENESIS_BYTES = Utils.toArray(OPNS_GENESIS, 'hex');
7
+ /** Ordinal inscription bitcom address for OpNS names. */
8
+ const OPNS_BITCOM = '1opNSUJVbBc2Vf8LFNSoywGGK4jMcGVrC';
9
+ /** OpNS content type. */
10
+ const OPNS_CONTENT_TYPE = 'application/op-ns';
11
+ /**
12
+ * OpNS - Ordinals Name System covenant template.
13
+ *
14
+ * A node output locks the compiled covenant plus a stateful OP_RETURN trailer
15
+ * carrying {genesis, claimed, domain, pow}. Spending it mines one character:
16
+ * the keyless unlock pushes char + nonce + ownerScript + trailingOutputs +
17
+ * the BIP-143 preimage (SIGHASH_ALL | ANYONECANPAY | FORKID), and the covenant
18
+ * validates the three mandated outputs (restated parent, child node, name
19
+ * inscription) against its own introspected state.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const node = OpNS.decode(parentTx.outputs[1].lockingScript)
24
+ * const child = OpNS.lock([0], node.domain + 'h', solutionHash)
25
+ * ```
26
+ */
27
+ export default class OpNS {
28
+ /**
29
+ * Builds a node locking script: the compiled covenant followed by the
30
+ * stateful OP_RETURN trailer.
31
+ *
32
+ * @param claimed - Claimed-character bitfield (little-endian)
33
+ * @param domain - The name mined so far
34
+ * @param pow - The sha256d hash the node was mined to (32 bytes)
35
+ * @returns The node locking script
36
+ */
37
+ static lock(claimed, domain, pow) {
38
+ const state = new Script()
39
+ .writeOpCode(OP.OP_RETURN)
40
+ .writeOpCode(OP.OP_FALSE)
41
+ .writeBin(OPNS_GENESIS_BYTES)
42
+ .writeBin(claimed)
43
+ .writeBin(Utils.toArray(domain, 'utf8'))
44
+ .writeBin(pow);
45
+ const stateBin = state.toBinary();
46
+ const writer = new Utils.Writer();
47
+ writer.write(stateBin);
48
+ writer.writeUInt32LE(stateBin.length - 1);
49
+ writer.writeUInt8(0);
50
+ return Script.fromBinary([...OPNS_CONTRACT_BYTES, ...writer.toArray()]);
51
+ }
52
+ /**
53
+ * Decodes a node's state from its locking script.
54
+ *
55
+ * @param script - The locking script to decode
56
+ * @returns Decoded node state, or null if not an OpNS node
57
+ */
58
+ static decode(script) {
59
+ try {
60
+ const bin = script.toBinary();
61
+ for (let i = 0; i < OPNS_CONTRACT_BYTES.length; i++) {
62
+ if (bin[i] !== OPNS_CONTRACT_BYTES[i])
63
+ return null;
64
+ }
65
+ // State starts after the contract plus OP_RETURN + OP_FALSE.
66
+ const state = Script.fromBinary(bin.slice(OPNS_CONTRACT_BYTES.length + 2));
67
+ const genesis = state.chunks[0]?.data;
68
+ if (genesis == null)
69
+ return null;
70
+ for (let i = 0; i < OPNS_GENESIS_BYTES.length; i++) {
71
+ if (genesis[i] !== OPNS_GENESIS_BYTES[i])
72
+ return null;
73
+ }
74
+ const domainData = state.chunks[2]?.data ?? [];
75
+ return {
76
+ claimed: state.chunks[1]?.data ?? [],
77
+ domain: Utils.toUTF8(domainData),
78
+ pow: state.chunks[3]?.data ?? [],
79
+ };
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Sets the bit for a claimed character in the node's bitfield.
87
+ *
88
+ * @param claimed - Current claimed bitfield (little-endian)
89
+ * @param char - Character byte to mark claimed
90
+ * @returns Updated claimed bitfield
91
+ */
92
+ static claimBit(claimed, char) {
93
+ let bits = 0n;
94
+ for (const b of [...claimed].reverse())
95
+ bits = (bits << 8n) | BigInt(b);
96
+ bits |= 1n << BigInt(char);
97
+ const out = [];
98
+ for (let v = bits; v > 0n; v >>= 8n)
99
+ out.unshift(Number(v & 0xffn));
100
+ // Sign guard: keep the value positive when the top byte's MSB is set.
101
+ if ((out[0] & 0x80) !== 0)
102
+ out.unshift(0);
103
+ return out.reverse();
104
+ }
105
+ /**
106
+ * Builds the 1Sat ordinal inscription for a mined name, locked to
107
+ * ownerScript.
108
+ *
109
+ * @param domain - The mined name
110
+ * @param ownerScript - The owner's locking script (prefix)
111
+ * @returns The inscription locking script
112
+ */
113
+ static buildInscription(domain, ownerScript) {
114
+ return new Script()
115
+ .writeScript(ownerScript)
116
+ .writeOpCode(OP.OP_FALSE)
117
+ .writeOpCode(OP.OP_IF)
118
+ .writeBin(Utils.toArray('ord', 'utf8'))
119
+ .writeOpCode(OP.OP_1)
120
+ .writeBin(Utils.toArray(OPNS_CONTENT_TYPE, 'utf8'))
121
+ .writeOpCode(OP.OP_0)
122
+ .writeBin(Utils.toArray(domain, 'utf8'))
123
+ .writeOpCode(OP.OP_ENDIF)
124
+ .writeOpCode(OP.OP_RETURN)
125
+ .writeBin(Utils.toArray(OPNS_BITCOM, 'utf8'))
126
+ .writeBin(OPNS_GENESIS_BYTES);
127
+ }
128
+ /**
129
+ * Tests whether a nonce solves the proof-of-work for a character: the
130
+ * top OPNS_DIFFICULTY bits of the reversed sha256d(pow ‖ char ‖ nonce)
131
+ * must be zero.
132
+ *
133
+ * @param pow - The node's pow root (32 bytes)
134
+ * @param char - Character byte being mined
135
+ * @param nonce - Candidate nonce (32 bytes)
136
+ * @returns The solution hash if valid, otherwise null
137
+ */
138
+ static testSolution(pow, char, nonce) {
139
+ const preimage = [...pow, char, ...nonce];
140
+ const hash = Hash.sha256(Hash.sha256(preimage));
141
+ const fullBytes = Math.floor(OPNS_DIFFICULTY / 8);
142
+ for (let i = 0; i < fullBytes; i++) {
143
+ if (hash[31 - i] !== 0)
144
+ return null;
145
+ }
146
+ const rem = OPNS_DIFFICULTY % 8;
147
+ if (rem > 0) {
148
+ const mask = (0xff << (8 - rem)) & 0xff;
149
+ if ((hash[31 - fullBytes] & mask) !== 0)
150
+ return null;
151
+ }
152
+ return hash;
153
+ }
154
+ /**
155
+ * Serializes a transaction output (8-byte LE value + varint length +
156
+ * script) as the covenant expects in trailingOutputs.
157
+ *
158
+ * @param satoshis - Output value
159
+ * @param script - Locking script bytes
160
+ * @returns Serialized output bytes
161
+ */
162
+ static buildOutput(satoshis, script) {
163
+ const writer = new Utils.Writer();
164
+ writer.writeUInt64LEBn(new BigNumber(satoshis));
165
+ writer.writeVarIntNum(script.length);
166
+ writer.write(script);
167
+ return writer.toArray();
168
+ }
169
+ /**
170
+ * Builds the keyless covenant unlock for a mined character. The unlock
171
+ * pushes char, nonce, ownerScript, the serialized trailing outputs (those
172
+ * beyond the three mandated by the covenant), and the BIP-143 preimage.
173
+ *
174
+ * @param char - Character byte being mined
175
+ * @param nonce - The winning nonce (32 bytes)
176
+ * @param ownerScript - The owner's locking script for the name
177
+ * @returns Unlock template with sign and estimateLength methods
178
+ */
179
+ static unlock(char, nonce, ownerScript) {
180
+ return {
181
+ sign: async (tx, inputIndex) => {
182
+ const input = tx.inputs[inputIndex];
183
+ const sourceTXID = input.sourceTXID ?? input.sourceTransaction?.id('hex');
184
+ if (!sourceTXID) {
185
+ throw new Error('The input sourceTXID or sourceTransaction is required for signing.');
186
+ }
187
+ const sourceOutput = input.sourceTransaction?.outputs[input.sourceOutputIndex];
188
+ if (!sourceOutput?.satoshis || !sourceOutput.lockingScript) {
189
+ throw new Error('The input sourceTransaction is required for signing the covenant.');
190
+ }
191
+ const preimage = TransactionSignature.format({
192
+ sourceTXID,
193
+ sourceOutputIndex: input.sourceOutputIndex,
194
+ sourceSatoshis: sourceOutput.satoshis,
195
+ transactionVersion: tx.version,
196
+ otherInputs: [],
197
+ inputIndex,
198
+ outputs: tx.outputs,
199
+ inputSequence: input.sequence ?? 0xffffffff,
200
+ subscript: sourceOutput.lockingScript,
201
+ lockTime: tx.lockTime,
202
+ scope: TransactionSignature.SIGHASH_ALL |
203
+ TransactionSignature.SIGHASH_ANYONECANPAY |
204
+ TransactionSignature.SIGHASH_FORKID,
205
+ });
206
+ // Trailing outputs are those beyond the three the covenant mandates.
207
+ const trailing = [];
208
+ for (const out of tx.outputs.slice(3)) {
209
+ trailing.push(...OpNS.buildOutput(out.satoshis ?? 0, (out.lockingScript ?? new Script()).toBinary()));
210
+ }
211
+ return new UnlockingScript()
212
+ .writeBin([char])
213
+ .writeBin(nonce)
214
+ .writeBin(ownerScript.toBinary())
215
+ .writeBin(trailing)
216
+ .writeBin(preimage);
217
+ },
218
+ estimateLength: async (tx, inputIndex) => {
219
+ return (await OpNS.unlock(char, nonce, ownerScript).sign(tx, inputIndex)).toBinary().length;
220
+ },
221
+ };
222
+ }
223
+ }
224
+ //# sourceMappingURL=opns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opns.js","sourceRoot":"","sources":["../../src/opns/opns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EACN,SAAS,EACT,IAAI,EACJ,EAAE,EACF,MAAM,EAEN,oBAAoB,EACpB,eAAe,EACf,KAAK,GACL,MAAM,UAAU,CAAA;AAEjB,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;AAEtE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;AAEpE,yDAAyD;AACzD,MAAM,WAAW,GAAG,mCAAmC,CAAA;AAEvD,yBAAyB;AACzB,MAAM,iBAAiB,GAAG,mBAAmB,CAAA;AAY7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IACxB;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAI,CAAC,OAAiB,EAAE,MAAc,EAAE,GAAa;QAC3D,MAAM,KAAK,GAAG,IAAI,MAAM,EAAE;aACxB,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC;aACzB,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC;aACxB,QAAQ,CAAC,kBAAkB,CAAC;aAC5B,QAAQ,CAAC,OAAO,CAAC;aACjB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aACvC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACf,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;QAEjC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAA;QACjC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtB,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACzC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAEpB,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,mBAAmB,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACxE,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,MAAc;QAC3B,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrD,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,mBAAmB,CAAC,CAAC,CAAC;oBAAE,OAAO,IAAI,CAAA;YACnD,CAAC;YACD,6DAA6D;YAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;YAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAA;YACrC,IAAI,OAAO,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAA;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBAAE,OAAO,IAAI,CAAA;YACtD,CAAC;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAA;YAC9C,OAAO;gBACN,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE;gBACpC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;gBAChC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE;aAChC,CAAA;QACF,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,CAAA;QACZ,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAiB,EAAE,IAAY;QAC9C,IAAI,IAAI,GAAG,EAAE,CAAA;QACb,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE;YAAE,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACvE,IAAI,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;QAE1B,MAAM,GAAG,GAAa,EAAE,CAAA;QACxB,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,EAAE;YAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;QACnE,sEAAsE;QACtE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACzC,OAAO,GAAG,CAAC,OAAO,EAAE,CAAA;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAc,EAAE,WAAmB;QAC1D,OAAO,IAAI,MAAM,EAAE;aACjB,WAAW,CAAC,WAAW,CAAC;aACxB,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC;aACxB,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC;aACrB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;aACtC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC;aACpB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;aAClD,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC;aACpB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aACvC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC;aACxB,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC;aACzB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;aAC5C,QAAQ,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,YAAY,CAClB,GAAa,EACb,IAAY,EACZ,KAAe;QAEf,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC,CAAA;QACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;QACpC,CAAC;QACD,MAAM,GAAG,GAAG,eAAe,GAAG,CAAC,CAAA;QAC/B,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;YACvC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;QACrD,CAAC;QACD,OAAO,IAAI,CAAA;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAAC,QAAgB,EAAE,MAAgB;QACpD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAA;QACjC,MAAM,CAAC,eAAe,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC/C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACpC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACpB,OAAO,MAAM,CAAC,OAAO,EAAE,CAAA;IACxB,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,MAAM,CACZ,IAAY,EACZ,KAAe,EACf,WAAmB;QAKnB,OAAO;YACN,IAAI,EAAE,KAAK,EAAE,EAAe,EAAE,UAAkB,EAAE,EAAE;gBACnD,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACnC,MAAM,UAAU,GACf,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;gBACvD,IAAI,CAAC,UAAU,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CACd,oEAAoE,CACpE,CAAA;gBACF,CAAC;gBACD,MAAM,YAAY,GACjB,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;gBAC1D,IAAI,CAAC,YAAY,EAAE,QAAQ,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;oBAC5D,MAAM,IAAI,KAAK,CACd,mEAAmE,CACnE,CAAA;gBACF,CAAC;gBAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC;oBAC5C,UAAU;oBACV,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;oBAC1C,cAAc,EAAE,YAAY,CAAC,QAAQ;oBACrC,kBAAkB,EAAE,EAAE,CAAC,OAAO;oBAC9B,WAAW,EAAE,EAAE;oBACf,UAAU;oBACV,OAAO,EAAE,EAAE,CAAC,OAAO;oBACnB,aAAa,EAAE,KAAK,CAAC,QAAQ,IAAI,UAAU;oBAC3C,SAAS,EAAE,YAAY,CAAC,aAAa;oBACrC,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,KAAK,EACJ,oBAAoB,CAAC,WAAW;wBAChC,oBAAoB,CAAC,oBAAoB;wBACzC,oBAAoB,CAAC,cAAc;iBACpC,CAAC,CAAA;gBAEF,qEAAqE;gBACrE,MAAM,QAAQ,GAAa,EAAE,CAAA;gBAC7B,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,QAAQ,CAAC,IAAI,CACZ,GAAG,IAAI,CAAC,WAAW,CAClB,GAAG,CAAC,QAAQ,IAAI,CAAC,EACjB,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAC9C,CACD,CAAA;gBACF,CAAC;gBAED,OAAO,IAAI,eAAe,EAAE;qBAC1B,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;qBAChB,QAAQ,CAAC,KAAK,CAAC;qBACf,QAAQ,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;qBAChC,QAAQ,CAAC,QAAQ,CAAC;qBAClB,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACrB,CAAC;YACD,cAAc,EAAE,KAAK,EAAE,EAAe,EAAE,UAAkB,EAAE,EAAE;gBAC7D,OAAO,CACN,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAChE,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAA;YACpB,CAAC;SACD,CAAA;IACF,CAAC;CACD"}
@@ -0,0 +1,29 @@
1
+ /** Inscription content type for shrug token display metadata */
2
+ export declare const SHRUG_METADATA_CONTENT_TYPE = "application/shrug+cbor";
3
+ /**
4
+ * Display metadata carried by an inscription on a token's deploy output.
5
+ * All fields are optional.
6
+ */
7
+ export interface ShrugMetadata {
8
+ /** Token symbol. Uniqueness is not enforced */
9
+ sym?: string;
10
+ /** Icon outpoint as `txid_vout` */
11
+ icon?: string;
12
+ /** Decimal precision 0-18, default 0 */
13
+ dec?: number;
14
+ }
15
+ /** Convert a `txid_vout` outpoint string to its 36-byte wire encoding */
16
+ export declare function outpointToBytes(outpoint: string): number[] | null;
17
+ /** Convert a 36-byte wire outpoint to its `txid_vout` string form */
18
+ export declare function outpointFromBytes(bytes: number[]): string | null;
19
+ /**
20
+ * Encode shrug metadata as a deterministic CBOR map (RFC 8949 §4.2).
21
+ * The icon is encoded as a 36-byte byte string.
22
+ */
23
+ export declare function encodeShrugMetadata(meta: ShrugMetadata): number[];
24
+ /**
25
+ * Decode a shrug metadata document. Unknown map keys are ignored.
26
+ * Returns null when the document is not a valid metadata map.
27
+ */
28
+ export declare function decodeShrugMetadata(content: number[] | Uint8Array): ShrugMetadata | null;
29
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/shrug/metadata.ts"],"names":[],"mappings":"AAIA,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,2BAA2B,CAAA;AAEnE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAgBjE;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAMhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,EAAE,CAmBjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,GAC5B,aAAa,GAAG,IAAI,CAsDtB"}
@@ -0,0 +1,106 @@
1
+ import { Utils } from '@bsv/sdk';
2
+ import { decode as cborDecode, encode as cborEncode } from 'cbor2';
3
+ import { sortCoreDeterministic } from 'cbor2/sorts';
4
+ /** Inscription content type for shrug token display metadata */
5
+ export const SHRUG_METADATA_CONTENT_TYPE = 'application/shrug+cbor';
6
+ /** Convert a `txid_vout` outpoint string to its 36-byte wire encoding */
7
+ export function outpointToBytes(outpoint) {
8
+ if (outpoint.charAt(64) !== '_')
9
+ return null;
10
+ const txid = outpoint.slice(0, 64);
11
+ if (!/^[0-9a-fA-F]{64}$/.test(txid))
12
+ return null;
13
+ const vout = Number(outpoint.slice(65));
14
+ if (!Number.isInteger(vout) || vout < 0 || vout > 0xffffffff) {
15
+ return null;
16
+ }
17
+ const bytes = Utils.toArray(txid, 'hex').reverse();
18
+ bytes.push(vout & 0xff, (vout >>> 8) & 0xff, (vout >>> 16) & 0xff, (vout >>> 24) & 0xff);
19
+ return bytes;
20
+ }
21
+ /** Convert a 36-byte wire outpoint to its `txid_vout` string form */
22
+ export function outpointFromBytes(bytes) {
23
+ if (bytes.length !== 36)
24
+ return null;
25
+ const txid = Utils.toHex(bytes.slice(0, 32).reverse());
26
+ const vout = (bytes[32] | (bytes[33] << 8) | (bytes[34] << 16) | (bytes[35] << 24)) >>> 0;
27
+ return `${txid}_${vout}`;
28
+ }
29
+ /**
30
+ * Encode shrug metadata as a deterministic CBOR map (RFC 8949 §4.2).
31
+ * The icon is encoded as a 36-byte byte string.
32
+ */
33
+ export function encodeShrugMetadata(meta) {
34
+ const wire = {};
35
+ if (meta.sym !== undefined) {
36
+ wire.sym = meta.sym;
37
+ }
38
+ if (meta.dec !== undefined) {
39
+ if (!Number.isInteger(meta.dec) || meta.dec < 0 || meta.dec > 18) {
40
+ throw new Error(`dec ${meta.dec} out of range 0-18`);
41
+ }
42
+ wire.dec = meta.dec;
43
+ }
44
+ if (meta.icon !== undefined) {
45
+ const bytes = outpointToBytes(meta.icon);
46
+ if (!bytes) {
47
+ throw new Error(`invalid icon outpoint: ${meta.icon}`);
48
+ }
49
+ wire.icon = new Uint8Array(bytes);
50
+ }
51
+ return Array.from(cborEncode(wire, { sortKeys: sortCoreDeterministic }));
52
+ }
53
+ /**
54
+ * Decode a shrug metadata document. Unknown map keys are ignored.
55
+ * Returns null when the document is not a valid metadata map.
56
+ */
57
+ export function decodeShrugMetadata(content) {
58
+ let value;
59
+ try {
60
+ value = cborDecode(content instanceof Uint8Array ? content : new Uint8Array(content));
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ let get;
66
+ if (value instanceof Map) {
67
+ get = (key) => value.get(key);
68
+ }
69
+ else if (typeof value === 'object' &&
70
+ value !== null &&
71
+ !Array.isArray(value)) {
72
+ get = (key) => value[key];
73
+ }
74
+ else {
75
+ return null;
76
+ }
77
+ const meta = {};
78
+ const sym = get('sym');
79
+ if (sym !== undefined) {
80
+ if (typeof sym !== 'string')
81
+ return null;
82
+ meta.sym = sym;
83
+ }
84
+ const dec = get('dec');
85
+ if (dec !== undefined) {
86
+ const num = typeof dec === 'bigint' ? Number(dec) : dec;
87
+ if (typeof num !== 'number' ||
88
+ !Number.isInteger(num) ||
89
+ num < 0 ||
90
+ num > 18) {
91
+ return null;
92
+ }
93
+ meta.dec = num;
94
+ }
95
+ const icon = get('icon');
96
+ if (icon !== undefined) {
97
+ if (!(icon instanceof Uint8Array))
98
+ return null;
99
+ const outpoint = outpointFromBytes(Array.from(icon));
100
+ if (!outpoint)
101
+ return null;
102
+ meta.icon = outpoint;
103
+ }
104
+ return meta;
105
+ }
106
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/shrug/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAChC,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,OAAO,CAAA;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,gEAAgE;AAChE,MAAM,CAAC,MAAM,2BAA2B,GAAG,wBAAwB,CAAA;AAenE,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC/C,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAClC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAA;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAA;IAClD,KAAK,CAAC,IAAI,CACT,IAAI,GAAG,IAAI,EACX,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,EACnB,CAAC,IAAI,KAAK,EAAE,CAAC,GAAG,IAAI,EACpB,CAAC,IAAI,KAAK,EAAE,CAAC,GAAG,IAAI,CACpB,CAAA;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,KAAe;IAChD,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACtD,MAAM,IAAI,GACT,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IAC7E,OAAO,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAmB;IACtD,MAAM,IAAI,GAA4B,EAAE,CAAA;IACxC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IACpB,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,GAAG,oBAAoB,CAAC,CAAA;QACrD,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;IACpB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAAA;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAClC,OAA8B;IAE9B,IAAI,KAAc,CAAA;IAClB,IAAI,CAAC;QACJ,KAAK,GAAG,UAAU,CACjB,OAAO,YAAY,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CACjE,CAAA;IACF,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,IAAI,GAA6B,CAAA;IACjC,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;QAC1B,GAAG,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;SAAM,IACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,CAAC;QACF,GAAG,GAAG,CAAC,GAAG,EAAE,EAAE,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAA;IACvD,CAAC;SAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,MAAM,IAAI,GAAkB,EAAE,CAAA;IAE9B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IACtB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACxC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;IACf,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IACtB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACvD,IACC,OAAO,GAAG,KAAK,QAAQ;YACvB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;YACtB,GAAG,GAAG,CAAC;YACP,GAAG,GAAG,EAAE,EACP,CAAC;YACF,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;IACf,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACpD,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;IACrB,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { LockingScript, Script } from '@bsv/sdk';
2
+ import Inscription from '../inscription/inscription.js';
3
+ import { type ShrugMetadata } from './metadata.js';
4
+ /** The 13-byte UTF-8 shrug tag ¯\_(ツ)_/¯ */
5
+ export declare const SHRUG_TAG_HEX = "c2af5c5f28e38384295f2fc2af";
6
+ /**
7
+ * Decoded shrug token output.
8
+ *
9
+ * Wire format:
10
+ * `<push tag> <push 36-byte id | OP_0> OP_2DROP <push amount | OP_0> OP_DROP <owner script>`
11
+ */
12
+ export interface ShrugData {
13
+ /** Token id `txid_vout`; absent on deploy outputs (the id is the output's own outpoint) */
14
+ id?: string;
15
+ /** 0n = mint authority, >0n = token value; arbitrary precision */
16
+ amount: bigint;
17
+ /** Script following the prefix (owner script, possibly with an inscription envelope) */
18
+ scriptSuffix: number[];
19
+ /** Inscription found in the suffix, if any */
20
+ insc?: Inscription;
21
+ /** Populated when the suffix inscription carries application/shrug+cbor */
22
+ metadata?: ShrugMetadata;
23
+ }
24
+ /**
25
+ * Shrug token template: a binary evolution of BSV-21 encoding token data as
26
+ * a stack-neutral prefix of raw pushes at the front of the locking script.
27
+ */
28
+ export default class Shrug {
29
+ /** Token id `txid_vout`; omit for deploy outputs */
30
+ readonly id?: string;
31
+ /** 0n = mint authority, >0n = token value */
32
+ readonly amount: bigint;
33
+ constructor(token?: {
34
+ id?: string;
35
+ amount?: bigint;
36
+ });
37
+ /**
38
+ * Decode a shrug output from a locking script.
39
+ *
40
+ * Runs the inscription decoder on the script suffix; an
41
+ * application/shrug+cbor inscription populates `metadata`. Malformed
42
+ * metadata does not invalidate the token output.
43
+ */
44
+ static decode(script: Script): ShrugData | null;
45
+ /**
46
+ * Build a shrug locking script.
47
+ *
48
+ * @param suffix - owner locking script, optionally preceded by an inscription envelope
49
+ */
50
+ lock(suffix?: Script | LockingScript): LockingScript;
51
+ }
52
+ //# sourceMappingURL=shrug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shrug.d.ts","sourceRoot":"","sources":["../../src/shrug/shrug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAM,MAAM,EAAS,MAAM,UAAU,CAAA;AAC3D,OAAO,WAAW,MAAM,+BAA+B,CAAA;AACvD,OAAO,EAEN,KAAK,aAAa,EAIlB,MAAM,eAAe,CAAA;AAEtB,4CAA4C;AAC5C,eAAO,MAAM,aAAa,+BAA+B,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,2FAA2F;IAC3F,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,wFAAwF;IACxF,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,aAAa,CAAA;CACxB;AAkCD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,KAAK;IACzB,oDAAoD;IACpD,SAAgB,EAAE,CAAC,EAAE,MAAM,CAAA;IAC3B,6CAA6C;IAC7C,SAAgB,MAAM,EAAE,MAAM,CAAA;gBAElB,KAAK,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAQxD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IA0C/C;;;;OAIG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa;CAmCpD"}
@@ -0,0 +1,137 @@
1
+ import { LockingScript, OP, Script, Utils } from '@bsv/sdk';
2
+ import Inscription from '../inscription/inscription.js';
3
+ import { SHRUG_METADATA_CONTENT_TYPE, decodeShrugMetadata, outpointFromBytes, outpointToBytes, } from './metadata.js';
4
+ /** The 13-byte UTF-8 shrug tag ¯\_(ツ)_/¯ */
5
+ export const SHRUG_TAG_HEX = 'c2af5c5f28e38384295f2fc2af';
6
+ /** Encode a non-negative bigint as a minimal Bitcoin script number (little-endian) */
7
+ function encodeScriptNum(n) {
8
+ const bytes = [];
9
+ let v = n;
10
+ while (v > 0n) {
11
+ bytes.push(Number(v & 0xffn));
12
+ v >>= 8n;
13
+ }
14
+ if (bytes.length > 0 && (bytes[bytes.length - 1] & 0x80) !== 0) {
15
+ bytes.push(0x00);
16
+ }
17
+ return bytes;
18
+ }
19
+ /** Decode a minimal Bitcoin script number. Returns null for non-minimal encodings */
20
+ function decodeScriptNum(data) {
21
+ if (data.length === 0)
22
+ return 0n;
23
+ const last = data[data.length - 1];
24
+ if ((last & 0x7f) === 0 &&
25
+ (data.length === 1 || (data[data.length - 2] & 0x80) === 0)) {
26
+ return null;
27
+ }
28
+ let v = 0n;
29
+ for (let i = data.length - 1; i >= 0; i--) {
30
+ const byte = i === data.length - 1 ? data[i] & 0x7f : data[i];
31
+ v = (v << 8n) | BigInt(byte);
32
+ }
33
+ return (last & 0x80) !== 0 ? -v : v;
34
+ }
35
+ /**
36
+ * Shrug token template: a binary evolution of BSV-21 encoding token data as
37
+ * a stack-neutral prefix of raw pushes at the front of the locking script.
38
+ */
39
+ export default class Shrug {
40
+ /** Token id `txid_vout`; omit for deploy outputs */
41
+ id;
42
+ /** 0n = mint authority, >0n = token value */
43
+ amount;
44
+ constructor(token = {}) {
45
+ if (token.amount !== undefined && token.amount < 0n) {
46
+ throw new Error('amount must be non-negative');
47
+ }
48
+ this.id = token.id;
49
+ this.amount = token.amount ?? 0n;
50
+ }
51
+ /**
52
+ * Decode a shrug output from a locking script.
53
+ *
54
+ * Runs the inscription decoder on the script suffix; an
55
+ * application/shrug+cbor inscription populates `metadata`. Malformed
56
+ * metadata does not invalidate the token output.
57
+ */
58
+ static decode(script) {
59
+ const chunks = script.chunks;
60
+ if (chunks.length < 5)
61
+ return null;
62
+ const [tag, idChunk, twoDrop, amountChunk, drop] = chunks;
63
+ if (!tag.data || Utils.toHex(tag.data) !== SHRUG_TAG_HEX)
64
+ return null;
65
+ let id;
66
+ if (idChunk.op > OP.OP_PUSHDATA4)
67
+ return null;
68
+ if (idChunk.data && idChunk.data.length === 36) {
69
+ id = outpointFromBytes(idChunk.data) ?? undefined;
70
+ if (!id)
71
+ return null;
72
+ }
73
+ else if (idChunk.data && idChunk.data.length !== 0) {
74
+ return null;
75
+ }
76
+ if (twoDrop.op !== OP.OP_2DROP)
77
+ return null;
78
+ if (amountChunk.op > OP.OP_PUSHDATA4)
79
+ return null;
80
+ const amount = decodeScriptNum(amountChunk.data ?? []);
81
+ if (amount === null || amount < 0n)
82
+ return null;
83
+ if (drop.op !== OP.OP_DROP)
84
+ return null;
85
+ const suffix = new Script(chunks.slice(5));
86
+ const data = {
87
+ id,
88
+ amount,
89
+ scriptSuffix: suffix.toBinary(),
90
+ };
91
+ const insc = Inscription.decode(suffix);
92
+ if (insc) {
93
+ data.insc = insc;
94
+ if (insc.file.type === SHRUG_METADATA_CONTENT_TYPE) {
95
+ data.metadata = decodeShrugMetadata(insc.file.content) ?? undefined;
96
+ }
97
+ }
98
+ return data;
99
+ }
100
+ /**
101
+ * Build a shrug locking script.
102
+ *
103
+ * @param suffix - owner locking script, optionally preceded by an inscription envelope
104
+ */
105
+ lock(suffix) {
106
+ const chunks = [
107
+ { op: 13, data: Utils.toArray(SHRUG_TAG_HEX, 'hex') },
108
+ ];
109
+ if (this.id !== undefined) {
110
+ const idBytes = outpointToBytes(this.id);
111
+ if (!idBytes) {
112
+ throw new Error(`invalid token id outpoint: ${this.id}`);
113
+ }
114
+ chunks.push({ op: 36, data: idBytes });
115
+ }
116
+ else {
117
+ chunks.push({ op: OP.OP_0 });
118
+ }
119
+ chunks.push({ op: OP.OP_2DROP });
120
+ if (this.amount > 0n) {
121
+ const amountBytes = encodeScriptNum(this.amount);
122
+ chunks.push({
123
+ op: amountBytes.length <= 75 ? amountBytes.length : OP.OP_PUSHDATA1,
124
+ data: amountBytes,
125
+ });
126
+ }
127
+ else {
128
+ chunks.push({ op: OP.OP_0 });
129
+ }
130
+ chunks.push({ op: OP.OP_DROP });
131
+ if (suffix) {
132
+ chunks.push(...suffix.chunks);
133
+ }
134
+ return new LockingScript(chunks);
135
+ }
136
+ }
137
+ //# sourceMappingURL=shrug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shrug.js","sourceRoot":"","sources":["../../src/shrug/shrug.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1sat/templates",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Bitcoin script templates for 1Sat Ordinals SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,7 +32,8 @@
32
32
  ],
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
- "@1sat/types": "0.0.30"
35
+ "@1sat/types": "0.0.33",
36
+ "cbor2": "^2.3.0"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "@bsv/sdk": "^2.0.13"