@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,116 @@
1
+ // The MPC's single entry point for discovering signature requests by event
2
+ // observation: watch the central signet contract's notifications, resolve each
3
+ // to an AUTHENTICATED request read from the named caller's own ledger, and
4
+ // yield only the ones that pass the membership check. Replaces polling a
5
+ // configured list of requester contracts — the feed discovers requesters
6
+ // dynamically, keyed off whose authenticated state it actually read.
7
+ //
8
+ // The requester allow-list is an OPTIONAL policy filter here (drop requests
9
+ // from contracts you choose not to serve), never a security requirement and
10
+ // never the discovery mechanism — attribution comes from the resolver's
11
+ // authenticated read (see signet-request-resolver.ts and
12
+ // knowledge-base/caller-attribution.md).
13
+ import { SignetEventObserver, sleepUnlessAborted, } from "./signet-event-observer.js";
14
+ import { signBidirectionalEventCodec, stripHexPrefix, } from "./signet-events.js";
15
+ import { SignetRequestResolver, } from "./signet-request-resolver.js";
16
+ /** Default gap between poll cycles of {@link SignetRequestFeed.requests}. */
17
+ export const DEFAULT_FEED_POLL_INTERVAL_MS = 3000;
18
+ /** Canonical form for comparing contract addresses: no `0x`, lowercase. */
19
+ function normalizeAddress(address) {
20
+ return stripHexPrefix(address).toLowerCase();
21
+ }
22
+ /**
23
+ * The event-driven request feed. Composes a {@link SignetEventObserver}
24
+ * (discovery) with a {@link SignetRequestResolver} (authentication), yielding
25
+ * only notifications that resolve to a real, member request. Dedupes by request
26
+ * id across its lifetime, so a redelivered notification is not re-yielded; call
27
+ * {@link forget} to re-arm a request whose downstream processing failed.
28
+ */
29
+ export class SignetRequestFeed {
30
+ observer;
31
+ resolver;
32
+ allowContracts;
33
+ pollIntervalMs;
34
+ // Request ids already yielded. NOT the security boundary (the resolver is) —
35
+ // just an at-most-once gate so one request is not processed twice.
36
+ yielded = new Set();
37
+ /**
38
+ * @param config - The signet contract, combined event/state source, optional
39
+ * policy allow-list, and resume floor.
40
+ */
41
+ constructor(config) {
42
+ this.observer = new SignetEventObserver({
43
+ signetContractAddress: config.signetContractAddress,
44
+ source: config.source,
45
+ codec: signBidirectionalEventCodec,
46
+ fromEventId: config.fromEventId,
47
+ pollIntervalMs: config.pollIntervalMs,
48
+ });
49
+ this.resolver = new SignetRequestResolver({ source: config.source });
50
+ this.allowContracts = config.allowContracts
51
+ ? new Set(Array.from(config.allowContracts, normalizeAddress))
52
+ : undefined;
53
+ this.pollIntervalMs =
54
+ config.pollIntervalMs ?? DEFAULT_FEED_POLL_INTERVAL_MS;
55
+ }
56
+ /** Whether the policy allow-list admits `callerAddress` (always true when unset). */
57
+ allowed(callerAddress) {
58
+ return (this.allowContracts === undefined ||
59
+ this.allowContracts.has(normalizeAddress(callerAddress)));
60
+ }
61
+ /**
62
+ * One-shot: every currently-visible notification that is admitted by the
63
+ * allow-list, not already yielded, and resolves to an authenticated member
64
+ * request. Forged / not-yet-indexed / wrong-field notifications resolve to
65
+ * nothing and are dropped WITHOUT being marked yielded, so a genuine
66
+ * request whose ledger write has not indexed yet is retried next cycle.
67
+ *
68
+ * @returns The newly-authenticated requests this cycle, in event id order.
69
+ */
70
+ async poll() {
71
+ const events = await this.observer.currentEvents();
72
+ const out = [];
73
+ for (const event of events) {
74
+ if (this.yielded.has(event.requestId))
75
+ continue;
76
+ if (!this.allowed(event.callerAddress))
77
+ continue;
78
+ const resolved = await this.resolver.resolve(event);
79
+ if (resolved === undefined)
80
+ continue;
81
+ this.yielded.add(event.requestId);
82
+ out.push(resolved);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Re-arm `requestId` for redelivery on the next {@link poll} / {@link requests}
88
+ * cycle — call when downstream processing of a yielded request failed, so it
89
+ * is retried (mirrors the MPC's delete-on-failure of its processed set).
90
+ *
91
+ * @param requestId - The request id to allow through again.
92
+ */
93
+ forget(requestId) {
94
+ this.yielded.delete(requestId);
95
+ }
96
+ /**
97
+ * Live stream: poll + sleep, yielding each authenticated request exactly once
98
+ * (subject to {@link forget}), until `opts.signal` aborts. The natural
99
+ * sequential `for await` consumption serializes downstream processing — no
100
+ * two requests are handed over concurrently.
101
+ *
102
+ * @param opts.signal - Abort to stop the stream.
103
+ * @yields Each authenticated request, in discovery order.
104
+ */
105
+ async *requests(opts) {
106
+ while (!opts?.signal?.aborted) {
107
+ const batch = await this.poll();
108
+ for (const resolved of batch)
109
+ yield resolved;
110
+ if (opts?.signal?.aborted)
111
+ break;
112
+ await sleepUnlessAborted(this.pollIntervalMs, opts?.signal);
113
+ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=signet-request-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signet-request-feed.js","sourceRoot":"","sources":["../src/signet-request-feed.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,+EAA+E;AAC/E,2EAA2E;AAC3E,yEAAyE;AACzE,yEAAyE;AACzE,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,wEAAwE;AACxE,yDAAyD;AACzD,yCAAyC;AAEzC,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GAEnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,2BAA2B,EAC3B,cAAc,GAEf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,GAEtB,MAAM,8BAA8B,CAAC;AAItC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAuBlD,2EAA2E;AAC3E,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACX,QAAQ,CAA8C;IACtD,QAAQ,CAAwB;IAChC,cAAc,CAAe;IAC7B,cAAc,CAAS;IAExC,6EAA6E;IAC7E,mEAAmE;IAClD,OAAO,GAAG,IAAI,GAAG,EAAgB,CAAC;IAEnD;;;OAGG;IACH,YAAY,MAA+B;QACzC,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,CAAC;YACtC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;YACnD,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,2BAA2B;YAClC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc;YACzC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;YAC9D,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,CAAC,cAAc;YACjB,MAAM,CAAC,cAAc,IAAI,6BAA6B,CAAC;IAC3D,CAAC;IAED,qFAAqF;IAC7E,OAAO,CAAC,aAAqB;QACnC,OAAO,CACL,IAAI,CAAC,cAAc,KAAK,SAAS;YACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CACzD,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QACnD,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;gBAAE,SAAS;YAChD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;gBAAE,SAAS;YACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,SAAS;gBAAE,SAAS;YACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,SAAuB;QAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,QAAQ,CAAC,IAEf;QACC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,KAAK,MAAM,QAAQ,IAAI,KAAK;gBAAE,MAAM,QAAQ,CAAC;YAC7C,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO;gBAAE,MAAM;YACjC,MAAM,kBAAkB,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,58 @@
1
+ import type { SignBidirectionalEvent } from "./signet-events.ts";
2
+ import type { SignetPublicStateSource } from "./signet-request-response-reader.ts";
3
+ import type { RequestIdHex, SignBidirectionalRequest } from "./signet-requests.ts";
4
+ /**
5
+ * A {@link SignBidirectionalEvent} resolved to the authenticated request it
6
+ * refers to: the request record read from `callerAddress`'s own ledger, with
7
+ * `requestId` confirmed to be a member of that contract's index.
8
+ */
9
+ export interface ResolvedSignetRequest {
10
+ /**
11
+ * The contract whose authenticated state the request was read from — the
12
+ * epsilon-derivation predecessor. Key derivation keys off THIS, never off a
13
+ * field taken from the event on faith.
14
+ */
15
+ callerAddress: string;
16
+ /** The request id, confirmed to be a member of `callerAddress`'s index. */
17
+ requestId: RequestIdHex;
18
+ /** The authenticated request record to sign. */
19
+ request: SignBidirectionalRequest;
20
+ }
21
+ /** Everything a {@link SignetRequestResolver} needs. */
22
+ export interface SignetRequestResolverConfig {
23
+ /** Source of raw contract state, e.g. midnight-js's `indexerPublicDataProvider`. */
24
+ readonly source: SignetPublicStateSource;
25
+ }
26
+ /**
27
+ * Resolves {@link SignBidirectionalEvent} notifications to authenticated
28
+ * {@link ResolvedSignetRequest}s by reading the named caller's ledger and
29
+ * enforcing the membership check. Construct once and reuse: resolved records
30
+ * are immutable (their ledger key is their hash), so they are cached by request
31
+ * id and a repeated notification for the same request costs no query.
32
+ *
33
+ * NB the cache is keyed by request id, NOT by contract address: a caller
34
+ * contract's state grows as it stores new requests, so caching its state would
35
+ * make the resolver blind to later requests from the same caller. Caching the
36
+ * immutable resolved record instead is the same pattern
37
+ * {@link SignetRequestResponseReader.getSignatureRequest} uses.
38
+ */
39
+ export declare class SignetRequestResolver {
40
+ private readonly source;
41
+ private readonly resolvedCache;
42
+ /**
43
+ * @param config - The state source to read caller ledgers through.
44
+ */
45
+ constructor(config: SignetRequestResolverConfig);
46
+ /**
47
+ * Resolve a notification to its authenticated request, or `undefined` when it
48
+ * cannot be trusted: the caller contract has no state, or `requestId` is not
49
+ * a member of the index at `requestsIndexField` (forged, stale, wrong field,
50
+ * or not yet indexed — poll again). Never throws on an untrusted event; a bad
51
+ * notification is dropped, not surfaced as an error.
52
+ *
53
+ * @param event - The decoded event notification.
54
+ * @returns The authenticated request, or `undefined` to drop the event.
55
+ */
56
+ resolve(event: SignBidirectionalEvent): Promise<ResolvedSignetRequest | undefined>;
57
+ }
58
+ //# sourceMappingURL=signet-request-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signet-request-resolver.d.ts","sourceRoot":"","sources":["../src/signet-request-resolver.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,KAAK,EACV,YAAY,EACZ,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,SAAS,EAAE,YAAY,CAAC;IACxB,gDAAgD;IAChD,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAED,wDAAwD;AACxD,MAAM,WAAW,2BAA2B;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;CAC1C;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IAIjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkD;IAEhF;;OAEG;gBACS,MAAM,EAAE,2BAA2B;IAI/C;;;;;;;;;OASG;IACG,OAAO,CACX,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;CA8B9C"}
@@ -0,0 +1,76 @@
1
+ // Turn a SignBidirectionalEvent notification into an AUTHENTICATED request
2
+ // record. This is the security core of the event flow (see
3
+ // knowledge-base/caller-attribution.md and the invariants in this task's
4
+ // brief): the event says only WHERE to look; the request that gets signed is
5
+ // read from the named caller's own authenticated ledger, and the event's
6
+ // `requestId` must be a member of that contract's request index. An attacker
7
+ // cannot write into a contract it does not control, so a forged event can at
8
+ // most re-point at a legitimate request that already exists — never inject one.
9
+ //
10
+ // Key derivation stays f(callerAddress, path), keyed off the contract whose
11
+ // authenticated state was actually read — exactly today's guarantee, now
12
+ // reached via an event ping instead of per-contract polling.
13
+ import { lookupSignetRequestAt } from "./signature-requests-state-reader.js";
14
+ /**
15
+ * Resolves {@link SignBidirectionalEvent} notifications to authenticated
16
+ * {@link ResolvedSignetRequest}s by reading the named caller's ledger and
17
+ * enforcing the membership check. Construct once and reuse: resolved records
18
+ * are immutable (their ledger key is their hash), so they are cached by request
19
+ * id and a repeated notification for the same request costs no query.
20
+ *
21
+ * NB the cache is keyed by request id, NOT by contract address: a caller
22
+ * contract's state grows as it stores new requests, so caching its state would
23
+ * make the resolver blind to later requests from the same caller. Caching the
24
+ * immutable resolved record instead is the same pattern
25
+ * {@link SignetRequestResponseReader.getSignatureRequest} uses.
26
+ */
27
+ export class SignetRequestResolver {
28
+ source;
29
+ // Resolved records never change; cache them so a redelivered notification for
30
+ // the same request id does not re-query the caller's state.
31
+ resolvedCache = new Map();
32
+ /**
33
+ * @param config - The state source to read caller ledgers through.
34
+ */
35
+ constructor(config) {
36
+ this.source = config.source;
37
+ }
38
+ /**
39
+ * Resolve a notification to its authenticated request, or `undefined` when it
40
+ * cannot be trusted: the caller contract has no state, or `requestId` is not
41
+ * a member of the index at `requestsIndexField` (forged, stale, wrong field,
42
+ * or not yet indexed — poll again). Never throws on an untrusted event; a bad
43
+ * notification is dropped, not surfaced as an error.
44
+ *
45
+ * @param event - The decoded event notification.
46
+ * @returns The authenticated request, or `undefined` to drop the event.
47
+ */
48
+ async resolve(event) {
49
+ const cached = this.resolvedCache.get(event.requestId);
50
+ if (cached !== undefined) {
51
+ return cached;
52
+ }
53
+ let state;
54
+ try {
55
+ state = await this.source.queryContractState(event.callerAddress);
56
+ }
57
+ catch {
58
+ return undefined; // caller address not a contract / transient read error
59
+ }
60
+ if (!state?.data) {
61
+ return undefined; // no state at the named caller — cannot authenticate
62
+ }
63
+ const request = lookupSignetRequestAt(state.data, event.requestsIndexField, event.requestId);
64
+ if (request === undefined) {
65
+ return undefined; // membership check failed — drop the notification
66
+ }
67
+ const resolved = {
68
+ callerAddress: event.callerAddress,
69
+ requestId: event.requestId,
70
+ request,
71
+ };
72
+ this.resolvedCache.set(event.requestId, resolved);
73
+ return resolved;
74
+ }
75
+ }
76
+ //# sourceMappingURL=signet-request-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signet-request-resolver.js","sourceRoot":"","sources":["../src/signet-request-resolver.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2DAA2D;AAC3D,yEAAyE;AACzE,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,6DAA6D;AAE7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAiC7E;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAqB;IACf,MAAM,CAA0B;IAEjD,8EAA8E;IAC9E,4DAA4D;IAC3C,aAAa,GAAG,IAAI,GAAG,EAAuC,CAAC;IAEhF;;OAEG;IACH,YAAY,MAAmC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,CACX,KAA6B;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,KAAwC,CAAC;QAC7C,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC,CAAC,uDAAuD;QAC3E,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC,CAAC,qDAAqD;QACzE,CAAC;QACD,MAAM,OAAO,GAAG,qBAAqB,CACnC,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,kBAAkB,EACxB,KAAK,CAAC,SAAS,CAChB,CAAC;QACF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC,CAAC,kDAAkD;QACtE,CAAC;QACD,MAAM,QAAQ,GAA0B;YACtC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO;SACR,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,160 @@
1
+ import type { PublicDataProvider } from "@midnight-ntwrk/midnight-js-types";
2
+ import type { Transaction } from "ethers";
3
+ import { type SignatureResponse, type RespondBidirectional } from "./signet-contract-state-reader.ts";
4
+ import type { RawContractState } from "./signature-state-reading.ts";
5
+ import { type SignBidirectionalRequest, type RequestIdHex } from "./signet-requests.ts";
6
+ /**
7
+ * The least of midnight-js's `PublicDataProvider` the reader needs: raw
8
+ * contract state by address. Declared structurally (rather than a `Pick`) so
9
+ * tests can satisfy it with a plain stub; any full `PublicDataProvider`
10
+ * (e.g. `indexerPublicDataProvider`) is assignable to it.
11
+ */
12
+ export interface SignetPublicStateSource {
13
+ /**
14
+ * Retrieve the on-chain state of a contract at the latest block.
15
+ *
16
+ * @param contractAddress - The contract address to query.
17
+ * @returns The state (its `data` is the raw ledger tree), or `null` when
18
+ * the address holds no contract.
19
+ */
20
+ queryContractState(contractAddress: Parameters<PublicDataProvider["queryContractState"]>[0]): Promise<{
21
+ data: RawContractState;
22
+ } | null>;
23
+ }
24
+ /** Everything a {@link SignetRequestResponseReader} needs to operate. */
25
+ export interface SignetRequestResponseReaderConfig {
26
+ /** Address of the signet-compliant requester contract (e.g. the vault). */
27
+ readonly requesterContractAddress: string;
28
+ /** Address of the central signet contract. */
29
+ readonly signetContractAddress: string;
30
+ /** Source of raw contract state, e.g. midnight-js's `indexerPublicDataProvider`. */
31
+ readonly publicDataProvider: SignetPublicStateSource;
32
+ }
33
+ /** The verdict on one posted response, in `count` order. */
34
+ export interface SignatureResponseVerdict {
35
+ /** 0-based position of the post in the request's response log. */
36
+ count: bigint;
37
+ /** The posted signature record, verbatim. */
38
+ response: SignatureResponse;
39
+ /** Recovered signer address — absent when the signature did not decode. */
40
+ signer?: string;
41
+ /** Why the post was rejected; absent when the post is valid. */
42
+ rejectedReason?: string;
43
+ }
44
+ /** Result of {@link SignetRequestResponseReader['getVerifiedSignatureResponse']}. */
45
+ export interface VerifiedSignatureResponseResult {
46
+ /**
47
+ * The first valid response (lowest count), or `undefined` when no valid
48
+ * response has been posted yet — poll again.
49
+ */
50
+ verified?: SignatureResponse;
51
+ /**
52
+ * One verdict per post, count order. Pure data: the reader never logs, so
53
+ * callers decide how to surface rejected posts.
54
+ */
55
+ verdicts: SignatureResponseVerdict[];
56
+ }
57
+ /**
58
+ * Reader over one requester contract / signet contract pair.
59
+ * Construct once per pair and reuse: fetched request records are cached (they
60
+ * are immutable — the ledger key is their hash), so repeated verification
61
+ * calls cost one responses-contract query each.
62
+ */
63
+ export declare class SignetRequestResponseReader {
64
+ private readonly config;
65
+ private readonly requestCache;
66
+ /**
67
+ * @param config - The contract pair and state source to read through.
68
+ */
69
+ constructor(config: SignetRequestResponseReaderConfig);
70
+ /**
71
+ * Query one contract's raw state, throwing a uniform error when absent.
72
+ *
73
+ * @param contractAddress - The contract to query.
74
+ * @param role - Human name of the contract for the error message.
75
+ * @returns The raw ledger state tree.
76
+ * @throws Error when the address holds no contract state.
77
+ */
78
+ private queryRawState;
79
+ /**
80
+ * Fetch the request record for `requestId` from the requester contract's
81
+ * ledger (request index, field 0 by the signet layout convention). Cached
82
+ * after the first fetch.
83
+ *
84
+ * @param requestId - The request id to look up.
85
+ * @returns The stored request record.
86
+ * @throws Error when the requester contract has no state or holds no
87
+ * request under `requestId`.
88
+ */
89
+ getSignatureRequest(requestId: RequestIdHex): Promise<SignBidirectionalRequest>;
90
+ /**
91
+ * Fetch every response posted for `requestId`, in post (count) order.
92
+ * UNVERIFIED — any of them may be garbage; see
93
+ * {@link getVerifiedSignatureResponse}.
94
+ *
95
+ * @param requestId - The request id whose posts to enumerate.
96
+ * @returns The posted payloads, index = count; empty when none yet.
97
+ * @throws Error when the responses contract has no state, or its counter
98
+ * disagrees with the log (inconsistent ledger).
99
+ */
100
+ getSignatureResponses(requestId: RequestIdHex): Promise<SignatureResponse[]>;
101
+ /**
102
+ * Fetch and verify the responses posted for `requestId`: each post's
103
+ * `{ bigR, s, recoveryId }` signature must recover to `expectedSigner`
104
+ * (compared case-insensitively) over the signing hash of the transaction
105
+ * the request record describes. The first valid post wins; every post gets
106
+ * a verdict so callers can report the noise.
107
+ *
108
+ * @param requestId - The request id to fetch a verified response for.
109
+ * @param expectedSigner - The EVM address (0x hex, any case) the genuine
110
+ * response must be signed by — the requester's MPC-derived address.
111
+ * @returns The first valid response (if any) plus per-post verdicts.
112
+ * @throws Error when either contract has no state, the request is not on
113
+ * the requester's ledger, or the responses ledger is inconsistent.
114
+ */
115
+ getVerifiedSignatureResponse(requestId: RequestIdHex, expectedSigner: string): Promise<VerifiedSignatureResponseResult>;
116
+ /**
117
+ * Rebuild the unsigned EIP-1559 transaction for `requestId` — the exact
118
+ * transaction the MPC signs, assembled from the request record's decomposed
119
+ * fields. No responses-contract query: this needs only the request record
120
+ * (fetched via {@link getSignatureRequest}, cached).
121
+ *
122
+ * @param requestId - The request id whose transaction to rebuild.
123
+ * @returns The unsigned ethers transaction (`unsignedHash` is the MPC's
124
+ * signing digest).
125
+ * @throws Error when the requester contract has no state or holds no
126
+ * request under `requestId`.
127
+ */
128
+ getUnsignedEVMTransaction(requestId: RequestIdHex): Promise<Transaction>;
129
+ /**
130
+ * Assemble the broadcast-ready signed EIP-1559 transaction for `requestId`:
131
+ * rebuild the request's transaction and attach the first VERIFIED response
132
+ * signed by `expectedSigner` (see {@link getVerifiedSignatureResponse} — the
133
+ * response log is unauthenticated, so an `expectedSigner` is required and
134
+ * unverified posts are never attached).
135
+ *
136
+ * @param requestId - The request id to produce a signed transaction for.
137
+ * @param expectedSigner - The EVM address (0x hex, any case) the genuine
138
+ * response must be signed by — the requester's MPC-derived address.
139
+ * @returns The signed ethers transaction (`serialized` is the payload for
140
+ * `eth_sendRawTransaction`), or `undefined` when no valid response has
141
+ * been posted yet — poll again.
142
+ * @throws Error when either contract has no state, the request is not on the
143
+ * requester's ledger, or the responses ledger is inconsistent.
144
+ */
145
+ getSignedEVMTransaction(requestId: RequestIdHex, expectedSigner: string): Promise<Transaction | undefined>;
146
+ /**
147
+ * Fetch the MPC's respond-bidirectional attestation for `requestId`,
148
+ * if posted. The signet contract verified it IN-CIRCUIT at post time
149
+ * (Schnorr over `(requestId, hash(serializedOutput, outputLen))` against
150
+ * the sealed MPC key), so it is single-slot and needs no off-chain
151
+ * verification or verdicts — `undefined` simply means not posted yet, poll
152
+ * again.
153
+ *
154
+ * @param requestId - The request id whose attestation to fetch.
155
+ * @returns The attestation record, or `undefined` when none is posted.
156
+ * @throws Error when the signet contract has no state on-chain.
157
+ */
158
+ getRespondBidirectional(requestId: RequestIdHex): Promise<RespondBidirectional | undefined>;
159
+ }
160
+ //# sourceMappingURL=signet-request-response-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signet-request-response-reader.d.ts","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG1C,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,kBAAkB,CAChB,eAAe,EAAE,UAAU,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,GACvE,OAAO,CAAC;QAAE,IAAI,EAAE,gBAAgB,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,yEAAyE;AACzE,MAAM,WAAW,iCAAiC;IAChD,2EAA2E;IAC3E,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,8CAA8C;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,oFAAoF;IACpF,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AAED,4DAA4D;AAC5D,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qFAAqF;AACrF,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;OAGG;IACH,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAG3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAGzB;IAEJ;;OAEG;gBACS,MAAM,EAAE,iCAAiC;IAIrD;;;;;;;OAOG;YACW,aAAa;IAc3B;;;;;;;;;OASG;IACG,mBAAmB,CACvB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,wBAAwB,CAAC;IAoBpC;;;;;;;;;OASG;IACG,qBAAqB,CACzB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAwB/B;;;;;;;;;;;;;OAaG;IACG,4BAA4B,CAChC,SAAS,EAAE,YAAY,EACvB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,+BAA+B,CAAC;IAiC3C;;;;;;;;;;;OAWG;IACG,yBAAyB,CAC7B,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,WAAW,CAAC;IAMvB;;;;;;;;;;;;;;;OAeG;IACG,uBAAuB,CAC3B,SAAS,EAAE,YAAY,EACvB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAcnC;;;;;;;;;;;OAWG;IACG,uBAAuB,CAC3B,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAS7C"}
@@ -0,0 +1,198 @@
1
+ // One-stop client-side reader for the signet request/response flow: fetch a
2
+ // request record from the requester contract's ledger, enumerate the posts in
3
+ // the signet contract's signature response log, and verify each candidate
4
+ // against the request.
5
+ // This is the helper the Signet.compact "Response Ledger Layout" comment
6
+ // promises — the log is UNAUTHENTICATED, so a client must verify every post
7
+ // and take the first valid one; this class packages that flow so every
8
+ // consumer (CLI poller, integration tests, a future UI) shares one
9
+ // implementation. Single-shot by design: each call queries state once; the
10
+ // caller owns any poll loop.
11
+ import { readSignetRequestsLedgerFromState } from "./signature-requests-state-reader.js";
12
+ import { readSignetContractLedgerFromState, signetResponseIndexKey, } from "./signet-contract-state-reader.js";
13
+ import { recoverSignatureResponseSigner } from "./signature-response-verification.js";
14
+ import { signBidirectionalRequestToSignedEVMTransaction, signBidirectionalRequestToUnsignedEVMTransaction, } from "./signet-requests.js";
15
+ /**
16
+ * Reader over one requester contract / signet contract pair.
17
+ * Construct once per pair and reuse: fetched request records are cached (they
18
+ * are immutable — the ledger key is their hash), so repeated verification
19
+ * calls cost one responses-contract query each.
20
+ */
21
+ export class SignetRequestResponseReader {
22
+ config;
23
+ // Request records never change once stored; cache them across calls.
24
+ requestCache = new Map();
25
+ /**
26
+ * @param config - The contract pair and state source to read through.
27
+ */
28
+ constructor(config) {
29
+ this.config = config;
30
+ }
31
+ /**
32
+ * Query one contract's raw state, throwing a uniform error when absent.
33
+ *
34
+ * @param contractAddress - The contract to query.
35
+ * @param role - Human name of the contract for the error message.
36
+ * @returns The raw ledger state tree.
37
+ * @throws Error when the address holds no contract state.
38
+ */
39
+ async queryRawState(contractAddress, role) {
40
+ const state = await this.config.publicDataProvider.queryContractState(contractAddress);
41
+ if (!state?.data) {
42
+ throw new Error(`no state data found for ${role} contract '${contractAddress}' - is it deployed?`);
43
+ }
44
+ return state.data;
45
+ }
46
+ /**
47
+ * Fetch the request record for `requestId` from the requester contract's
48
+ * ledger (request index, field 0 by the signet layout convention). Cached
49
+ * after the first fetch.
50
+ *
51
+ * @param requestId - The request id to look up.
52
+ * @returns The stored request record.
53
+ * @throws Error when the requester contract has no state or holds no
54
+ * request under `requestId`.
55
+ */
56
+ async getSignatureRequest(requestId) {
57
+ const cached = this.requestCache.get(requestId);
58
+ if (cached !== undefined) {
59
+ return cached;
60
+ }
61
+ const raw = await this.queryRawState(this.config.requesterContractAddress, "requester");
62
+ const { requestsIndex } = readSignetRequestsLedgerFromState(raw);
63
+ const request = requestsIndex.get(requestId);
64
+ if (request === undefined) {
65
+ throw new Error(`request ${requestId} is not on the requester contract's ledger — was it submitted?`);
66
+ }
67
+ this.requestCache.set(requestId, request);
68
+ return request;
69
+ }
70
+ /**
71
+ * Fetch every response posted for `requestId`, in post (count) order.
72
+ * UNVERIFIED — any of them may be garbage; see
73
+ * {@link getVerifiedSignatureResponse}.
74
+ *
75
+ * @param requestId - The request id whose posts to enumerate.
76
+ * @returns The posted payloads, index = count; empty when none yet.
77
+ * @throws Error when the responses contract has no state, or its counter
78
+ * disagrees with the log (inconsistent ledger).
79
+ */
80
+ async getSignatureResponses(requestId) {
81
+ const raw = await this.queryRawState(this.config.signetContractAddress, "signet contract");
82
+ const { signatureResponseCounterIndex, signatureResponseIndex } = readSignetContractLedgerFromState(raw);
83
+ const totalPosts = signatureResponseCounterIndex.get(requestId) ?? 0n;
84
+ const responses = [];
85
+ for (let count = 0n; count < totalPosts; count++) {
86
+ const response = signatureResponseIndex.get(signetResponseIndexKey(requestId, count));
87
+ if (response === undefined) {
88
+ throw new Error(`response log has no entry ${count} for request ${requestId} ` +
89
+ `despite its counter reading ${totalPosts} — ledger state is inconsistent`);
90
+ }
91
+ responses.push(response);
92
+ }
93
+ return responses;
94
+ }
95
+ /**
96
+ * Fetch and verify the responses posted for `requestId`: each post's
97
+ * `{ bigR, s, recoveryId }` signature must recover to `expectedSigner`
98
+ * (compared case-insensitively) over the signing hash of the transaction
99
+ * the request record describes. The first valid post wins; every post gets
100
+ * a verdict so callers can report the noise.
101
+ *
102
+ * @param requestId - The request id to fetch a verified response for.
103
+ * @param expectedSigner - The EVM address (0x hex, any case) the genuine
104
+ * response must be signed by — the requester's MPC-derived address.
105
+ * @returns The first valid response (if any) plus per-post verdicts.
106
+ * @throws Error when either contract has no state, the request is not on
107
+ * the requester's ledger, or the responses ledger is inconsistent.
108
+ */
109
+ async getVerifiedSignatureResponse(requestId, expectedSigner) {
110
+ const request = await this.getSignatureRequest(requestId);
111
+ const responses = await this.getSignatureResponses(requestId);
112
+ const verdicts = responses.map((response, index) => {
113
+ const count = BigInt(index);
114
+ let signer;
115
+ try {
116
+ signer = recoverSignatureResponseSigner(request, response);
117
+ }
118
+ catch (error) {
119
+ return {
120
+ count,
121
+ response,
122
+ rejectedReason: `not a decodable signature (${String(error)})`,
123
+ };
124
+ }
125
+ if (signer.toLowerCase() !== expectedSigner.toLowerCase()) {
126
+ return {
127
+ count,
128
+ response,
129
+ signer,
130
+ rejectedReason: `signed by ${signer}, expected ${expectedSigner}`,
131
+ };
132
+ }
133
+ return { count, response, signer };
134
+ });
135
+ return {
136
+ verified: verdicts.find((v) => v.rejectedReason === undefined)?.response,
137
+ verdicts,
138
+ };
139
+ }
140
+ /**
141
+ * Rebuild the unsigned EIP-1559 transaction for `requestId` — the exact
142
+ * transaction the MPC signs, assembled from the request record's decomposed
143
+ * fields. No responses-contract query: this needs only the request record
144
+ * (fetched via {@link getSignatureRequest}, cached).
145
+ *
146
+ * @param requestId - The request id whose transaction to rebuild.
147
+ * @returns The unsigned ethers transaction (`unsignedHash` is the MPC's
148
+ * signing digest).
149
+ * @throws Error when the requester contract has no state or holds no
150
+ * request under `requestId`.
151
+ */
152
+ async getUnsignedEVMTransaction(requestId) {
153
+ return signBidirectionalRequestToUnsignedEVMTransaction(await this.getSignatureRequest(requestId));
154
+ }
155
+ /**
156
+ * Assemble the broadcast-ready signed EIP-1559 transaction for `requestId`:
157
+ * rebuild the request's transaction and attach the first VERIFIED response
158
+ * signed by `expectedSigner` (see {@link getVerifiedSignatureResponse} — the
159
+ * response log is unauthenticated, so an `expectedSigner` is required and
160
+ * unverified posts are never attached).
161
+ *
162
+ * @param requestId - The request id to produce a signed transaction for.
163
+ * @param expectedSigner - The EVM address (0x hex, any case) the genuine
164
+ * response must be signed by — the requester's MPC-derived address.
165
+ * @returns The signed ethers transaction (`serialized` is the payload for
166
+ * `eth_sendRawTransaction`), or `undefined` when no valid response has
167
+ * been posted yet — poll again.
168
+ * @throws Error when either contract has no state, the request is not on the
169
+ * requester's ledger, or the responses ledger is inconsistent.
170
+ */
171
+ async getSignedEVMTransaction(requestId, expectedSigner) {
172
+ const { verified } = await this.getVerifiedSignatureResponse(requestId, expectedSigner);
173
+ if (verified === undefined) {
174
+ return undefined;
175
+ }
176
+ // getSignatureRequest is cached — getVerifiedSignatureResponse already
177
+ // fetched it, so this is a free lookup, not a second query.
178
+ const request = await this.getSignatureRequest(requestId);
179
+ return signBidirectionalRequestToSignedEVMTransaction(request, verified);
180
+ }
181
+ /**
182
+ * Fetch the MPC's respond-bidirectional attestation for `requestId`,
183
+ * if posted. The signet contract verified it IN-CIRCUIT at post time
184
+ * (Schnorr over `(requestId, hash(serializedOutput, outputLen))` against
185
+ * the sealed MPC key), so it is single-slot and needs no off-chain
186
+ * verification or verdicts — `undefined` simply means not posted yet, poll
187
+ * again.
188
+ *
189
+ * @param requestId - The request id whose attestation to fetch.
190
+ * @returns The attestation record, or `undefined` when none is posted.
191
+ * @throws Error when the signet contract has no state on-chain.
192
+ */
193
+ async getRespondBidirectional(requestId) {
194
+ const raw = await this.queryRawState(this.config.signetContractAddress, "signet contract");
195
+ return readSignetContractLedgerFromState(raw).respondBidirectionalIndex.get(requestId);
196
+ }
197
+ }
198
+ //# sourceMappingURL=signet-request-response-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signet-request-response-reader.js","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"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"}