@sig-net/midnight 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +113 -49
  2. package/dist/constants.d.ts +55 -0
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +85 -5
  5. package/dist/constants.js.map +1 -1
  6. package/dist/ecdsa-attestation.d.ts +6 -5
  7. package/dist/ecdsa-attestation.d.ts.map +1 -1
  8. package/dist/ecdsa-attestation.js +5 -4
  9. package/dist/ecdsa-attestation.js.map +1 -1
  10. package/dist/index.d.ts +1 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -4
  13. package/dist/index.js.map +1 -1
  14. package/dist/managed/compiler/contract-manifest.json +2 -2
  15. package/dist/managed/contract/index.js +31 -31
  16. package/dist/managed/contract/index.js.map +1 -1
  17. package/dist/signature-requests-state-reader.d.ts +23 -5
  18. package/dist/signature-requests-state-reader.d.ts.map +1 -1
  19. package/dist/signature-requests-state-reader.js +50 -5
  20. package/dist/signature-requests-state-reader.js.map +1 -1
  21. package/dist/signature-response-verification.d.ts +1 -1
  22. package/dist/signature-response-verification.d.ts.map +1 -1
  23. package/dist/signature-response-verification.js +3 -3
  24. package/dist/signature-response-verification.js.map +1 -1
  25. package/dist/signature-state-reading.js +2 -2
  26. package/dist/signature-state-reading.js.map +1 -1
  27. package/dist/signet-contract-events.d.ts +262 -0
  28. package/dist/signet-contract-events.d.ts.map +1 -0
  29. package/dist/signet-contract-events.js +266 -0
  30. package/dist/signet-contract-events.js.map +1 -0
  31. package/dist/signet-evtype2tx-requests.d.ts +4 -4
  32. package/dist/signet-evtype2tx-requests.d.ts.map +1 -1
  33. package/dist/signet-evtype2tx-requests.js +3 -3
  34. package/dist/signet-request-feed.d.ts +59 -34
  35. package/dist/signet-request-feed.d.ts.map +1 -1
  36. package/dist/signet-request-feed.js +95 -62
  37. package/dist/signet-request-feed.js.map +1 -1
  38. package/dist/signet-request-response-reader.d.ts +62 -55
  39. package/dist/signet-request-response-reader.d.ts.map +1 -1
  40. package/dist/signet-request-response-reader.js +85 -99
  41. package/dist/signet-request-response-reader.js.map +1 -1
  42. package/dist/signet-requests.js +2 -2
  43. package/dist/signet-requests.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/Signet.compact +43 -36
  46. package/dist/signet-contract-state-reader.d.ts +0 -247
  47. package/dist/signet-contract-state-reader.d.ts.map +0 -1
  48. package/dist/signet-contract-state-reader.js +0 -363
  49. package/dist/signet-contract-state-reader.js.map +0 -1
  50. package/dist/signet-request-resolver.d.ts +0 -60
  51. package/dist/signet-request-resolver.d.ts.map +0 -1
  52. package/dist/signet-request-resolver.js +0 -78
  53. package/dist/signet-request-resolver.js.map +0 -1
@@ -1,22 +1,42 @@
1
- import { type ResolvedSignetRequest } from "./signet-request-resolver.ts";
1
+ import { type SignetEventSource } from "./signet-contract-events.ts";
2
2
  import type { SignetPublicStateSource } from "./signet-request-response-reader.ts";
3
- import { type RequestIdHex } from "./signet-requests.ts";
3
+ import { type RequestIdHex, type SignBidirectionalEvent } from "./signet-requests.ts";
4
4
  /** Default gap between poll cycles of {@link SignetRequestFeed.requests}. */
5
5
  export declare const DEFAULT_FEED_POLL_INTERVAL_MS = 3000;
6
+ /**
7
+ * A request discovered through a notification event and read from the named
8
+ * caller's own authenticated ledger.
9
+ */
10
+ export interface ResolvedSignetRequest {
11
+ /**
12
+ * The contract whose authenticated state the request was read from: the
13
+ * epsilon-derivation predecessor. Key derivation keys off THIS, never off a
14
+ * field taken from the notification on faith.
15
+ */
16
+ callerAddress: string;
17
+ /** The request id the record is stored under in `callerAddress`'s index. */
18
+ requestId: RequestIdHex;
19
+ /** The authenticated request record to sign. */
20
+ request: SignBidirectionalEvent;
21
+ }
6
22
  /** Everything a {@link SignetRequestFeed} needs. */
7
23
  export interface SignetRequestFeedConfig {
8
- /** Address of the central signet contract whose notification registry to poll. */
24
+ /** Address of the central signet contract whose notification events to poll. */
9
25
  readonly signetContractAddress: string;
10
26
  /**
11
- * Source of raw contract state for BOTH the signet contract's registry and
12
- * the requester ledgers the resolver authenticates against — a full
13
- * `indexerPublicDataProvider` is assignable.
27
+ * Source of raw contract state for the requester ledgers the feed
28
+ * enumerates. A full `indexerPublicDataProvider` is assignable.
14
29
  */
15
30
  readonly source: SignetPublicStateSource;
31
+ /**
32
+ * Source of the signet contract's emitted events (discovery). Adapt a full
33
+ * provider with `signetEventSourceFromPublicDataProvider`.
34
+ */
35
+ readonly eventSource: SignetEventSource;
16
36
  /**
17
37
  * Optional policy allow-list of requester contract addresses to serve
18
38
  * (matched case- and `0x`-prefix-insensitively). Omit to serve every
19
- * requester the resolver can authenticate. NOT a security control.
39
+ * requester a notification points at. NOT a security control.
20
40
  */
21
41
  readonly allowContracts?: Iterable<string>;
22
42
  /** Poll cadence for {@link SignetRequestFeed.requests}; default {@link DEFAULT_FEED_POLL_INTERVAL_MS}. */
@@ -32,51 +52,56 @@ export interface SignetRequestFeedConfig {
32
52
  */
33
53
  export declare function sleepUnlessAborted(ms: number, signal?: AbortSignal): Promise<void>;
34
54
  /**
35
- * The registry-polling request feed. Reads the signet contract's notification
36
- * registry (discovery) and hands each notification to a
37
- * {@link SignetRequestResolver} (authentication), yielding only notifications
38
- * that resolve to a real, member request. Dedupes by request id across its
39
- * lifetime, so a re-registered notification is not re-yielded; call
40
- * {@link forget} to re-arm a request whose downstream processing failed.
55
+ * The event-polling request feed. Reads the signet contract's emitted
56
+ * notifications (discovery) and enumerates each pointed-at caller's own
57
+ * request map (authentication by construction: the records come from the
58
+ * caller's ledger), yielding each member request once. Dedupes by request id
59
+ * across its lifetime, so a re-notified or still-pending request is not
60
+ * re-yielded. Call {@link forget} to re-arm a request whose downstream
61
+ * processing failed.
41
62
  */
42
63
  export declare class SignetRequestFeed {
43
64
  private readonly signetContractAddress;
44
65
  private readonly source;
45
- private readonly resolver;
66
+ private readonly eventSource;
46
67
  private readonly allowContracts?;
47
68
  private readonly pollIntervalMs;
48
69
  private readonly yielded;
49
70
  /**
50
- * @param config - The signet contract, state source, and optional policy
51
- * allow-list.
71
+ * @param config - The signet contract, state and event sources, and
72
+ * optional policy allow-list.
52
73
  */
53
74
  constructor(config: SignetRequestFeedConfig);
54
75
  /** Whether the policy allow-list admits `callerAddress` (always true when unset). */
55
76
  private allowed;
56
77
  /**
57
- * One-shot: every currently-registered notification that decodes, is
58
- * admitted by the allow-list, not already yielded, and resolves to an
59
- * authenticated member request. Registry enumeration has no meaningful
60
- * on-ledger order, so entries are processed in ascending request-id-hex
61
- * order — a stable, deterministic sequence. Forged / not-yet-indexed /
62
- * wrong-field notifications resolve to nothing and are dropped WITHOUT
63
- * being marked yielded, so a genuine request whose ledger write has not
64
- * indexed yet is retried next cycle; undecodable or unsupported-version
65
- * records are likewise skipped (and logged) without being marked.
78
+ * The unique `(callerAddress, requestsPath)` pointers of the currently
79
+ * emitted notification events, allow-list applied, in ascending
80
+ * caller-address order (event enumeration order is per-source, so a
81
+ * stable sort keeps the poll deterministic). Undecodable or
82
+ * unsupported-version events are skipped (and logged): they carry no
83
+ * request, so nothing is lost.
66
84
  *
67
- * Dedupe and resolution key off the request id of the registry entry's map
68
- * key (the V1 payload no longer carries one). The key is caller-supplied,
69
- * so it confers no authority — the resolver's membership check against the
70
- * named caller's own ledger is what authenticates it.
85
+ * @returns The deduplicated pointers to enumerate this cycle.
86
+ */
87
+ private notificationPointers;
88
+ /**
89
+ * One-shot: every request in a notified caller's request map that is
90
+ * admitted by the allow-list and not already yielded. Within one caller's
91
+ * map, requests are processed in ascending request-id-hex order: a
92
+ * stable, deterministic sequence. A pointer at a caller with no readable
93
+ * state, or at a field that is not a request map, yields nothing WITHOUT
94
+ * marking anything, so a genuine request whose ledger write has not
95
+ * indexed yet is retried next cycle.
71
96
  *
72
- * @returns The newly-authenticated requests this cycle.
73
- * @throws Error if the signet contract has no readable state at the
74
- * configured address (wrong address or not yet deployed/indexed).
97
+ * @returns The newly-discovered authenticated requests this cycle.
98
+ * @throws Error when the event source itself fails (e.g. the indexer is
99
+ * unreachable).
75
100
  */
76
101
  poll(): Promise<ResolvedSignetRequest[]>;
77
102
  /**
78
103
  * Re-arm `requestId` for redelivery on the next {@link poll} / {@link requests}
79
- * cycle — call when downstream processing of a yielded request failed, so it
104
+ * cycle: call when downstream processing of a yielded request failed, so it
80
105
  * is retried (mirrors the MPC's delete-on-failure of its processed set).
81
106
  *
82
107
  * @param requestId - The request id to allow through again.
@@ -85,7 +110,7 @@ export declare class SignetRequestFeed {
85
110
  /**
86
111
  * Live stream: poll + sleep, yielding each authenticated request exactly once
87
112
  * (subject to {@link forget}), until `opts.signal` aborts. The natural
88
- * sequential `for await` consumption serializes downstream processing — no
113
+ * sequential `for await` consumption serializes downstream processing: no
89
114
  * two requests are handed over concurrently.
90
115
  *
91
116
  * @param opts.signal - Abort to stop the stream.
@@ -1 +1 @@
1
- {"version":3,"file":"signet-request-feed.d.ts","sourceRoot":"","sources":["../src/signet-request-feed.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC,kFAAkF;IAClF,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,0GAA0G;IAC1G,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAaf;AAOD;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAIxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD;;;OAGG;gBACS,MAAM,EAAE,uBAAuB;IAW3C,qFAAqF;IACrF,OAAO,CAAC,OAAO;IAOf;;;;;;;;;;;;;;;;;;;OAmBG;IACG,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAqC9C;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAIrC;;;;;;;;OAQG;IACI,QAAQ,CAAC,IAAI,CAAC,EAAE;QACrB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;CAQjD"}
1
+ {"version":3,"file":"signet-request-feed.d.ts","sourceRoot":"","sources":["../src/signet-request-feed.ts"],"names":[],"mappings":"AAmBA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAE9B,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,SAAS,EAAE,YAAY,CAAC;IACxB,gDAAgD;IAChD,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC,gFAAgF;IAChF,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,0GAA0G;IAC1G,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAaf;AAOD;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAIxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD;;;OAGG;gBACS,MAAM,EAAE,uBAAuB;IAW3C,qFAAqF;IACrF,OAAO,CAAC,OAAO;IAOf;;;;;;;;;OASG;YACW,oBAAoB;IAyClC;;;;;;;;;;;;OAYG;IACG,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IA+B9C;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAIrC;;;;;;;;OAQG;IACI,QAAQ,CAAC,IAAI,CAAC,EAAE;QACrB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC;CAQjD"}
@@ -1,19 +1,24 @@
1
1
  // The MPC's single entry point for discovering signature requests: poll the
2
- // central signet contract's notification registry (ledger field 4), resolve
3
- // each notification to an AUTHENTICATED request read from the named caller's
4
- // own ledger, and yield only the ones that pass the membership check. The
5
- // registry is append-only with no on-ledger cursor, so the feed's in-memory
6
- // `yielded` set is the diff cursor: every poll enumerates the registry and
7
- // serves what it has not served before.
2
+ // central signet contract's emitted SignBidirectionalEvent notifications,
3
+ // follow each to the named caller contract, and enumerate the AUTHENTICATED
4
+ // requests in that caller's own request map. A notification is a doorbell,
5
+ // never an authority: it says only WHERE to look (caller address + the
6
+ // resolved ledger-tree path of its request map), and every request served
7
+ // comes from the named caller's own ledger. An attacker cannot write into a
8
+ // contract it does not control, so a forged notification can at most
9
+ // re-point at a legitimate caller's map, never inject a request.
10
+ //
11
+ // The event log has no on-ledger cursor the feed consumes, so the feed's
12
+ // in-memory `yielded` set is the diff cursor: every poll enumerates the
13
+ // pointed-at maps and serves what it has not served before.
8
14
  //
9
15
  // The requester allow-list is an OPTIONAL policy filter here (drop requests
10
16
  // from contracts you choose not to serve), never a security requirement and
11
- // never the discovery mechanism — attribution comes from the resolver's
12
- // authenticated read (see signet-request-resolver.ts and
13
- // knowledge-base/caller-attribution.md).
14
- import { decodeSignBidirectionalNotification, readSignBidirectionalNotificationIndexFromState, } from "./signet-contract-state-reader.js";
15
- import { SignetRequestResolver, } from "./signet-request-resolver.js";
16
- import { stripHexPrefix } from "./signet-requests.js";
17
+ // never the discovery mechanism: attribution comes from reading the
18
+ // caller's authenticated state.
19
+ import { decodeSignBidirectionalEventNotificationPayload, decodeSignBidirectionalNotification, SignetEventName, } from "./signet-contract-events.js";
20
+ import { readSignetRequestIndexAt } from "./signature-requests-state-reader.js";
21
+ import { stripHexPrefix, } from "./signet-requests.js";
17
22
  /** Default gap between poll cycles of {@link SignetRequestFeed.requests}. */
18
23
  export const DEFAULT_FEED_POLL_INTERVAL_MS = 3000;
19
24
  /**
@@ -44,30 +49,31 @@ function normalizeAddress(address) {
44
49
  return stripHexPrefix(address).toLowerCase();
45
50
  }
46
51
  /**
47
- * The registry-polling request feed. Reads the signet contract's notification
48
- * registry (discovery) and hands each notification to a
49
- * {@link SignetRequestResolver} (authentication), yielding only notifications
50
- * that resolve to a real, member request. Dedupes by request id across its
51
- * lifetime, so a re-registered notification is not re-yielded; call
52
- * {@link forget} to re-arm a request whose downstream processing failed.
52
+ * The event-polling request feed. Reads the signet contract's emitted
53
+ * notifications (discovery) and enumerates each pointed-at caller's own
54
+ * request map (authentication by construction: the records come from the
55
+ * caller's ledger), yielding each member request once. Dedupes by request id
56
+ * across its lifetime, so a re-notified or still-pending request is not
57
+ * re-yielded. Call {@link forget} to re-arm a request whose downstream
58
+ * processing failed.
53
59
  */
54
60
  export class SignetRequestFeed {
55
61
  signetContractAddress;
56
62
  source;
57
- resolver;
63
+ eventSource;
58
64
  allowContracts;
59
65
  pollIntervalMs;
60
- // Request ids already yielded. NOT the security boundary (the resolver is) —
61
- // just an at-most-once gate so one request is not processed twice.
66
+ // Request ids already yielded. NOT the security boundary (the caller-ledger
67
+ // read is), just an at-most-once gate so one request is not processed twice.
62
68
  yielded = new Set();
63
69
  /**
64
- * @param config - The signet contract, state source, and optional policy
65
- * allow-list.
70
+ * @param config - The signet contract, state and event sources, and
71
+ * optional policy allow-list.
66
72
  */
67
73
  constructor(config) {
68
74
  this.signetContractAddress = config.signetContractAddress;
69
75
  this.source = config.source;
70
- this.resolver = new SignetRequestResolver({ source: config.source });
76
+ this.eventSource = config.eventSource;
71
77
  this.allowContracts = config.allowContracts
72
78
  ? new Set(Array.from(config.allowContracts, normalizeAddress))
73
79
  : undefined;
@@ -80,58 +86,85 @@ export class SignetRequestFeed {
80
86
  this.allowContracts.has(normalizeAddress(callerAddress)));
81
87
  }
82
88
  /**
83
- * One-shot: every currently-registered notification that decodes, is
84
- * admitted by the allow-list, not already yielded, and resolves to an
85
- * authenticated member request. Registry enumeration has no meaningful
86
- * on-ledger order, so entries are processed in ascending request-id-hex
87
- * order — a stable, deterministic sequence. Forged / not-yet-indexed /
88
- * wrong-field notifications resolve to nothing and are dropped WITHOUT
89
- * being marked yielded, so a genuine request whose ledger write has not
90
- * indexed yet is retried next cycle; undecodable or unsupported-version
91
- * records are likewise skipped (and logged) without being marked.
92
- *
93
- * Dedupe and resolution key off the request id of the registry entry's map
94
- * key (the V1 payload no longer carries one). The key is caller-supplied,
95
- * so it confers no authority — the resolver's membership check against the
96
- * named caller's own ledger is what authenticates it.
89
+ * The unique `(callerAddress, requestsPath)` pointers of the currently
90
+ * emitted notification events, allow-list applied, in ascending
91
+ * caller-address order (event enumeration order is per-source, so a
92
+ * stable sort keeps the poll deterministic). Undecodable or
93
+ * unsupported-version events are skipped (and logged): they carry no
94
+ * request, so nothing is lost.
97
95
  *
98
- * @returns The newly-authenticated requests this cycle.
99
- * @throws Error if the signet contract has no readable state at the
100
- * configured address (wrong address or not yet deployed/indexed).
96
+ * @returns The deduplicated pointers to enumerate this cycle.
101
97
  */
102
- async poll() {
103
- const state = await this.source.queryContractState(this.signetContractAddress);
104
- if (!state?.data) {
105
- throw new Error(`No contract state at signet contract ${this.signetContractAddress} ` +
106
- `— wrong address, or not yet deployed/indexed`);
107
- }
108
- const registry = readSignBidirectionalNotificationIndexFromState(state.data);
109
- const out = [];
110
- for (const [requestId, record] of [...registry.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
98
+ async notificationPointers() {
99
+ const events = await this.eventSource.querySignetEvents(this.signetContractAddress);
100
+ const pointers = new Map();
101
+ for (const event of events) {
102
+ if (event.name !== SignetEventName.SignBidirectionalEvent)
103
+ continue;
111
104
  let notification;
112
105
  try {
113
- notification = decodeSignBidirectionalNotification(record);
106
+ notification = decodeSignBidirectionalNotification(decodeSignBidirectionalEventNotificationPayload(event.payload));
114
107
  }
115
108
  catch (error) {
116
- console.warn(`SignetRequestFeed: skipping undecodable notification ` +
117
- `registered under ${requestId}: ${String(error)}`);
109
+ console.warn(`SignetRequestFeed: skipping undecodable notification event: ${String(error)}`);
118
110
  continue;
119
111
  }
120
- if (this.yielded.has(requestId))
121
- continue;
122
112
  if (!this.allowed(notification.callerAddress))
123
113
  continue;
124
- const resolved = await this.resolver.resolve(requestId, notification);
125
- if (resolved === undefined)
126
- continue;
127
- this.yielded.add(requestId);
128
- out.push(resolved);
114
+ pointers.set(`${notification.callerAddress}:${notification.requestsPath.join(",")}`, {
115
+ callerAddress: notification.callerAddress,
116
+ requestsPath: notification.requestsPath,
117
+ });
118
+ }
119
+ return [...pointers.values()].sort((a, b) => a.callerAddress < b.callerAddress
120
+ ? -1
121
+ : a.callerAddress > b.callerAddress
122
+ ? 1
123
+ : 0);
124
+ }
125
+ /**
126
+ * One-shot: every request in a notified caller's request map that is
127
+ * admitted by the allow-list and not already yielded. Within one caller's
128
+ * map, requests are processed in ascending request-id-hex order: a
129
+ * stable, deterministic sequence. A pointer at a caller with no readable
130
+ * state, or at a field that is not a request map, yields nothing WITHOUT
131
+ * marking anything, so a genuine request whose ledger write has not
132
+ * indexed yet is retried next cycle.
133
+ *
134
+ * @returns The newly-discovered authenticated requests this cycle.
135
+ * @throws Error when the event source itself fails (e.g. the indexer is
136
+ * unreachable).
137
+ */
138
+ async poll() {
139
+ const out = [];
140
+ for (const pointer of await this.notificationPointers()) {
141
+ let state;
142
+ try {
143
+ state = await this.source.queryContractState(pointer.callerAddress);
144
+ }
145
+ catch {
146
+ continue; // caller address not a contract / transient read error
147
+ }
148
+ if (!state?.data) {
149
+ continue; // no state at the named caller: nothing to serve yet
150
+ }
151
+ const index = readSignetRequestIndexAt(state.data, pointer.requestsPath);
152
+ for (const [requestId, request] of [...index.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
153
+ if (this.yielded.has(requestId))
154
+ continue;
155
+ this.yielded.add(requestId);
156
+ out.push({
157
+ callerAddress: pointer.callerAddress,
158
+ requestId,
159
+ request,
160
+ });
161
+ }
129
162
  }
130
163
  return out;
131
164
  }
132
165
  /**
133
166
  * Re-arm `requestId` for redelivery on the next {@link poll} / {@link requests}
134
- * cycle — call when downstream processing of a yielded request failed, so it
167
+ * cycle: call when downstream processing of a yielded request failed, so it
135
168
  * is retried (mirrors the MPC's delete-on-failure of its processed set).
136
169
  *
137
170
  * @param requestId - The request id to allow through again.
@@ -142,7 +175,7 @@ export class SignetRequestFeed {
142
175
  /**
143
176
  * Live stream: poll + sleep, yielding each authenticated request exactly once
144
177
  * (subject to {@link forget}), until `opts.signal` aborts. The natural
145
- * sequential `for await` consumption serializes downstream processing — no
178
+ * sequential `for await` consumption serializes downstream processing: no
146
179
  * two requests are handed over concurrently.
147
180
  *
148
181
  * @param opts.signal - Abort to stop the stream.
@@ -1 +1 @@
1
- {"version":3,"file":"signet-request-feed.js","sourceRoot":"","sources":["../src/signet-request-feed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signet-request-feed.js","sourceRoot":"","sources":["../src/signet-request-feed.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { PublicDataProvider } from "@midnight-ntwrk/midnight-js-types";
2
2
  import type { Transaction } from "ethers";
3
- import { type SignatureRespondedEvent, type RespondBidirectionalEvent } from "./signet-contract-state-reader.ts";
3
+ import { type SignetEventSource, type SignatureRespondedEvent, type RespondBidirectionalEvent } from "./signet-contract-events.ts";
4
4
  import { type Secp256k1Point } from "./ecdsa-attestation.ts";
5
5
  import type { RawContractState } from "./signature-state-reading.ts";
6
6
  import { type SignBidirectionalEvent, type RequestIdHex } from "./signet-requests.ts";
@@ -38,11 +38,16 @@ export interface SignetRequestResponseReaderConfig {
38
38
  readonly signetContractAddress: string;
39
39
  /** Source of raw contract state, e.g. midnight-js's `indexerPublicDataProvider`. */
40
40
  readonly publicDataProvider: SignetPublicStateSource;
41
+ /**
42
+ * Source of the signet contract's emitted events. Adapt a full provider
43
+ * with `signetEventSourceFromPublicDataProvider`.
44
+ */
45
+ readonly eventSource: SignetEventSource;
41
46
  }
42
- /** The verdict on one posted response, in `count` order. */
47
+ /** The verdict on one emitted response, in emission order. */
43
48
  export interface SignatureResponseVerdict {
44
- /** 0-based position of the post in the request's response log. */
45
- count: bigint;
49
+ /** 0-based position of the post among the request's signature-response events. */
50
+ index: bigint;
46
51
  /** The posted signature record, verbatim. */
47
52
  response: SignatureRespondedEvent;
48
53
  /** Recovered signer address, absent when the signature did not decode. */
@@ -53,13 +58,13 @@ export interface SignatureResponseVerdict {
53
58
  /** Result of {@link SignetRequestResponseReader['getVerifiedSignatureRespondedEvent']}. */
54
59
  export interface VerifiedSignatureResponseResult {
55
60
  /**
56
- * The first valid response (lowest count), or `undefined` when no valid
61
+ * The first valid response (lowest index), or `undefined` when no valid
57
62
  * response has been posted yet: poll again.
58
63
  */
59
64
  verified?: SignatureRespondedEvent;
60
65
  /**
61
- * One verdict per post, count order. Pure data: the reader never logs, so
62
- * callers decide how to surface rejected posts.
66
+ * One verdict per post, emission order. Pure data: the reader never logs,
67
+ * so callers decide how to surface rejected posts.
63
68
  */
64
69
  verdicts: SignatureResponseVerdict[];
65
70
  }
@@ -67,24 +72,16 @@ export interface VerifiedSignatureResponseResult {
67
72
  * Reader over one requester contract / signet contract pair.
68
73
  * Construct once per pair and reuse: fetched request records are cached (they
69
74
  * are immutable, the ledger key is their hash), so repeated verification
70
- * calls cost one responses-contract query each.
75
+ * calls cost one event query each.
71
76
  */
72
77
  export declare class SignetRequestResponseReader {
73
78
  private readonly config;
74
79
  private readonly requestCache;
75
80
  /**
76
- * @param config - The contract pair and state source to read through.
81
+ * @param config - The contract pair, state source and event source to read
82
+ * through.
77
83
  */
78
84
  constructor(config: SignetRequestResponseReaderConfig);
79
- /**
80
- * Query one contract's raw state, throwing a uniform error when absent.
81
- *
82
- * @param contractAddress - The contract to query.
83
- * @param role - Human name of the contract for the error message.
84
- * @returns The raw ledger state tree.
85
- * @throws Error when the address holds no contract state.
86
- */
87
- private queryRawState;
88
85
  /**
89
86
  * Fetch the request record for `requestId` from the requester contract's
90
87
  * request index (at the configured `requesterRequestsPath`). Cached
@@ -97,35 +94,49 @@ export declare class SignetRequestResponseReader {
97
94
  */
98
95
  getSignatureRequest(requestId: RequestIdHex): Promise<SignBidirectionalEvent>;
99
96
  /**
100
- * Fetch every response posted for `requestId`, in post (count) order.
101
- * UNVERIFIED: any of them may be garbage (see
102
- * {@link getVerifiedSignatureRespondedEvent}).
97
+ * Fetch every event of `name` the signet contract has emitted, decode each
98
+ * with `decode`, and keep the posts whose declared request id is
99
+ * `requestId`, in emission order. The declared id is routing data only:
100
+ * the verified getters run the actual authenticity checks.
101
+ *
102
+ * @param name - The signet event name to keep.
103
+ * @param decode - The payload decoder for that event kind.
104
+ * @param requestId - The request id the kept posts must declare.
105
+ * @returns The kept posts' records, oldest first.
106
+ */
107
+ private getRespondPostsNamed;
108
+ /**
109
+ * Fetch every signature response posted under `requestId`, in emission
110
+ * order. UNVERIFIED: the declared id is routing data on an unauthenticated
111
+ * event log, so any post may still be garbage (see
112
+ * {@link getVerifiedSignatureRespondedEvent}, where verification
113
+ * establishes authenticity).
103
114
  *
104
- * @param requestId - The request id whose posts to enumerate.
105
- * @returns The posted payloads, index = count, empty when none yet.
106
- * @throws Error when the responses contract has no state, or its counter
107
- * disagrees with the log (inconsistent ledger).
115
+ * @param requestId - The request id the posts must declare.
116
+ * @returns The request's posted records, oldest first, empty when none yet.
108
117
  */
109
- getSignatureResponses(requestId: RequestIdHex): Promise<SignatureRespondedEvent[]>;
118
+ getSignatureRespondedEvents(requestId: RequestIdHex): Promise<SignatureRespondedEvent[]>;
110
119
  /**
111
- * Fetch and verify the responses posted for `requestId`: each post's
112
- * signature must recover to `expectedSigner`
113
- * (compared case-insensitively) over the signing hash of the transaction
114
- * the request record describes. The first valid post wins, and every post
115
- * gets a verdict so callers can report the noise.
120
+ * Fetch the signature responses posted under `requestId` and verify each
121
+ * against the request: a post's signature must recover to
122
+ * `expectedSigner` (compared case-insensitively) over the signing hash of
123
+ * the transaction the request record describes. The first valid post wins,
124
+ * and every candidate gets a verdict so callers can report the noise. The
125
+ * declared id only routes: this verification is what separates the genuine
126
+ * response from garbage posted under the same id.
116
127
  *
117
128
  * @param requestId - The request id to fetch a verified response for.
118
129
  * @param expectedSigner - The EVM address (0x hex, any case) the genuine
119
130
  * response must be signed by: the requester's MPC-derived address.
120
131
  * @returns The first valid response (if any) plus per-post verdicts.
121
- * @throws Error when either contract has no state, the request is not on
122
- * the requester's ledger, or the responses ledger is inconsistent.
132
+ * @throws Error when the requester contract has no state or the request is
133
+ * not on its ledger.
123
134
  */
124
135
  getVerifiedSignatureRespondedEvent(requestId: RequestIdHex, expectedSigner: string): Promise<VerifiedSignatureResponseResult>;
125
136
  /**
126
137
  * Rebuild the unsigned EIP-1559 transaction for `requestId`: the exact
127
138
  * transaction the MPC signs, assembled from the request record's decomposed
128
- * fields. No responses-contract query: this needs only the request record
139
+ * fields. No event query: this needs only the request record
129
140
  * (fetched via {@link getSignatureRequest}, cached).
130
141
  *
131
142
  * @param requestId - The request id whose transaction to rebuild.
@@ -139,7 +150,7 @@ export declare class SignetRequestResponseReader {
139
150
  * Assemble the broadcast-ready signed EIP-1559 transaction for `requestId`:
140
151
  * rebuild the request's transaction and attach the first VERIFIED response
141
152
  * signed by `expectedSigner` (see {@link getVerifiedSignatureRespondedEvent}:
142
- * the response log is unauthenticated, so an `expectedSigner` is required
153
+ * the event log is unauthenticated, so an `expectedSigner` is required
143
154
  * and unverified posts are never attached).
144
155
  *
145
156
  * @param requestId - The request id to produce a signed transaction for.
@@ -148,47 +159,43 @@ export declare class SignetRequestResponseReader {
148
159
  * @returns The signed ethers transaction (`serialized` is the payload for
149
160
  * `eth_sendRawTransaction`), or `undefined` when no valid response has
150
161
  * been posted yet: poll again.
151
- * @throws Error when either contract has no state, the request is not on the
152
- * requester's ledger, or the responses ledger is inconsistent.
162
+ * @throws Error when the requester contract has no state or the request is
163
+ * not on its ledger.
153
164
  */
154
165
  getSignedEvmTransaction(requestId: RequestIdHex, expectedSigner: string): Promise<Transaction | undefined>;
155
166
  /**
156
- * Fetch every respond-bidirectional response posted for `requestId`, in
157
- * post (count) order. UNVERIFIED: the signet contract stores posts without
158
- * checking them, so any entry may be garbage. Each post carries a signature
159
- * and nothing else, so verifying it against the MPC response key you expect
160
- * is the only way to pick the genuine one: in-circuit at claim time, or off
161
- * chain with {@link verifyRespondBidirectionalSignature} over the output you
162
- * fetched. An empty array simply means none posted yet: poll again.
167
+ * Fetch every respond-bidirectional response posted under `requestId`, in
168
+ * emission order. UNVERIFIED: the declared id is routing data on an
169
+ * unauthenticated event log, so verifying a post against the MPC response
170
+ * key you expect is still the only way to pick the genuine one: in-circuit
171
+ * at claim time, or off chain with
172
+ * {@link verifyRespondBidirectionalSignature} over the output you fetched.
173
+ * An empty array simply means none posted yet: poll again.
163
174
  *
164
- * @param requestId - The request id whose responses to enumerate.
165
- * @returns The posted records, index = count, empty when none yet.
166
- * @throws Error when the signet contract has no state, or its counter
167
- * disagrees with the log (inconsistent ledger).
175
+ * @param requestId - The request id the posts must declare.
176
+ * @returns The request's posted records, oldest first, empty when none yet.
168
177
  */
169
178
  getRespondBidirectionalEvents(requestId: RequestIdHex): Promise<RespondBidirectionalEvent[]>;
170
179
  /**
171
- * Fetch the respond-bidirectional posts for `requestId` and return the
172
- * first (lowest count) one whose signature verifies over
180
+ * Fetch the respond-bidirectional posts declared under `requestId` and
181
+ * return the first (oldest) one whose signature verifies over
173
182
  * `serializedOutput` against `mpcResponseKey`: the off-chain twin of the
174
183
  * check the client contract runs in-circuit, and the only way to pick a
175
- * genuine post out of an unauthenticated log now that posts carry nothing
176
- * but a signature.
184
+ * genuine post out of an unauthenticated event log.
177
185
  *
178
186
  * The output must be the exact unpadded bytes the attestation commits to
179
187
  * (the packed respond payload, recomputed from the execution output the
180
188
  * client fetched), so a post that verifies here is the post that proves at
181
189
  * claim time.
182
190
  *
183
- * @param requestId - The request id to fetch a verified attestation for.
191
+ * @param requestId - The request id the posts must declare and the
192
+ * attestation must commit to.
184
193
  * @param serializedOutput - The serialised execution output the attestation
185
194
  * must commit to, exact unpadded bytes.
186
195
  * @param mpcResponseKey - The MPC response key the requesting contract
187
196
  * pinned at deploy (see `deriveMidnightResponseKey`).
188
197
  * @returns The first verifying post, or `undefined` when none has been
189
198
  * posted yet (poll again) or none attests this output.
190
- * @throws Error when the signet contract has no state, or its counter
191
- * disagrees with the log (inconsistent ledger).
192
199
  */
193
200
  getVerifiedRespondBidirectionalEvent(requestId: RequestIdHex, serializedOutput: Uint8Array, mpcResponseKey: Secp256k1Point): Promise<RespondBidirectionalEvent | undefined>;
194
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"signet-request-response-reader.d.ts","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signet-request-response-reader.d.ts","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"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"}