@sig-net/midnight 0.0.1

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.
Files changed (90) hide show
  1. package/README.md +20 -0
  2. package/dist/constants.d.ts +62 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +83 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/epsilon-derivation.d.ts +32 -0
  7. package/dist/epsilon-derivation.d.ts.map +1 -0
  8. package/dist/epsilon-derivation.js +54 -0
  9. package/dist/epsilon-derivation.js.map +1 -0
  10. package/dist/index.d.ts +26 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +30 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/managed/compiler/contract-info.json +165 -0
  15. package/dist/managed/compiler/contract-manifest.json +32 -0
  16. package/dist/managed/contract/index.d.ts +65 -0
  17. package/dist/managed/contract/index.js +611 -0
  18. package/dist/managed/contract/index.js.map +8 -0
  19. package/dist/schnorr.d.ts +100 -0
  20. package/dist/schnorr.d.ts.map +1 -0
  21. package/dist/schnorr.js +144 -0
  22. package/dist/schnorr.js.map +1 -0
  23. package/dist/signature-requests-state-reader.d.ts +74 -0
  24. package/dist/signature-requests-state-reader.d.ts.map +1 -0
  25. package/dist/signature-requests-state-reader.js +167 -0
  26. package/dist/signature-requests-state-reader.js.map +1 -0
  27. package/dist/signature-response-verification.d.ts +27 -0
  28. package/dist/signature-response-verification.d.ts.map +1 -0
  29. package/dist/signature-response-verification.js +45 -0
  30. package/dist/signature-response-verification.js.map +1 -0
  31. package/dist/signature-state-reading.d.ts +36 -0
  32. package/dist/signature-state-reading.d.ts.map +1 -0
  33. package/dist/signature-state-reading.js +62 -0
  34. package/dist/signature-state-reading.js.map +1 -0
  35. package/dist/signet-contract-state-reader.d.ts +146 -0
  36. package/dist/signet-contract-state-reader.d.ts.map +1 -0
  37. package/dist/signet-contract-state-reader.js +226 -0
  38. package/dist/signet-contract-state-reader.js.map +1 -0
  39. package/dist/signet-event-observer.d.ts +102 -0
  40. package/dist/signet-event-observer.d.ts.map +1 -0
  41. package/dist/signet-event-observer.js +127 -0
  42. package/dist/signet-event-observer.js.map +1 -0
  43. package/dist/signet-events.d.ts +175 -0
  44. package/dist/signet-events.d.ts.map +1 -0
  45. package/dist/signet-events.js +210 -0
  46. package/dist/signet-events.js.map +1 -0
  47. package/dist/signet-request-feed.d.ts +78 -0
  48. package/dist/signet-request-feed.d.ts.map +1 -0
  49. package/dist/signet-request-feed.js +116 -0
  50. package/dist/signet-request-feed.js.map +1 -0
  51. package/dist/signet-request-resolver.d.ts +58 -0
  52. package/dist/signet-request-resolver.d.ts.map +1 -0
  53. package/dist/signet-request-resolver.js +76 -0
  54. package/dist/signet-request-resolver.js.map +1 -0
  55. package/dist/signet-request-response-reader.d.ts +160 -0
  56. package/dist/signet-request-response-reader.d.ts.map +1 -0
  57. package/dist/signet-request-response-reader.js +198 -0
  58. package/dist/signet-request-response-reader.js.map +1 -0
  59. package/dist/signet-requests.d.ts +363 -0
  60. package/dist/signet-requests.d.ts.map +1 -0
  61. package/dist/signet-requests.js +497 -0
  62. package/dist/signet-requests.js.map +1 -0
  63. package/dist/signet-response-feed.d.ts +161 -0
  64. package/dist/signet-response-feed.d.ts.map +1 -0
  65. package/dist/signet-response-feed.js +234 -0
  66. package/dist/signet-response-feed.js.map +1 -0
  67. package/package.json +47 -0
  68. package/src/Schnorr.compact +63 -0
  69. package/src/Signet.compact +529 -0
  70. package/src/circuits.compact +36 -0
  71. package/src/constants.ts +97 -0
  72. package/src/epsilon-derivation.ts +62 -0
  73. package/src/index.ts +31 -0
  74. package/src/managed/compiler/contract-info.json +165 -0
  75. package/src/managed/compiler/contract-manifest.json +32 -0
  76. package/src/managed/contract/index.d.ts +65 -0
  77. package/src/managed/contract/index.js +611 -0
  78. package/src/managed/contract/index.js.map +8 -0
  79. package/src/schnorr.ts +210 -0
  80. package/src/signature-requests-state-reader.ts +223 -0
  81. package/src/signature-response-verification.ts +64 -0
  82. package/src/signature-state-reading.ts +87 -0
  83. package/src/signet-contract-state-reader.ts +391 -0
  84. package/src/signet-event-observer.ts +186 -0
  85. package/src/signet-events.ts +337 -0
  86. package/src/signet-request-feed.ts +158 -0
  87. package/src/signet-request-resolver.ts +116 -0
  88. package/src/signet-request-response-reader.ts +324 -0
  89. package/src/signet-requests.ts +737 -0
  90. package/src/signet-response-feed.ts +325 -0
@@ -0,0 +1,100 @@
1
+ import { type JubjubPoint } from "@midnight-ntwrk/compact-runtime";
2
+ export type { JubjubPoint } from "@midnight-ntwrk/compact-runtime";
3
+ /** Jubjub curve scalar field order (group order of the generator). */
4
+ export declare const JUBJUB_ORDER = 6554484396890773809930967563523245729705921265872317281365359162392183254199n;
5
+ /** BLS12-381 scalar field order (the Compact `Field` type modulus). */
6
+ export declare const BLS_ORDER = 52435875175126190479447740508185965837690552500527637822603658699938581184513n;
7
+ /**
8
+ * Convert little-endian bytes to a bigint. Matches Compact's
9
+ * `Bytes<32> as Field` interpretation (and the MPC monitor's ABI-word
10
+ * decoding convention).
11
+ *
12
+ * @param bytes - Little-endian byte array.
13
+ * @returns The decoded non-negative integer.
14
+ */
15
+ export declare function bytesToBigint(bytes: Uint8Array): bigint;
16
+ /**
17
+ * Convert a bigint to exactly 32 little-endian bytes. Matches Compact's
18
+ * `Field as Bytes<32>` encoding (the inverse of {@link bytesToBigint});
19
+ * negative inputs are interpreted in the BLS scalar field.
20
+ *
21
+ * @param n - The integer to encode.
22
+ * @returns The 32-byte little-endian encoding.
23
+ */
24
+ export declare function bigintToBytes32(n: bigint): Uint8Array;
25
+ /** A Jubjub keypair: the secret scalar and its public curve point. */
26
+ export interface JubjubKeypair {
27
+ /** Secret scalar in `[1, JUBJUB_ORDER - 1]`. */
28
+ sk: bigint;
29
+ /** Public key: `sk * G` on Jubjub. */
30
+ pk: JubjubPoint;
31
+ }
32
+ /**
33
+ * Derive a Jubjub keypair from a seed — the same derivation the MPC server
34
+ * performs on its root key, so this MUST stay bit-identical to it:
35
+ * `sk = (persistentHash([pad32("jubjub:auth:"), seed]) mod (order - 1)) + 1`,
36
+ * `pk = sk * G`.
37
+ *
38
+ * @param seed - Seed bytes (e.g. the 32-byte MPC root key).
39
+ * @returns The derived {@link JubjubKeypair}.
40
+ */
41
+ export declare function deriveJubjubKeypair(seed: Uint8Array): JubjubKeypair;
42
+ /**
43
+ * A Schnorr signature (TS twin of CompactStandardLibrary's
44
+ * `JubjubSchnorrSignature`).
45
+ */
46
+ export interface SchnorrSignature {
47
+ /** Nonce commitment R = k * G. */
48
+ announcement: JubjubPoint;
49
+ /** Signature scalar s = (k + c * sk) mod JUBJUB_ORDER. */
50
+ response: bigint;
51
+ }
52
+ /**
53
+ * Computes the Schnorr challenge (the Poseidon transientHash output reduced
54
+ * into Jubjub's scalar field, exactly as `jubjubSchnorrVerify` computes it).
55
+ * ALWAYS inject the compiled circuit — signet-midnight's own
56
+ * `pureCircuits.schnorrChallenge` — never a TS re-implementation; keeping it
57
+ * injected keeps this signer decoupled from any one compiled artifact.
58
+ */
59
+ export type SchnorrChallengeFn = (annX: bigint, annY: bigint, pkX: bigint, pkY: bigint, msg: bigint[]) => bigint;
60
+ /**
61
+ * Sign a message with Schnorr on Jubjub, matching CompactStandardLibrary's
62
+ * `jubjubSchnorrVerify`: `c = challenge` (already reduced into Jubjub's
63
+ * scalar field by the compiled circuit), `s = (k + c * sk) mod JUBJUB_ORDER`.
64
+ * For signet attestations the message is the compiled
65
+ * `pureCircuits.signetAttestationMessage(requestId, outputData)`.
66
+ *
67
+ * @param sk - Jubjub private key scalar.
68
+ * @param msg - Message field limbs.
69
+ * @param schnorrChallenge - The compiled `pureCircuits.schnorrChallenge`.
70
+ * @returns The signature (announcement R, response s).
71
+ * @throws Error if `sk` reduces to zero mod the Jubjub order.
72
+ */
73
+ export declare function schnorrSign(sk: bigint, msg: bigint[], schnorrChallenge: SchnorrChallengeFn): SchnorrSignature;
74
+ /**
75
+ * Hash a Jubjub point exactly as the circuits do (`persistentHash<JubjubPoint>`)
76
+ * — the form the signet contract seals as `mpcPubKeyHash`.
77
+ *
78
+ * @param point - The point to hash.
79
+ * @returns The 32-byte hash.
80
+ */
81
+ export declare function hashJubjubPoint(point: JubjubPoint): Uint8Array;
82
+ /**
83
+ * Parse a Jubjub public key from its `"x,y"` config/env form (decimal or
84
+ * 0x-hex field coordinates) — how deploys receive `MPC_JUBJUB_PK`.
85
+ *
86
+ * @param value - The `"x,y"` string.
87
+ * @returns The parsed point.
88
+ * @throws Error if the value is not two comma-separated field coordinates.
89
+ */
90
+ export declare function parseJubjubPublicKey(value: string): JubjubPoint;
91
+ /**
92
+ * Format a Jubjub public key as the `"x,y"` decimal config/env form that
93
+ * {@link parseJubjubPublicKey} accepts — the round-trip inverse, for handing
94
+ * a derived key to deploys as `MPC_JUBJUB_PK`.
95
+ *
96
+ * @param point - The point to format.
97
+ * @returns The `"x,y"` string with decimal coordinates.
98
+ */
99
+ export declare function formatJubjubPublicKey(point: JubjubPoint): string;
100
+ //# sourceMappingURL=schnorr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schnorr.d.ts","sourceRoot":"","sources":["../src/schnorr.ts"],"names":[],"mappings":"AAiBA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,iCAAiC,CAAC;AAKzC,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,sEAAsE;AACtE,eAAO,MAAM,YAAY,gFAAgF,CAAC;AAE1G,uEAAuE;AACvE,eAAO,MAAM,SAAS,iFAAiF,CAAC;AAKxG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAQrD;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,EAAE,EAAE,WAAW,CAAC;CACjB;AASD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,aAAa,CAKnE;AAID;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,YAAY,EAAE,WAAW,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EAAE,KACV,MAAM,CAAC;AAEZ;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EAAE,EACb,gBAAgB,EAAE,kBAAkB,GACnC,gBAAgB,CAgBlB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,CAE9D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAU/D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,144 @@
1
+ // Jubjub Schnorr helpers — the TS side of the shared Schnorr.compact module:
2
+ // key derivation, SIGNING (which needs the secret scalar, so it cannot be a
3
+ // circuit), and key parsing/hashing. Everything provable stays in Compact:
4
+ // the challenge is the COMPILED `pureCircuits.schnorrChallenge`, injected by
5
+ // callers (see SchnorrChallengeFn), and the attestation message is the
6
+ // compiled `pureCircuits.signetAttestationMessage` — this file never
7
+ // re-implements either. Verification lives in circuits only
8
+ // (CompactStandardLibrary's jubjubSchnorrVerify, run by the signet contract
9
+ // at post time).
10
+ //
11
+ // This belongs in github.com/sig-net/signet.js as its Midnight adapter —
12
+ // kept here until upstreamed. The math is Midnight-specific (Jubjub embedded
13
+ // in BLS12-381 via @midnight-ntwrk/compact-runtime EC ops), which is exactly
14
+ // why signet.js does not cover it today.
15
+ import { randomBytes } from "node:crypto";
16
+ import { CompactTypeBytes, CompactTypeJubjubPoint, CompactTypeVector, ecMulGenerator, persistentHash, } from "@midnight-ntwrk/compact-runtime";
17
+ /** Jubjub curve scalar field order (group order of the generator). */
18
+ export const JUBJUB_ORDER = 6554484396890773809930967563523245729705921265872317281365359162392183254199n;
19
+ /** BLS12-381 scalar field order (the Compact `Field` type modulus). */
20
+ export const BLS_ORDER = 52435875175126190479447740508185965837690552500527637822603658699938581184513n;
21
+ const bytes32Type = new CompactTypeBytes(32);
22
+ const vec2x32Type = new CompactTypeVector(2, bytes32Type);
23
+ /**
24
+ * Convert little-endian bytes to a bigint. Matches Compact's
25
+ * `Bytes<32> as Field` interpretation (and the MPC monitor's ABI-word
26
+ * decoding convention).
27
+ *
28
+ * @param bytes - Little-endian byte array.
29
+ * @returns The decoded non-negative integer.
30
+ */
31
+ export function bytesToBigint(bytes) {
32
+ let result = 0n;
33
+ for (let i = bytes.length - 1; i >= 0; i--) {
34
+ result = (result << 8n) | BigInt(bytes[i]);
35
+ }
36
+ return result;
37
+ }
38
+ /**
39
+ * Convert a bigint to exactly 32 little-endian bytes. Matches Compact's
40
+ * `Field as Bytes<32>` encoding (the inverse of {@link bytesToBigint});
41
+ * negative inputs are interpreted in the BLS scalar field.
42
+ *
43
+ * @param n - The integer to encode.
44
+ * @returns The 32-byte little-endian encoding.
45
+ */
46
+ export function bigintToBytes32(n) {
47
+ const buf = new Uint8Array(32);
48
+ let v = n < 0n ? n + BLS_ORDER : n;
49
+ for (let i = 0; i < 32; i++) {
50
+ buf[i] = Number(v & 0xffn);
51
+ v >>= 8n;
52
+ }
53
+ return buf;
54
+ }
55
+ /** Zero-pad an ASCII domain tag to 32 bytes (Compact `pad(32, ...)`). */
56
+ function pad32(tag) {
57
+ const padded = new Uint8Array(32);
58
+ new TextEncoder().encodeInto(tag, padded);
59
+ return padded;
60
+ }
61
+ /**
62
+ * Derive a Jubjub keypair from a seed — the same derivation the MPC server
63
+ * performs on its root key, so this MUST stay bit-identical to it:
64
+ * `sk = (persistentHash([pad32("jubjub:auth:"), seed]) mod (order - 1)) + 1`,
65
+ * `pk = sk * G`.
66
+ *
67
+ * @param seed - Seed bytes (e.g. the 32-byte MPC root key).
68
+ * @returns The derived {@link JubjubKeypair}.
69
+ */
70
+ export function deriveJubjubKeypair(seed) {
71
+ const skBytes = persistentHash(vec2x32Type, [pad32("jubjub:auth:"), seed]);
72
+ const sk = (bytesToBigint(skBytes) % (JUBJUB_ORDER - 1n)) + 1n;
73
+ const pk = ecMulGenerator(sk);
74
+ return { sk, pk };
75
+ }
76
+ /**
77
+ * Sign a message with Schnorr on Jubjub, matching CompactStandardLibrary's
78
+ * `jubjubSchnorrVerify`: `c = challenge` (already reduced into Jubjub's
79
+ * scalar field by the compiled circuit), `s = (k + c * sk) mod JUBJUB_ORDER`.
80
+ * For signet attestations the message is the compiled
81
+ * `pureCircuits.signetAttestationMessage(requestId, outputData)`.
82
+ *
83
+ * @param sk - Jubjub private key scalar.
84
+ * @param msg - Message field limbs.
85
+ * @param schnorrChallenge - The compiled `pureCircuits.schnorrChallenge`.
86
+ * @returns The signature (announcement R, response s).
87
+ * @throws Error if `sk` reduces to zero mod the Jubjub order.
88
+ */
89
+ export function schnorrSign(sk, msg, schnorrChallenge) {
90
+ const skReduced = ((sk % JUBJUB_ORDER) + JUBJUB_ORDER) % JUBJUB_ORDER;
91
+ if (skReduced === 0n) {
92
+ throw new Error("Private key must be non-zero mod JUBJUB_ORDER");
93
+ }
94
+ const pk = ecMulGenerator(skReduced);
95
+ const k = (bytesToBigint(randomBytes(32)) % JUBJUB_ORDER) || 1n;
96
+ const announcement = ecMulGenerator(k);
97
+ // schnorrChallenge returns the challenge already reduced into Jubjub's
98
+ // scalar field — use it as-is.
99
+ const c = schnorrChallenge(announcement.x, announcement.y, pk.x, pk.y, msg);
100
+ const response = (((k + c * skReduced) % JUBJUB_ORDER) + JUBJUB_ORDER) % JUBJUB_ORDER;
101
+ return { announcement, response };
102
+ }
103
+ /**
104
+ * Hash a Jubjub point exactly as the circuits do (`persistentHash<JubjubPoint>`)
105
+ * — the form the signet contract seals as `mpcPubKeyHash`.
106
+ *
107
+ * @param point - The point to hash.
108
+ * @returns The 32-byte hash.
109
+ */
110
+ export function hashJubjubPoint(point) {
111
+ return persistentHash(CompactTypeJubjubPoint, point);
112
+ }
113
+ /**
114
+ * Parse a Jubjub public key from its `"x,y"` config/env form (decimal or
115
+ * 0x-hex field coordinates) — how deploys receive `MPC_JUBJUB_PK`.
116
+ *
117
+ * @param value - The `"x,y"` string.
118
+ * @returns The parsed point.
119
+ * @throws Error if the value is not two comma-separated field coordinates.
120
+ */
121
+ export function parseJubjubPublicKey(value) {
122
+ const parts = value.split(",").map((part) => part.trim());
123
+ if (parts.length !== 2 || parts.some((part) => part === "")) {
124
+ throw new Error(`expected a Jubjub public key as "x,y"; got "${value}"`);
125
+ }
126
+ try {
127
+ return { x: BigInt(parts[0]), y: BigInt(parts[1]) };
128
+ }
129
+ catch {
130
+ throw new Error(`Jubjub public key coordinates must be decimal or 0x-hex integers; got "${value}"`);
131
+ }
132
+ }
133
+ /**
134
+ * Format a Jubjub public key as the `"x,y"` decimal config/env form that
135
+ * {@link parseJubjubPublicKey} accepts — the round-trip inverse, for handing
136
+ * a derived key to deploys as `MPC_JUBJUB_PK`.
137
+ *
138
+ * @param point - The point to format.
139
+ * @returns The `"x,y"` string with decimal coordinates.
140
+ */
141
+ export function formatJubjubPublicKey(point) {
142
+ return `${point.x},${point.y}`;
143
+ }
144
+ //# sourceMappingURL=schnorr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schnorr.js","sourceRoot":"","sources":["../src/schnorr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { type RequestIdHex, type SignBidirectionalRequest, type SignBidirectionalRequestIndex } from "./signet-requests.ts";
2
+ import { type RawContractState } from "./signature-state-reading.ts";
3
+ /** Signet layout convention: the request index is ledger field 0. */
4
+ export declare const SIGNET_REQUESTS_INDEX_FIELD = 0;
5
+ /** Signet layout convention: the request counter (`SignetNonce`) is ledger field 1. */
6
+ export declare const SIGNET_NONCE_FIELD = 1;
7
+ /**
8
+ * Aligned-value entry count of a request record EXCLUDING the capacity-scaled
9
+ * vectors: requestNonce (1) + txParamType (1, enums are one atom whatever
10
+ * their byte width) + the EVMType2TxParams fixed fields (to..value = 7,
11
+ * accessListEntryCount = 1) + the calldata Maybe's is_some (1), selector (1)
12
+ * and noWords (1) + the routing fields caip2Id..respondSerializationSchema (8).
13
+ * A stored request cell therefore holds
14
+ * `REQUEST_FIXED_VALUE_ATOMS + maxCalldataWords
15
+ * + maxAccessListEntries·(2 + maxStorageKeysPerEntry)`
16
+ * entries (each calldata word is one Bytes<32> atom; each access-list entry is
17
+ * address + storageKeyCount + its keys).
18
+ */
19
+ export declare const REQUEST_FIXED_VALUE_ATOMS = 21;
20
+ /**
21
+ * The decoded signet ledger fields of a conforming contract — the complete
22
+ * view the MPC needs: the request index (field 0) and the request counter
23
+ * (field 1, Compact `SignetNonce`), whose value doubles as a cheap
24
+ * change-detection signal (unchanged nonce ⇒ no new requests).
25
+ */
26
+ export interface SignetRequestsLedger {
27
+ /** The request counter (ledger field {@link SIGNET_NONCE_FIELD}). */
28
+ nonce: bigint;
29
+ /**
30
+ * The request index (ledger field {@link SIGNET_REQUESTS_INDEX_FIELD}),
31
+ * keyed by hex request id.
32
+ */
33
+ requestsIndex: SignBidirectionalRequestIndex;
34
+ }
35
+ /**
36
+ * MPC-style read: parse the signet ledger fields out of raw contract state
37
+ * by field position alone — no compiled contract, no generated `ledger()`,
38
+ * only the signet layout convention and the canonical descriptors from
39
+ * signet-requests.ts.
40
+ *
41
+ * @param raw - Raw contract state, e.g. `queryContractState(address).data`
42
+ * from the indexer or `ctx.currentQueryContext.state` from the simulator.
43
+ * @returns The decoded {@link SignetRequestsLedger}.
44
+ * @throws Error if a field is missing, has the wrong state-value shape, or a
45
+ * record matches no capacity split.
46
+ */
47
+ export declare function readSignetRequestsLedgerFromState(raw: RawContractState): SignetRequestsLedger;
48
+ /**
49
+ * Look up ONE request by id in a contract's request index at an arbitrary
50
+ * ledger field — the generalization of {@link readSignetRequestsLedgerFromState}
51
+ * the event path needs: a `SignBidirectionalEvent` names both the requester
52
+ * contract AND which field holds its index, so the field is no longer assumed
53
+ * to be {@link SIGNET_REQUESTS_INDEX_FIELD}.
54
+ *
55
+ * This is the mandatory membership check of the event flow (see
56
+ * signet-request-resolver.ts): `undefined` means the id is NOT a member of the
57
+ * index at `fieldIndex` — the notification is forged, stale, points at the
58
+ * wrong field, or the request is not yet indexed — and the caller MUST drop it.
59
+ * Every non-membership case (field out of range, field is not a Map, id absent,
60
+ * a cell that fails to decode) returns `undefined` rather than throwing, so a
61
+ * malformed or adversarial event can never crash the reader.
62
+ *
63
+ * Only the matched record is decoded (not the whole index), and it is decoded
64
+ * by the same {@link decodeSignBidirectionalRequest} the full reader uses, so
65
+ * the result is `toEqual` to `readSignetRequestsLedgerFromState(raw)
66
+ * .requestsIndex.get(requestId)` when `fieldIndex` is the index field.
67
+ *
68
+ * @param raw - Raw contract state, e.g. `queryContractState(address).data`.
69
+ * @param fieldIndex - Ledger field position of the request index in `raw`.
70
+ * @param requestId - The request id to look up.
71
+ * @returns The stored request record, or `undefined` when it is not a member.
72
+ */
73
+ export declare function lookupSignetRequestAt(raw: RawContractState, fieldIndex: number, requestId: RequestIdHex): SignBidirectionalRequest | undefined;
74
+ //# sourceMappingURL=signature-requests-state-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-requests-state-reader.d.ts","sourceRoot":"","sources":["../src/signature-requests-state-reader.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EACnC,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAEtC,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AA+D5C;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,EAAE,6BAA6B,CAAC;CAC9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,gBAAgB,GAAG,oBAAoB,CAwB7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,gBAAgB,EACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,YAAY,GACtB,wBAAwB,GAAG,SAAS,CA2BtC"}
@@ -0,0 +1,167 @@
1
+ // MPC-style raw state reader for the signature-REQUESTS side: decode the signet
2
+ // request ledger fields out of a contract's raw state WITHOUT the compiled
3
+ // contract. This is how the MPC monitor consumes signet contracts — it has only
4
+ // a contract address, queries raw state from the indexer
5
+ // (queryContractState(address).data), and decodes by the signet layout
6
+ // convention: the request index is ledger field 0, the request counter field 1.
7
+ // The compiled contract's generated ledger() does exactly this walk internally;
8
+ // the record descriptors themselves are the parameterized twins in
9
+ // signet-requests.ts. The generic tree walk and shared base descriptors live
10
+ // in signature-state-reading.ts.
11
+ import { requestIdHex, signBidirectionalRequestDescriptor, } from "./signet-requests.js";
12
+ import { requestIdType, signetFieldNode, u64, } from "./signature-state-reading.js";
13
+ /** Signet layout convention: the request index is ledger field 0. */
14
+ export const SIGNET_REQUESTS_INDEX_FIELD = 0;
15
+ /** Signet layout convention: the request counter (`SignetNonce`) is ledger field 1. */
16
+ export const SIGNET_NONCE_FIELD = 1;
17
+ /**
18
+ * Aligned-value entry count of a request record EXCLUDING the capacity-scaled
19
+ * vectors: requestNonce (1) + txParamType (1, enums are one atom whatever
20
+ * their byte width) + the EVMType2TxParams fixed fields (to..value = 7,
21
+ * accessListEntryCount = 1) + the calldata Maybe's is_some (1), selector (1)
22
+ * and noWords (1) + the routing fields caip2Id..respondSerializationSchema (8).
23
+ * A stored request cell therefore holds
24
+ * `REQUEST_FIXED_VALUE_ATOMS + maxCalldataWords
25
+ * + maxAccessListEntries·(2 + maxStorageKeysPerEntry)`
26
+ * entries (each calldata word is one Bytes<32> atom; each access-list entry is
27
+ * address + storageKeyCount + its keys).
28
+ */
29
+ export const REQUEST_FIXED_VALUE_ATOMS = 21;
30
+ /**
31
+ * Recover a record's capacity instantiation (maxCalldataWords,
32
+ * maxAccessListEntries, maxStorageKeysPerEntry) from its aligned-value atom
33
+ * count and decode it. Unlike the old single-vector layout, one atom count no
34
+ * longer determines the capacities uniquely, so candidates are enumerated —
35
+ * access-list-free first (today's only producer, the vault, is <2, 0, 0>) —
36
+ * and validated by the decode itself: the descriptors' Bytes length checks
37
+ * and the enum range check reject wrong splits, and a decode that leaves
38
+ * atoms unconsumed is rejected here.
39
+ *
40
+ * @param atoms - The record cell's aligned value (a fresh copy per attempt).
41
+ * @returns The decoded record.
42
+ * @throws Error if no capacity split decodes the value cleanly.
43
+ */
44
+ function decodeSignBidirectionalRequest(atoms) {
45
+ const variable = atoms.length - REQUEST_FIXED_VALUE_ATOMS;
46
+ if (variable < 0) {
47
+ throw new Error(`request record has ${atoms.length} value entries — fewer than the ` +
48
+ `${REQUEST_FIXED_VALUE_ATOMS} its fixed fields need`);
49
+ }
50
+ const attempt = (maxWords, maxEntries, maxKeys) => {
51
+ const cursor = [...atoms];
52
+ try {
53
+ const record = signBidirectionalRequestDescriptor(maxWords, maxEntries, maxKeys).fromValue(cursor);
54
+ // A clean decode consumes the record exactly.
55
+ return cursor.length === 0 ? record : undefined;
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ };
61
+ // No access list: variable atoms are calldata words alone (one atom each).
62
+ {
63
+ const record = attempt(variable, 0, 0);
64
+ if (record !== undefined)
65
+ return record;
66
+ }
67
+ // With an access list: E entries of (2 + K) atoms, the rest words.
68
+ for (let entries = 1; entries * 2 <= variable; entries++) {
69
+ for (let keys = 0; entries * (2 + keys) <= variable; keys++) {
70
+ const words = variable - entries * (2 + keys);
71
+ const record = attempt(words, entries, keys);
72
+ if (record !== undefined)
73
+ return record;
74
+ }
75
+ }
76
+ throw new Error(`request record with ${atoms.length} value entries matches no ` +
77
+ `(calldata words, access-list entries, storage keys) capacity split`);
78
+ }
79
+ /**
80
+ * MPC-style read: parse the signet ledger fields out of raw contract state
81
+ * by field position alone — no compiled contract, no generated `ledger()`,
82
+ * only the signet layout convention and the canonical descriptors from
83
+ * signet-requests.ts.
84
+ *
85
+ * @param raw - Raw contract state, e.g. `queryContractState(address).data`
86
+ * from the indexer or `ctx.currentQueryContext.state` from the simulator.
87
+ * @returns The decoded {@link SignetRequestsLedger}.
88
+ * @throws Error if a field is missing, has the wrong state-value shape, or a
89
+ * record matches no capacity split.
90
+ */
91
+ export function readSignetRequestsLedgerFromState(raw) {
92
+ const map = signetFieldNode(raw, SIGNET_REQUESTS_INDEX_FIELD).asMap();
93
+ if (map === undefined) {
94
+ throw new Error(`Ledger field ${SIGNET_REQUESTS_INDEX_FIELD} is not a Map`);
95
+ }
96
+ const requestsIndex = new Map();
97
+ for (const key of map.keys()) {
98
+ // fromValue consumes its input, so hand each descriptor a copy.
99
+ const requestId = requestIdType.fromValue([...key.value]);
100
+ const cell = map.get(key)?.asCell();
101
+ if (cell === undefined)
102
+ continue;
103
+ requestsIndex.set(requestIdHex(requestId), decodeSignBidirectionalRequest(cell.value));
104
+ }
105
+ const nonceCell = signetFieldNode(raw, SIGNET_NONCE_FIELD).asCell();
106
+ if (nonceCell === undefined) {
107
+ throw new Error(`Ledger field ${SIGNET_NONCE_FIELD} is not a Cell`);
108
+ }
109
+ const nonce = u64.fromValue([...nonceCell.value]);
110
+ return { nonce, requestsIndex };
111
+ }
112
+ /**
113
+ * Look up ONE request by id in a contract's request index at an arbitrary
114
+ * ledger field — the generalization of {@link readSignetRequestsLedgerFromState}
115
+ * the event path needs: a `SignBidirectionalEvent` names both the requester
116
+ * contract AND which field holds its index, so the field is no longer assumed
117
+ * to be {@link SIGNET_REQUESTS_INDEX_FIELD}.
118
+ *
119
+ * This is the mandatory membership check of the event flow (see
120
+ * signet-request-resolver.ts): `undefined` means the id is NOT a member of the
121
+ * index at `fieldIndex` — the notification is forged, stale, points at the
122
+ * wrong field, or the request is not yet indexed — and the caller MUST drop it.
123
+ * Every non-membership case (field out of range, field is not a Map, id absent,
124
+ * a cell that fails to decode) returns `undefined` rather than throwing, so a
125
+ * malformed or adversarial event can never crash the reader.
126
+ *
127
+ * Only the matched record is decoded (not the whole index), and it is decoded
128
+ * by the same {@link decodeSignBidirectionalRequest} the full reader uses, so
129
+ * the result is `toEqual` to `readSignetRequestsLedgerFromState(raw)
130
+ * .requestsIndex.get(requestId)` when `fieldIndex` is the index field.
131
+ *
132
+ * @param raw - Raw contract state, e.g. `queryContractState(address).data`.
133
+ * @param fieldIndex - Ledger field position of the request index in `raw`.
134
+ * @param requestId - The request id to look up.
135
+ * @returns The stored request record, or `undefined` when it is not a member.
136
+ */
137
+ export function lookupSignetRequestAt(raw, fieldIndex, requestId) {
138
+ let node;
139
+ try {
140
+ node = signetFieldNode(raw, fieldIndex);
141
+ }
142
+ catch {
143
+ return undefined; // field position out of range for this contract
144
+ }
145
+ const map = node.asMap();
146
+ if (map === undefined) {
147
+ return undefined; // the named field is not a request index
148
+ }
149
+ for (const key of map.keys()) {
150
+ // fromValue consumes its input, so hand each descriptor a copy.
151
+ if (requestIdHex(requestIdType.fromValue([...key.value])) !== requestId) {
152
+ continue;
153
+ }
154
+ const cell = map.get(key)?.asCell();
155
+ if (cell === undefined) {
156
+ return undefined;
157
+ }
158
+ try {
159
+ return decodeSignBidirectionalRequest(cell.value);
160
+ }
161
+ catch {
162
+ return undefined; // a cell that is not a decodable request record
163
+ }
164
+ }
165
+ return undefined; // id absent from the index
166
+ }
167
+ //# sourceMappingURL=signature-requests-state-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-requests-state-reader.js","sourceRoot":"","sources":["../src/signature-requests-state-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type SignBidirectionalRequest } from "./signet-requests.ts";
2
+ import type { SignatureResponse } from "./signet-contract-state-reader.ts";
3
+ /**
4
+ * Recover the EVM address that produced a response signature, over the
5
+ * signing hash of the transaction the request describes.
6
+ *
7
+ * @param request - The on-ledger request record the response answers.
8
+ * @param response - The posted signature record answering it.
9
+ * @returns The checksummed recovered signer address.
10
+ * @throws Error if the response is not a decodable signature or the request
11
+ * record is malformed (see
12
+ * {@link signBidirectionalRequestToUnsignedEVMTransaction}).
13
+ */
14
+ export declare function recoverSignatureResponseSigner(request: SignBidirectionalRequest, response: SignatureResponse): string;
15
+ /**
16
+ * Verify a posted response against its request: does the signature recover
17
+ * to `expectedSigner`? Never throws — a response that is malformed or signed
18
+ * by anyone else is simply not valid, which is the expected state of affairs
19
+ * on an unauthenticated log.
20
+ *
21
+ * @param request - The on-ledger request record the response answers.
22
+ * @param response - The posted signature record answering it.
23
+ * @param expectedSigner - The EVM address (any case, 0x hex) that must have signed.
24
+ * @returns `true` iff the response is a valid signature by `expectedSigner`.
25
+ */
26
+ export declare function verifySignatureResponse(request: SignBidirectionalRequest, response: SignatureResponse, expectedSigner: string): boolean;
27
+ //# sourceMappingURL=signature-response-verification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-response-verification.d.ts","sourceRoot":"","sources":["../src/signature-response-verification.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,iBAAiB,GAC1B,MAAM,CAKR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,iBAAiB,EAC3B,cAAc,EAAE,MAAM,GACrB,OAAO,CAST"}
@@ -0,0 +1,45 @@
1
+ // Client-side verification of MPC signature responses. Posting to the
2
+ // signet contract's signature response log is UNAUTHENTICATED (see "Signet
3
+ // Layout" in Signet.compact), so a poller must verify every posted response
4
+ // before trusting it: rebuild the unsigned EVM transaction from the on-ledger
5
+ // request record — assembled exactly as the MPC assembles it (sig-net/mpc
6
+ // response server, managed/erc20-vault/signet/calldata-builder.ts) — and
7
+ // check that the posted `{ bigR, s, recoveryId }` signature recovers to the
8
+ // requester's derived EVM address over that transaction's signing hash.
9
+ import { getAddress, recoverAddress } from "ethers";
10
+ import { signBidirectionalRequestToUnsignedEVMTransaction, signatureResponseToSignature, } from "./signet-requests.js";
11
+ /**
12
+ * Recover the EVM address that produced a response signature, over the
13
+ * signing hash of the transaction the request describes.
14
+ *
15
+ * @param request - The on-ledger request record the response answers.
16
+ * @param response - The posted signature record answering it.
17
+ * @returns The checksummed recovered signer address.
18
+ * @throws Error if the response is not a decodable signature or the request
19
+ * record is malformed (see
20
+ * {@link signBidirectionalRequestToUnsignedEVMTransaction}).
21
+ */
22
+ export function recoverSignatureResponseSigner(request, response) {
23
+ return recoverAddress(signBidirectionalRequestToUnsignedEVMTransaction(request).unsignedHash, signatureResponseToSignature(response));
24
+ }
25
+ /**
26
+ * Verify a posted response against its request: does the signature recover
27
+ * to `expectedSigner`? Never throws — a response that is malformed or signed
28
+ * by anyone else is simply not valid, which is the expected state of affairs
29
+ * on an unauthenticated log.
30
+ *
31
+ * @param request - The on-ledger request record the response answers.
32
+ * @param response - The posted signature record answering it.
33
+ * @param expectedSigner - The EVM address (any case, 0x hex) that must have signed.
34
+ * @returns `true` iff the response is a valid signature by `expectedSigner`.
35
+ */
36
+ export function verifySignatureResponse(request, response, expectedSigner) {
37
+ try {
38
+ return (recoverSignatureResponseSigner(request, response) ===
39
+ getAddress(expectedSigner));
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ //# sourceMappingURL=signature-response-verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-response-verification.js","sourceRoot":"","sources":["../src/signature-response-verification.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,yEAAyE;AACzE,4EAA4E;AAC5E,wEAAwE;AAExE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAEpD,OAAO,EACL,gDAAgD,EAChD,4BAA4B,GAE7B,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAC5C,OAAiC,EACjC,QAA2B;IAE3B,OAAO,cAAc,CACnB,gDAAgD,CAAC,OAAO,CAAC,CAAC,YAAY,EACtE,4BAA4B,CAAC,QAAQ,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAiC,EACjC,QAA2B,EAC3B,cAAsB;IAEtB,IAAI,CAAC;QACH,OAAO,CACL,8BAA8B,CAAC,OAAO,EAAE,QAAQ,CAAC;YACjD,UAAU,CAAC,cAAc,CAAC,CAC3B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { CompactTypeBytes, CompactTypeUnsignedInteger, type CompactType, type StateValue } from "@midnight-ntwrk/compact-runtime";
2
+ import { type RequestId } from "./signet-requests.ts";
3
+ /** Descriptor for a Compact `Uint<64>` (8-byte unsigned integer). */
4
+ export declare const u64: CompactTypeUnsignedInteger;
5
+ /** Descriptor for a Compact `Bytes<32>`. */
6
+ export declare const bytes32: CompactTypeBytes;
7
+ /**
8
+ * Descriptor for a request id ledger key (Compact `RequestId`, a
9
+ * nominal `Bytes<32>`). Use it to encode a {@link RequestId} into the
10
+ * aligned form the state tree stores, or decode one back.
11
+ */
12
+ export declare const requestIdType: CompactType<RequestId>;
13
+ /**
14
+ * What the indexer / simulator hands us: a bare `StateValue`, or anything
15
+ * wrapping one under `.state` (e.g. `ChargedState`,
16
+ * `queryContractState(address).data`).
17
+ */
18
+ export type RawContractState = StateValue | {
19
+ state: StateValue;
20
+ };
21
+ /**
22
+ * Resolve a flat ledger field index to its node in the raw state tree.
23
+ *
24
+ * The runtime stores ledger fields as a root array and chunks them one level
25
+ * deep once the field count grows, so chunked roots are flattened before
26
+ * indexing. Chunk detection assumes signet field 0 is a `Map`, never a
27
+ * `List` (whose node is also array-typed) — guaranteed by the signet layout
28
+ * convention.
29
+ *
30
+ * @param raw - Raw contract state from the indexer or simulator.
31
+ * @param flatIndex - Zero-based ledger field position in declaration order.
32
+ * @returns The `StateValue` node holding that field.
33
+ * @throws Error if `flatIndex` is beyond the contract's field count.
34
+ */
35
+ export declare function signetFieldNode(raw: RawContractState, flatIndex: number): StateValue;
36
+ //# sourceMappingURL=signature-state-reading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-state-reading.d.ts","sourceRoot":"","sources":["../src/signature-state-reading.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAOtD,qEAAqE;AACrE,eAAO,MAAM,GAAG,4BAA2D,CAAC;AAE5E,4CAA4C;AAC5C,eAAO,MAAM,OAAO,kBAA2B,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,SAAS,CAAW,CAAC;AAI7D;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAWlE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,MAAM,GAChB,UAAU,CAgBZ"}