@sig-net/midnight 0.0.2 → 0.0.4
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/README.md +137 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/managed/compiler/contract-info.json +1 -1
- package/dist/managed/compiler/contract-manifest.json +5 -5
- package/dist/managed/contract/index.js +169 -169
- package/dist/managed/contract/index.js.map +1 -1
- package/dist/signature-requests-state-reader.d.ts +21 -22
- package/dist/signature-requests-state-reader.d.ts.map +1 -1
- package/dist/signature-requests-state-reader.js +24 -20
- package/dist/signature-requests-state-reader.js.map +1 -1
- package/dist/signature-state-reading.d.ts +21 -6
- package/dist/signature-state-reading.d.ts.map +1 -1
- package/dist/signature-state-reading.js +42 -10
- package/dist/signature-state-reading.js.map +1 -1
- package/dist/signet-request-response-reader.d.ts +9 -2
- package/dist/signet-request-response-reader.d.ts.map +1 -1
- package/dist/signet-request-response-reader.js +6 -6
- package/dist/signet-request-response-reader.js.map +1 -1
- package/dist/signet-requests.d.ts +2 -1
- package/dist/signet-requests.d.ts.map +1 -1
- package/dist/signet-requests.js +4 -4
- package/dist/signet-requests.js.map +1 -1
- package/package.json +10 -5
- package/src/Schnorr.compact +1 -1
- package/src/Signet.compact +11 -11
- package/src/circuits.compact +1 -1
- package/src/constants.ts +0 -97
- package/src/epsilon-derivation.ts +0 -62
- package/src/index.ts +0 -29
- package/src/managed/compiler/contract-info.json +0 -222
- package/src/managed/compiler/contract-manifest.json +0 -32
- package/src/managed/contract/index.d.ts +0 -78
- package/src/managed/contract/index.js +0 -676
- package/src/managed/contract/index.js.map +0 -8
- package/src/schnorr.ts +0 -210
- package/src/signature-requests-state-reader.ts +0 -223
- package/src/signature-response-verification.ts +0 -64
- package/src/signature-state-reading.ts +0 -87
- package/src/signet-contract-state-reader.ts +0 -587
- package/src/signet-request-feed.ts +0 -208
- package/src/signet-request-resolver.ts +0 -116
- package/src/signet-request-response-reader.ts +0 -324
- package/src/signet-requests.ts +0 -762
|
@@ -1,587 +0,0 @@
|
|
|
1
|
-
// MPC-/client-style raw state reader for the central SIGNET contract: decode
|
|
2
|
-
// its ledger fields out of a contract's raw state WITHOUT the compiled
|
|
3
|
-
// contract, the mirror image of signature-requests-state-reader.ts. A poller
|
|
4
|
-
// has only the contract address, queries raw state from the indexer
|
|
5
|
-
// (queryContractState(address).data), and decodes by the signet contract
|
|
6
|
-
// layout convention (see "Signet Contract Ledger Layout" in Signet.compact):
|
|
7
|
-
// signature response counter index (field 0), signature response log
|
|
8
|
-
// (field 1), respond-bidirectional index (field 2), sealed MPC key hash
|
|
9
|
-
// (field 3), notification registry (field 4). The generic state-tree walk
|
|
10
|
-
// (RawContractState, signetFieldNode) and the shared base descriptors live in
|
|
11
|
-
// signature-state-reading.ts.
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
CompactTypeBytes,
|
|
15
|
-
CompactTypeField,
|
|
16
|
-
CompactTypeJubjubPoint,
|
|
17
|
-
CompactTypeUnsignedInteger,
|
|
18
|
-
type CompactType,
|
|
19
|
-
type JubjubPoint,
|
|
20
|
-
} from "@midnight-ntwrk/compact-runtime";
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
bytesToHex,
|
|
24
|
-
requestIdHex,
|
|
25
|
-
type RequestId,
|
|
26
|
-
type RequestIdHex,
|
|
27
|
-
} from "./signet-requests.ts";
|
|
28
|
-
|
|
29
|
-
import {
|
|
30
|
-
requestIdType,
|
|
31
|
-
signetFieldNode,
|
|
32
|
-
u64,
|
|
33
|
-
type RawContractState,
|
|
34
|
-
} from "./signature-state-reading.ts";
|
|
35
|
-
|
|
36
|
-
/** Signet contract layout: the signature response counter index is ledger field 0. */
|
|
37
|
-
export const SIGNATURE_RESPONSE_COUNTER_INDEX_FIELD = 0;
|
|
38
|
-
|
|
39
|
-
/** Signet contract layout: the signature response log is ledger field 1. */
|
|
40
|
-
export const SIGNATURE_RESPONSE_INDEX_FIELD = 1;
|
|
41
|
-
|
|
42
|
-
/** Signet contract layout: the respond-bidirectional index is ledger field 2. */
|
|
43
|
-
export const RESPOND_BIDIRECTIONAL_INDEX_FIELD = 2;
|
|
44
|
-
|
|
45
|
-
/** Signet contract layout: the sealed MPC attestation key hash is ledger field 3. */
|
|
46
|
-
export const MPC_PUB_KEY_HASH_FIELD = 3;
|
|
47
|
-
|
|
48
|
-
/** Signet contract layout: the request notification registry is ledger field 4. */
|
|
49
|
-
export const SIGN_BIDIRECTIONAL_NOTIFICATION_INDEX_FIELD = 4;
|
|
50
|
-
|
|
51
|
-
// ---- Type descriptors (must mirror Signet.compact field-for-field) ----
|
|
52
|
-
// As in the requests reader, fromValue consumes the aligned value
|
|
53
|
-
// sequentially, so field order and width here must match the Compact structs
|
|
54
|
-
// exactly — a mismatch is silent data corruption, not an error.
|
|
55
|
-
|
|
56
|
-
/** Descriptor for a signature scalar / MPC key hash (`Bytes<32>`). */
|
|
57
|
-
const bytes32 = new CompactTypeBytes(32);
|
|
58
|
-
|
|
59
|
-
/** Descriptor for the attestation's serialized output (`Bytes<128>`). */
|
|
60
|
-
const bytes128 = new CompactTypeBytes(128);
|
|
61
|
-
|
|
62
|
-
/** Descriptor for a Compact `Uint<8>` (1-byte unsigned integer). */
|
|
63
|
-
const u8 = new CompactTypeUnsignedInteger(255n, 1);
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* The MPC's secp256k1 signature over the requested EVM transaction (Compact
|
|
67
|
-
* `SignatureResponse` — the canonical MPC `Signature { big_r, s,
|
|
68
|
-
* recovery_id }` with `big_r` decomposed into affine coordinates, big-endian
|
|
69
|
-
* scalar bytes). The request id it answers lives in the response index key,
|
|
70
|
-
* not here.
|
|
71
|
-
*/
|
|
72
|
-
export interface SignatureResponse {
|
|
73
|
-
/** Signature R.x, 32 big-endian bytes. */
|
|
74
|
-
bigRx: Uint8Array;
|
|
75
|
-
/** Signature R.y, 32 big-endian bytes. */
|
|
76
|
-
bigRy: Uint8Array;
|
|
77
|
-
/** Signature s, 32 big-endian bytes. */
|
|
78
|
-
s: Uint8Array;
|
|
79
|
-
/** Parity of R.y for public-key recovery (0 or 1). */
|
|
80
|
-
recoveryId: bigint;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Hand-composed descriptor for {@link SignatureResponse}. Field
|
|
85
|
-
* order (bigRx, bigRy, s, recoveryId) must match the Compact struct.
|
|
86
|
-
*/
|
|
87
|
-
export const signatureResponseType: CompactType<SignatureResponse> = {
|
|
88
|
-
/** @returns Compound alignment of the struct's fields in declaration order. */
|
|
89
|
-
alignment() {
|
|
90
|
-
return bytes32
|
|
91
|
-
.alignment()
|
|
92
|
-
.concat(bytes32.alignment())
|
|
93
|
-
.concat(bytes32.alignment())
|
|
94
|
-
.concat(u8.alignment());
|
|
95
|
-
},
|
|
96
|
-
/**
|
|
97
|
-
* Decode one signature response from an aligned value, consuming it field
|
|
98
|
-
* by field.
|
|
99
|
-
*
|
|
100
|
-
* @param value - Mutable aligned value cursor; pass a copy.
|
|
101
|
-
* @returns The decoded record.
|
|
102
|
-
*/
|
|
103
|
-
fromValue(value) {
|
|
104
|
-
return {
|
|
105
|
-
bigRx: bytes32.fromValue(value),
|
|
106
|
-
bigRy: bytes32.fromValue(value),
|
|
107
|
-
s: bytes32.fromValue(value),
|
|
108
|
-
recoveryId: u8.fromValue(value),
|
|
109
|
-
};
|
|
110
|
-
},
|
|
111
|
-
/**
|
|
112
|
-
* Encode a signature response into its aligned on-ledger representation.
|
|
113
|
-
*
|
|
114
|
-
* @param record - The record to encode.
|
|
115
|
-
* @returns The aligned value, fields concatenated in declaration order.
|
|
116
|
-
*/
|
|
117
|
-
toValue(record) {
|
|
118
|
-
return bytes32
|
|
119
|
-
.toValue(record.bigRx)
|
|
120
|
-
.concat(bytes32.toValue(record.bigRy))
|
|
121
|
-
.concat(bytes32.toValue(record.s))
|
|
122
|
-
.concat(u8.toValue(record.recoveryId));
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* The MPC's respond-bidirectional attestation of a request's remote EVM
|
|
128
|
-
* execution (Compact `RespondBidirectional`): the serialized execution
|
|
129
|
-
* output plus the Schnorr signature over
|
|
130
|
-
* `(requestId, hash(serializedOutput, outputLen))`. Stored records were
|
|
131
|
-
* verified IN-CIRCUIT by the signet contract at post time, so readers can
|
|
132
|
-
* trust them without re-verifying.
|
|
133
|
-
*/
|
|
134
|
-
export interface RespondBidirectional {
|
|
135
|
-
/** ABI-encoded return data (canonical serialized_output), zero-padded to 128 bytes. */
|
|
136
|
-
serializedOutput: Uint8Array;
|
|
137
|
-
/** Meaningful byte count of {@link serializedOutput}. */
|
|
138
|
-
outputLen: bigint;
|
|
139
|
-
/** The MPC attestation key (hash-checked against the sealed key at post). */
|
|
140
|
-
pk: JubjubPoint;
|
|
141
|
-
/** Schnorr nonce commitment R. */
|
|
142
|
-
announcement: JubjubPoint;
|
|
143
|
-
/** Schnorr response scalar s. */
|
|
144
|
-
response: bigint;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Composite key of one posted signature response (Compact
|
|
149
|
-
* `SignetResponseKey`): the request id it answers plus this post's 0-based
|
|
150
|
-
* count. Field order — count first, then request id — mirrors the Compact
|
|
151
|
-
* struct.
|
|
152
|
-
*/
|
|
153
|
-
export interface SignetResponseKey {
|
|
154
|
-
/** 0-based position of this post among the responses for {@link requestId}. */
|
|
155
|
-
count: bigint;
|
|
156
|
-
/** 32-byte id of the request this response answers. */
|
|
157
|
-
requestId: RequestId;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Hand-composed descriptor for {@link SignetResponseKey} — the map key of
|
|
162
|
-
* the signature response log. Field order (count, then requestId) must match
|
|
163
|
-
* the Compact struct.
|
|
164
|
-
*/
|
|
165
|
-
export const signetResponseKeyType: CompactType<SignetResponseKey> = {
|
|
166
|
-
/** @returns Compound alignment of the struct's fields in declaration order. */
|
|
167
|
-
alignment() {
|
|
168
|
-
return u64.alignment().concat(requestIdType.alignment());
|
|
169
|
-
},
|
|
170
|
-
/**
|
|
171
|
-
* Decode one key from an aligned value, consuming it field by field.
|
|
172
|
-
*
|
|
173
|
-
* @param value - Mutable aligned value cursor; pass a copy.
|
|
174
|
-
* @returns The decoded composite key.
|
|
175
|
-
*/
|
|
176
|
-
fromValue(value) {
|
|
177
|
-
return {
|
|
178
|
-
count: u64.fromValue(value),
|
|
179
|
-
requestId: requestIdType.fromValue(value),
|
|
180
|
-
};
|
|
181
|
-
},
|
|
182
|
-
/**
|
|
183
|
-
* Encode a key into its aligned on-ledger representation.
|
|
184
|
-
*
|
|
185
|
-
* @param key - The composite key to encode.
|
|
186
|
-
* @returns The aligned value, fields concatenated in declaration order.
|
|
187
|
-
*/
|
|
188
|
-
toValue(key) {
|
|
189
|
-
return u64.toValue(key.count).concat(requestIdType.toValue(key.requestId));
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Hand-composed descriptor for {@link RespondBidirectional}. Field
|
|
195
|
-
* order (serializedOutput, outputLen, pk, announcement, response) must match
|
|
196
|
-
* the Compact struct.
|
|
197
|
-
*/
|
|
198
|
-
export const respondBidirectionalType: CompactType<RespondBidirectional> = {
|
|
199
|
-
/** @returns Compound alignment of the struct's fields in declaration order. */
|
|
200
|
-
alignment() {
|
|
201
|
-
return bytes128
|
|
202
|
-
.alignment()
|
|
203
|
-
.concat(u8.alignment())
|
|
204
|
-
.concat(CompactTypeJubjubPoint.alignment())
|
|
205
|
-
.concat(CompactTypeJubjubPoint.alignment())
|
|
206
|
-
.concat(CompactTypeField.alignment());
|
|
207
|
-
},
|
|
208
|
-
/**
|
|
209
|
-
* Decode one attestation record from an aligned value, consuming it field
|
|
210
|
-
* by field.
|
|
211
|
-
*
|
|
212
|
-
* @param value - Mutable aligned value cursor; pass a copy.
|
|
213
|
-
* @returns The decoded record.
|
|
214
|
-
*/
|
|
215
|
-
fromValue(value) {
|
|
216
|
-
return {
|
|
217
|
-
serializedOutput: bytes128.fromValue(value),
|
|
218
|
-
outputLen: u8.fromValue(value),
|
|
219
|
-
pk: CompactTypeJubjubPoint.fromValue(value),
|
|
220
|
-
announcement: CompactTypeJubjubPoint.fromValue(value),
|
|
221
|
-
response: CompactTypeField.fromValue(value),
|
|
222
|
-
};
|
|
223
|
-
},
|
|
224
|
-
/**
|
|
225
|
-
* Encode an attestation record into its aligned on-ledger representation.
|
|
226
|
-
*
|
|
227
|
-
* @param record - The record to encode.
|
|
228
|
-
* @returns The aligned value, fields concatenated in declaration order.
|
|
229
|
-
*/
|
|
230
|
-
toValue(record) {
|
|
231
|
-
return bytes128
|
|
232
|
-
.toValue(record.serializedOutput)
|
|
233
|
-
.concat(u8.toValue(record.outputLen))
|
|
234
|
-
.concat(CompactTypeJubjubPoint.toValue(record.pk))
|
|
235
|
-
.concat(CompactTypeJubjubPoint.toValue(record.announcement))
|
|
236
|
-
.concat(CompactTypeField.toValue(record.response));
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
/** Descriptor for the notification's packed V1 payload (`Bytes<65>`). */
|
|
241
|
-
const bytes65 = new CompactTypeBytes(65);
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Raw twin of the Compact `SignBidirectionalNotification` struct as stored
|
|
245
|
-
* on-ledger: the version tag plus the still-packed 65-byte payload. Decode
|
|
246
|
-
* the payload with {@link decodeSignBidirectionalNotification}.
|
|
247
|
-
*/
|
|
248
|
-
export interface SignBidirectionalNotificationRecord {
|
|
249
|
-
/** Payload layout tag (Compact `Uint<8>`); 1 = the V1 layout. */
|
|
250
|
-
version: bigint;
|
|
251
|
-
/** The packed payload bytes, exactly as the registering circuit built them. */
|
|
252
|
-
payload: Uint8Array;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Hand-composed descriptor for {@link SignBidirectionalNotificationRecord}.
|
|
257
|
-
* Field order (version, payload) must match the Compact struct.
|
|
258
|
-
*/
|
|
259
|
-
export const signBidirectionalNotificationType: CompactType<SignBidirectionalNotificationRecord> =
|
|
260
|
-
{
|
|
261
|
-
/** @returns Compound alignment of the struct's fields in declaration order. */
|
|
262
|
-
alignment() {
|
|
263
|
-
return u8.alignment().concat(bytes65.alignment());
|
|
264
|
-
},
|
|
265
|
-
/**
|
|
266
|
-
* Decode one notification record from an aligned value, consuming it
|
|
267
|
-
* field by field.
|
|
268
|
-
*
|
|
269
|
-
* @param value - Mutable aligned value cursor; pass a copy.
|
|
270
|
-
* @returns The decoded record.
|
|
271
|
-
*/
|
|
272
|
-
fromValue(value) {
|
|
273
|
-
return {
|
|
274
|
-
version: u8.fromValue(value),
|
|
275
|
-
payload: bytes65.fromValue(value),
|
|
276
|
-
};
|
|
277
|
-
},
|
|
278
|
-
/**
|
|
279
|
-
* Encode a notification record into its aligned on-ledger representation.
|
|
280
|
-
*
|
|
281
|
-
* @param record - The record to encode.
|
|
282
|
-
* @returns The aligned value, fields concatenated in declaration order.
|
|
283
|
-
*/
|
|
284
|
-
toValue(record) {
|
|
285
|
-
return u8.toValue(record.version).concat(bytes65.toValue(record.payload));
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
/** Offset of the V1 `callerAddress` in the packed payload (`Bytes<32>` at the front). */
|
|
290
|
-
const NOTIFICATION_CALLER_ADDRESS_OFFSET = 0;
|
|
291
|
-
|
|
292
|
-
/** Offset of the V1 `requestId` (after the 32 callerAddress bytes). */
|
|
293
|
-
const NOTIFICATION_REQUEST_ID_OFFSET = 32;
|
|
294
|
-
|
|
295
|
-
/** Offset of the V1 `requestsIndexField` (after callerAddress + requestId). */
|
|
296
|
-
const NOTIFICATION_REQUESTS_INDEX_FIELD_OFFSET = 64;
|
|
297
|
-
|
|
298
|
-
/** The only payload interpretation {@link decodeSignBidirectionalNotification} understands today. */
|
|
299
|
-
const SUPPORTED_NOTIFICATION_VERSION = 1n;
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* A decoded V1 notification from the signet contract's registry: the flat
|
|
303
|
-
* pointer a client registered to tell the MPC a request was stored — and
|
|
304
|
-
* WHERE to read the authenticated copy. Never trusted on its own: the
|
|
305
|
-
* resolver authenticates by reading the request back from
|
|
306
|
-
* {@link callerAddress}'s own ledger (see signet-request-resolver.ts).
|
|
307
|
-
*/
|
|
308
|
-
export interface SignBidirectionalNotification {
|
|
309
|
-
/** Payload layout tag; this decoder only produces version 1. */
|
|
310
|
-
version: number;
|
|
311
|
-
/**
|
|
312
|
-
* Address of the contract whose request index holds the request, rendered
|
|
313
|
-
* as lowercase hex, no `0x` prefix — directly usable as a
|
|
314
|
-
* `queryContractState` argument. The MPC reads the request from THIS
|
|
315
|
-
* contract's authenticated state; the field itself confers no authority.
|
|
316
|
-
*/
|
|
317
|
-
callerAddress: string;
|
|
318
|
-
/** Which request in {@link callerAddress}'s index this notification is about. */
|
|
319
|
-
requestId: RequestIdHex;
|
|
320
|
-
/**
|
|
321
|
-
* Ledger field position of the `Map<RequestId, SignBidirectionalRequest>`
|
|
322
|
-
* request index in {@link callerAddress} (the signet layout convention puts
|
|
323
|
-
* it at field 0, but the notification carries it so the reader never assumes).
|
|
324
|
-
*/
|
|
325
|
-
requestsIndexField: number;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Unpack a stored {@link SignBidirectionalNotificationRecord}'s payload by
|
|
330
|
-
* the fixed V1 offsets — the decode twin of the compiled
|
|
331
|
-
* `constructSignBidirectionalNotificationV1` circuit (byte plumbing only; the
|
|
332
|
-
* pack↔decode lockstep is pinned by the state-reader unit test that round-trips
|
|
333
|
-
* through the real circuit).
|
|
334
|
-
*
|
|
335
|
-
* Fails closed on an unrecognised `version`: a future payload layout adds a
|
|
336
|
-
* branch here rather than silently misinterpreting bytes under the V1 offsets.
|
|
337
|
-
*
|
|
338
|
-
* @param record - The raw on-ledger record.
|
|
339
|
-
* @returns The decoded flat notification.
|
|
340
|
-
* @throws Error if the record's `version` is not one this decoder understands.
|
|
341
|
-
*/
|
|
342
|
-
export function decodeSignBidirectionalNotification(
|
|
343
|
-
record: SignBidirectionalNotificationRecord,
|
|
344
|
-
): SignBidirectionalNotification {
|
|
345
|
-
if (record.version !== SUPPORTED_NOTIFICATION_VERSION) {
|
|
346
|
-
throw new Error(
|
|
347
|
-
`SignBidirectionalNotification version ${record.version} is not supported ` +
|
|
348
|
-
`(this decoder understands version ${SUPPORTED_NOTIFICATION_VERSION})`,
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
const callerAddress = bytesToHex(
|
|
352
|
-
record.payload.slice(
|
|
353
|
-
NOTIFICATION_CALLER_ADDRESS_OFFSET,
|
|
354
|
-
NOTIFICATION_REQUEST_ID_OFFSET,
|
|
355
|
-
),
|
|
356
|
-
);
|
|
357
|
-
const requestId = requestIdHex(
|
|
358
|
-
record.payload.slice(
|
|
359
|
-
NOTIFICATION_REQUEST_ID_OFFSET,
|
|
360
|
-
NOTIFICATION_REQUESTS_INDEX_FIELD_OFFSET,
|
|
361
|
-
),
|
|
362
|
-
);
|
|
363
|
-
const requestsIndexField =
|
|
364
|
-
record.payload[NOTIFICATION_REQUESTS_INDEX_FIELD_OFFSET];
|
|
365
|
-
return {
|
|
366
|
-
version: Number(record.version),
|
|
367
|
-
callerAddress,
|
|
368
|
-
requestId,
|
|
369
|
-
requestsIndexField,
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Plain-JS notification registry parsed out of the ledger: hex request id
|
|
375
|
-
* (the map KEY under which the notification was registered) to the raw
|
|
376
|
-
* stored record. Decode each record with
|
|
377
|
-
* {@link decodeSignBidirectionalNotification}.
|
|
378
|
-
*/
|
|
379
|
-
export type SignBidirectionalNotificationIndex = Map<
|
|
380
|
-
RequestIdHex,
|
|
381
|
-
SignBidirectionalNotificationRecord
|
|
382
|
-
>;
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Plain-JS signature response counter index parsed out of the ledger: hex
|
|
386
|
-
* request id (see {@link requestIdHex}) to the number of responses posted for
|
|
387
|
-
* that request. Entries in the response log exist for counts `0 .. value - 1`.
|
|
388
|
-
*/
|
|
389
|
-
export type SignatureResponseCounterIndex = Map<RequestIdHex, bigint>;
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Plain-JS signature response log parsed out of the ledger, keyed by
|
|
393
|
-
* {@link signetResponseIndexKey} (`"<hexRequestId>:<count>"`) so the
|
|
394
|
-
* composite Compact key survives as a usable JS `Map` key.
|
|
395
|
-
*/
|
|
396
|
-
export type SignatureResponseIndex = Map<string, SignatureResponse>;
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Plain-JS respond-bidirectional index parsed out of the ledger: hex
|
|
400
|
-
* request id to the contract-verified attestation. One slot per request.
|
|
401
|
-
*/
|
|
402
|
-
export type RespondBidirectionalIndex = Map<
|
|
403
|
-
RequestIdHex,
|
|
404
|
-
RespondBidirectional
|
|
405
|
-
>;
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Build the {@link SignatureResponseIndex} key for a `(requestId, count)`
|
|
409
|
-
* pair — the composite Compact key flattened to a string so it works as a JS
|
|
410
|
-
* `Map` key.
|
|
411
|
-
*
|
|
412
|
-
* @param id - The request id the response answers, in canonical hex form.
|
|
413
|
-
* @param count - 0-based post count within that request.
|
|
414
|
-
* @returns `"<hexRequestId>:<count>"`.
|
|
415
|
-
*/
|
|
416
|
-
export function signetResponseIndexKey(
|
|
417
|
-
id: RequestIdHex,
|
|
418
|
-
count: bigint,
|
|
419
|
-
): string {
|
|
420
|
-
return `${id}:${count}`;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Read ONLY the notification registry (ledger field
|
|
425
|
-
* {@link SIGN_BIDIRECTIONAL_NOTIFICATION_INDEX_FIELD}) out of raw signet
|
|
426
|
-
* contract state — the poll-loop primitive of {@link SignetRequestFeed},
|
|
427
|
-
* which cycles frequently and has no use for the response fields.
|
|
428
|
-
*
|
|
429
|
-
* @param raw - Raw contract state, e.g. `queryContractState(address).data`
|
|
430
|
-
* from the indexer or `ctx.currentQueryContext.state` from the simulator.
|
|
431
|
-
* @returns The registry, keyed by the hex request id each record was
|
|
432
|
-
* registered under.
|
|
433
|
-
* @throws Error if the field is missing or is not a Map.
|
|
434
|
-
*/
|
|
435
|
-
export function readSignBidirectionalNotificationIndexFromState(
|
|
436
|
-
raw: RawContractState,
|
|
437
|
-
): SignBidirectionalNotificationIndex {
|
|
438
|
-
const notificationMap = signetFieldNode(
|
|
439
|
-
raw,
|
|
440
|
-
SIGN_BIDIRECTIONAL_NOTIFICATION_INDEX_FIELD,
|
|
441
|
-
).asMap();
|
|
442
|
-
if (notificationMap === undefined) {
|
|
443
|
-
throw new Error(
|
|
444
|
-
`Ledger field ${SIGN_BIDIRECTIONAL_NOTIFICATION_INDEX_FIELD} is not a Map`,
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
const index: SignBidirectionalNotificationIndex = new Map();
|
|
448
|
-
for (const key of notificationMap.keys()) {
|
|
449
|
-
// fromValue consumes its input, so hand each descriptor a copy.
|
|
450
|
-
const requestId = requestIdType.fromValue([...key.value]);
|
|
451
|
-
const cell = notificationMap.get(key)?.asCell();
|
|
452
|
-
if (cell === undefined) continue;
|
|
453
|
-
index.set(
|
|
454
|
-
requestIdHex(requestId),
|
|
455
|
-
signBidirectionalNotificationType.fromValue([...cell.value]),
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
return index;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* The decoded ledger fields of the signet contract: the signature response
|
|
463
|
-
* counter (field 0) and log (field 1), the respond-bidirectional index
|
|
464
|
-
* (field 2), the sealed MPC attestation key hash (field 3), and the request
|
|
465
|
-
* notification registry (field 4). Together they give a poller everything
|
|
466
|
-
* the contract ever records about a request.
|
|
467
|
-
*/
|
|
468
|
-
export interface SignetContractLedger {
|
|
469
|
-
/**
|
|
470
|
-
* The signature response counter index (ledger field
|
|
471
|
-
* {@link SIGNATURE_RESPONSE_COUNTER_INDEX_FIELD}), keyed by hex request id.
|
|
472
|
-
*/
|
|
473
|
-
signatureResponseCounterIndex: SignatureResponseCounterIndex;
|
|
474
|
-
/**
|
|
475
|
-
* The signature response log (ledger field
|
|
476
|
-
* {@link SIGNATURE_RESPONSE_INDEX_FIELD}), keyed by
|
|
477
|
-
* {@link signetResponseIndexKey}.
|
|
478
|
-
*/
|
|
479
|
-
signatureResponseIndex: SignatureResponseIndex;
|
|
480
|
-
/**
|
|
481
|
-
* The respond-bidirectional index (ledger field
|
|
482
|
-
* {@link RESPOND_BIDIRECTIONAL_INDEX_FIELD}), keyed by hex request id.
|
|
483
|
-
*/
|
|
484
|
-
respondBidirectionalIndex: RespondBidirectionalIndex;
|
|
485
|
-
/**
|
|
486
|
-
* The sealed MPC attestation key hash (ledger field
|
|
487
|
-
* {@link MPC_PUB_KEY_HASH_FIELD}) posts are verified against.
|
|
488
|
-
*/
|
|
489
|
-
mpcPubKeyHash: Uint8Array;
|
|
490
|
-
/**
|
|
491
|
-
* The request notification registry (ledger field
|
|
492
|
-
* {@link SIGN_BIDIRECTIONAL_NOTIFICATION_INDEX_FIELD}), keyed by hex
|
|
493
|
-
* request id.
|
|
494
|
-
*/
|
|
495
|
-
signBidirectionalNotificationIndex: SignBidirectionalNotificationIndex;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
* MPC-/client-style read: parse the signet contract's ledger fields out of
|
|
500
|
-
* raw contract state by field position alone — no compiled contract, no
|
|
501
|
-
* generated `ledger()`, only the signet contract layout convention and the
|
|
502
|
-
* canonical descriptors above.
|
|
503
|
-
*
|
|
504
|
-
* @param raw - Raw contract state, e.g. `queryContractState(address).data`
|
|
505
|
-
* from the indexer or `ctx.currentQueryContext.state` from the simulator.
|
|
506
|
-
* @returns The decoded {@link SignetContractLedger}.
|
|
507
|
-
* @throws Error if a field is missing or has the wrong state-value shape.
|
|
508
|
-
*/
|
|
509
|
-
export function readSignetContractLedgerFromState(
|
|
510
|
-
raw: RawContractState,
|
|
511
|
-
): SignetContractLedger {
|
|
512
|
-
const counterMap = signetFieldNode(
|
|
513
|
-
raw,
|
|
514
|
-
SIGNATURE_RESPONSE_COUNTER_INDEX_FIELD,
|
|
515
|
-
).asMap();
|
|
516
|
-
if (counterMap === undefined) {
|
|
517
|
-
throw new Error(
|
|
518
|
-
`Ledger field ${SIGNATURE_RESPONSE_COUNTER_INDEX_FIELD} is not a Map`,
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
const signatureResponseCounterIndex: SignatureResponseCounterIndex =
|
|
522
|
-
new Map();
|
|
523
|
-
for (const key of counterMap.keys()) {
|
|
524
|
-
// fromValue consumes its input, so hand each descriptor a copy.
|
|
525
|
-
const requestId = requestIdType.fromValue([...key.value]);
|
|
526
|
-
// A Counter is stored as a plain u64 cell.
|
|
527
|
-
const cell = counterMap.get(key)?.asCell();
|
|
528
|
-
if (cell === undefined) continue;
|
|
529
|
-
signatureResponseCounterIndex.set(
|
|
530
|
-
requestIdHex(requestId),
|
|
531
|
-
u64.fromValue([...cell.value]),
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
const responseMap = signetFieldNode(
|
|
536
|
-
raw,
|
|
537
|
-
SIGNATURE_RESPONSE_INDEX_FIELD,
|
|
538
|
-
).asMap();
|
|
539
|
-
if (responseMap === undefined) {
|
|
540
|
-
throw new Error(`Ledger field ${SIGNATURE_RESPONSE_INDEX_FIELD} is not a Map`);
|
|
541
|
-
}
|
|
542
|
-
const signatureResponseIndex: SignatureResponseIndex = new Map();
|
|
543
|
-
for (const key of responseMap.keys()) {
|
|
544
|
-
const responseKey = signetResponseKeyType.fromValue([...key.value]);
|
|
545
|
-
const cell = responseMap.get(key)?.asCell();
|
|
546
|
-
if (cell === undefined) continue;
|
|
547
|
-
signatureResponseIndex.set(
|
|
548
|
-
signetResponseIndexKey(requestIdHex(responseKey.requestId), responseKey.count),
|
|
549
|
-
signatureResponseType.fromValue([...cell.value]),
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const respondBidirectionalMap = signetFieldNode(
|
|
554
|
-
raw,
|
|
555
|
-
RESPOND_BIDIRECTIONAL_INDEX_FIELD,
|
|
556
|
-
).asMap();
|
|
557
|
-
if (respondBidirectionalMap === undefined) {
|
|
558
|
-
throw new Error(
|
|
559
|
-
`Ledger field ${RESPOND_BIDIRECTIONAL_INDEX_FIELD} is not a Map`,
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
const respondBidirectionalIndex: RespondBidirectionalIndex = new Map();
|
|
563
|
-
for (const key of respondBidirectionalMap.keys()) {
|
|
564
|
-
const requestId = requestIdType.fromValue([...key.value]);
|
|
565
|
-
const cell = respondBidirectionalMap.get(key)?.asCell();
|
|
566
|
-
if (cell === undefined) continue;
|
|
567
|
-
respondBidirectionalIndex.set(
|
|
568
|
-
requestIdHex(requestId),
|
|
569
|
-
respondBidirectionalType.fromValue([...cell.value]),
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const hashCell = signetFieldNode(raw, MPC_PUB_KEY_HASH_FIELD).asCell();
|
|
574
|
-
if (hashCell === undefined) {
|
|
575
|
-
throw new Error(`Ledger field ${MPC_PUB_KEY_HASH_FIELD} is not a Cell`);
|
|
576
|
-
}
|
|
577
|
-
const mpcPubKeyHash = bytes32.fromValue([...hashCell.value]);
|
|
578
|
-
|
|
579
|
-
return {
|
|
580
|
-
signatureResponseCounterIndex,
|
|
581
|
-
signatureResponseIndex,
|
|
582
|
-
respondBidirectionalIndex,
|
|
583
|
-
mpcPubKeyHash,
|
|
584
|
-
signBidirectionalNotificationIndex:
|
|
585
|
-
readSignBidirectionalNotificationIndexFromState(raw),
|
|
586
|
-
};
|
|
587
|
-
}
|