@sig-net/midnight 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/managed/compiler/contract-info.json +57 -0
- package/dist/managed/compiler/contract-manifest.json +8 -8
- package/dist/managed/contract/index.d.ts +13 -0
- package/dist/managed/contract/index.js +138 -73
- package/dist/managed/contract/index.js.map +1 -1
- package/dist/signature-requests-state-reader.d.ts +5 -5
- package/dist/signature-requests-state-reader.js +5 -5
- package/dist/signet-contract-state-reader.d.ts +88 -2
- package/dist/signet-contract-state-reader.d.ts.map +1 -1
- package/dist/signet-contract-state-reader.js +106 -3
- package/dist/signet-contract-state-reader.js.map +1 -1
- package/dist/signet-request-feed.d.ts +40 -21
- package/dist/signet-request-feed.d.ts.map +1 -1
- package/dist/signet-request-feed.js +79 -34
- package/dist/signet-request-feed.js.map +1 -1
- package/dist/signet-request-resolver.d.ts +11 -11
- package/dist/signet-request-resolver.d.ts.map +1 -1
- package/dist/signet-request-resolver.js +22 -22
- package/dist/signet-request-resolver.js.map +1 -1
- package/dist/signet-requests.d.ts +18 -4
- package/dist/signet-requests.d.ts.map +1 -1
- package/dist/signet-requests.js +29 -6
- package/dist/signet-requests.js.map +1 -1
- package/package.json +2 -2
- package/src/Signet.compact +75 -99
- package/src/circuits.compact +5 -2
- package/dist/signet-event-observer.d.ts +0 -102
- package/dist/signet-event-observer.d.ts.map +0 -1
- package/dist/signet-event-observer.js +0 -127
- package/dist/signet-event-observer.js.map +0 -1
- package/dist/signet-events.d.ts +0 -175
- package/dist/signet-events.d.ts.map +0 -1
- package/dist/signet-events.js +0 -210
- package/dist/signet-events.js.map +0 -1
- package/dist/signet-response-feed.d.ts +0 -161
- package/dist/signet-response-feed.d.ts.map +0 -1
- package/dist/signet-response-feed.js +0 -234
- package/dist/signet-response-feed.js.map +0 -1
- package/src/constants.ts +0 -97
- package/src/epsilon-derivation.ts +0 -62
- package/src/index.ts +0 -31
- package/src/managed/compiler/contract-info.json +0 -165
- package/src/managed/compiler/contract-manifest.json +0 -32
- package/src/managed/contract/index.d.ts +0 -65
- package/src/managed/contract/index.js +0 -611
- 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 -391
- package/src/signet-event-observer.ts +0 -186
- package/src/signet-events.ts +0 -337
- package/src/signet-request-feed.ts +0 -158
- package/src/signet-request-resolver.ts +0 -116
- package/src/signet-request-response-reader.ts +0 -324
- package/src/signet-requests.ts +0 -737
- package/src/signet-response-feed.ts +0 -325
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { type SignetEventSource } from "./signet-event-observer.ts";
|
|
2
|
-
import { type RespondBidirectional } from "./signet-contract-state-reader.ts";
|
|
3
|
-
import { type SignatureResponseVerdict, type SignetPublicStateSource } from "./signet-request-response-reader.ts";
|
|
4
|
-
import type { RequestIdHex, SignBidirectionalRequest } from "./signet-requests.ts";
|
|
5
|
-
/** Default gap between poll cycles of {@link SignetResponseFeed.verdicts}. */
|
|
6
|
-
export declare const DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS = 3000;
|
|
7
|
-
/** Everything a {@link SignetResponseFeed} needs. */
|
|
8
|
-
export interface SignetResponseFeedConfig {
|
|
9
|
-
/** Address of the central signet contract whose events and response log to watch. */
|
|
10
|
-
readonly signetContractAddress: string;
|
|
11
|
-
/** Address of the signet-compliant requester contract holding the request records (e.g. the vault). */
|
|
12
|
-
readonly requesterContractAddress: string;
|
|
13
|
-
/**
|
|
14
|
-
* Source of BOTH events and raw contract state — a full
|
|
15
|
-
* `indexerPublicDataProvider` satisfies both halves.
|
|
16
|
-
*/
|
|
17
|
-
readonly source: SignetEventSource & SignetPublicStateSource;
|
|
18
|
-
/** Durable resume floor for the underlying observer (see {@link SignetEventObserverConfig.fromEventId}). */
|
|
19
|
-
readonly fromEventId?: number;
|
|
20
|
-
/** Poll cadence for {@link SignetResponseFeed.verdicts}; default {@link DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS}. */
|
|
21
|
-
readonly pollIntervalMs?: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* The event-driven signature response feed. Composes a
|
|
25
|
-
* {@link SignetEventObserver} of {@link SignatureRespondedEvent} notifications
|
|
26
|
-
* (discovery) with a {@link SignetRequestResponseReader} (verification),
|
|
27
|
-
* yielding one {@link SignatureResponseVerdict} per posted response, in count
|
|
28
|
-
* order, each exactly once per feed lifetime. Consumers act on the first
|
|
29
|
-
* valid verdict and surface the rejected ones as they see fit — the feed,
|
|
30
|
-
* like the reader, never logs.
|
|
31
|
-
*/
|
|
32
|
-
export declare class SignetResponseFeed {
|
|
33
|
-
private readonly observer;
|
|
34
|
-
private readonly reader;
|
|
35
|
-
private readonly pollIntervalMs;
|
|
36
|
-
private readonly yielded;
|
|
37
|
-
/**
|
|
38
|
-
* @param config - The contract pair, combined event/state source, and
|
|
39
|
-
* resume floor.
|
|
40
|
-
*/
|
|
41
|
-
constructor(config: SignetResponseFeedConfig);
|
|
42
|
-
/** The yielded-count set for `requestId`, created on first use. */
|
|
43
|
-
private yieldedCounts;
|
|
44
|
-
/**
|
|
45
|
-
* One-shot: the verdicts on every response post for `requestId` not yielded
|
|
46
|
-
* before, in count order. The response log is only read when a currently-
|
|
47
|
-
* visible event announces a post this feed has not yielded yet — no new
|
|
48
|
-
* event, no state query. Ledger posts the read then surfaces beyond the
|
|
49
|
-
* announced ones are yielded too (events are the trigger, the ledger is the
|
|
50
|
-
* source of truth), and a post whose event is visible but whose write has
|
|
51
|
-
* not indexed yet is simply retried next cycle.
|
|
52
|
-
*
|
|
53
|
-
* @param requestId - The request whose response posts to judge.
|
|
54
|
-
* @param expectedSigner - The EVM address (0x hex, any case) the genuine
|
|
55
|
-
* response must be signed by — the requester's MPC-derived address.
|
|
56
|
-
* @returns The newly-judged verdicts this cycle (possibly empty).
|
|
57
|
-
* @throws Error when either contract has no state, the request is not on
|
|
58
|
-
* the requester's ledger, or the responses ledger is inconsistent.
|
|
59
|
-
*/
|
|
60
|
-
poll(requestId: RequestIdHex, expectedSigner: string): Promise<SignatureResponseVerdict[]>;
|
|
61
|
-
/**
|
|
62
|
-
* Live stream: poll + sleep, yielding the verdict on each posted response
|
|
63
|
-
* exactly once, in count order, until `opts.signal` aborts. The natural
|
|
64
|
-
* consumption is to warn on each rejected verdict and act on the first
|
|
65
|
-
* valid one (see the cli's poll-signature-response command).
|
|
66
|
-
*
|
|
67
|
-
* @param requestId - The request whose response posts to judge.
|
|
68
|
-
* @param expectedSigner - The EVM address (0x hex, any case) the genuine
|
|
69
|
-
* response must be signed by — the requester's MPC-derived address.
|
|
70
|
-
* @param opts.signal - Abort to stop the stream.
|
|
71
|
-
* @yields Each post's verdict, in discovery order.
|
|
72
|
-
* @throws Error when either contract has no state, the request is not on
|
|
73
|
-
* the requester's ledger, or the responses ledger is inconsistent.
|
|
74
|
-
*/
|
|
75
|
-
verdicts(requestId: RequestIdHex, expectedSigner: string, opts?: {
|
|
76
|
-
signal?: AbortSignal;
|
|
77
|
-
}): AsyncIterableIterator<SignatureResponseVerdict>;
|
|
78
|
-
/**
|
|
79
|
-
* The request record a verdict's response answers, read through the feed's
|
|
80
|
-
* own reader (cached after the first fetch — free after any {@link poll}
|
|
81
|
-
* that reached verification). What a consumer needs to assemble the signed
|
|
82
|
-
* transaction from a valid verdict via
|
|
83
|
-
* `signBidirectionalRequestToSignedEVMTransaction`.
|
|
84
|
-
*
|
|
85
|
-
* @param requestId - The request id to look up.
|
|
86
|
-
* @returns The stored request record.
|
|
87
|
-
* @throws Error when the requester contract has no state or holds no
|
|
88
|
-
* request under `requestId`.
|
|
89
|
-
*/
|
|
90
|
-
getSignatureRequest(requestId: RequestIdHex): Promise<SignBidirectionalRequest>;
|
|
91
|
-
}
|
|
92
|
-
/** Everything a {@link SignetRespondBidirectionalFeed} needs. */
|
|
93
|
-
export interface SignetRespondBidirectionalFeedConfig {
|
|
94
|
-
/**
|
|
95
|
-
* Address of the central signet contract whose events and
|
|
96
|
-
* respond-bidirectional index to watch. Attestations live entirely on the
|
|
97
|
-
* signet contract, so — unlike {@link SignetResponseFeedConfig} — no
|
|
98
|
-
* requester contract address is needed.
|
|
99
|
-
*/
|
|
100
|
-
readonly signetContractAddress: string;
|
|
101
|
-
/**
|
|
102
|
-
* Source of BOTH events and raw contract state — a full
|
|
103
|
-
* `indexerPublicDataProvider` satisfies both halves.
|
|
104
|
-
*/
|
|
105
|
-
readonly source: SignetEventSource & SignetPublicStateSource;
|
|
106
|
-
/** Durable resume floor for the underlying observer (see {@link SignetEventObserverConfig.fromEventId}). */
|
|
107
|
-
readonly fromEventId?: number;
|
|
108
|
-
/** Poll cadence for {@link SignetRespondBidirectionalFeed.attestation}; default {@link DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS}. */
|
|
109
|
-
readonly pollIntervalMs?: number;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* The event-driven respond-bidirectional feed: composes a
|
|
113
|
-
* {@link SignetEventObserver} of {@link RespondBidirectionalEvent}
|
|
114
|
-
* notifications (discovery) with a read of the signet contract's
|
|
115
|
-
* respond-bidirectional index (the source of truth), yielding the MPC's
|
|
116
|
-
* attestation of a request's remote execution. No verdicts and no off-chain
|
|
117
|
-
* verification — the signet contract verified the attestation IN-CIRCUIT at
|
|
118
|
-
* post time (Schnorr over `(requestId, hash(serializedOutput, outputLen))`
|
|
119
|
-
* against its sealed MPC key), so the stored record is authentic by
|
|
120
|
-
* construction and there is exactly one per request (first valid write wins).
|
|
121
|
-
*/
|
|
122
|
-
export declare class SignetRespondBidirectionalFeed {
|
|
123
|
-
private readonly observer;
|
|
124
|
-
private readonly signetContractAddress;
|
|
125
|
-
private readonly source;
|
|
126
|
-
private readonly pollIntervalMs;
|
|
127
|
-
private readonly attestations;
|
|
128
|
-
/**
|
|
129
|
-
* @param config - The signet contract, combined event/state source, and
|
|
130
|
-
* resume floor.
|
|
131
|
-
*/
|
|
132
|
-
constructor(config: SignetRespondBidirectionalFeedConfig);
|
|
133
|
-
/**
|
|
134
|
-
* One-shot: the attestation for `requestId`, or `undefined` while none is
|
|
135
|
-
* discoverable yet. The index is only read when a currently-visible event
|
|
136
|
-
* announces `requestId`'s attestation — no event, no state query. An event
|
|
137
|
-
* whose ledger write has not indexed yet is simply retried next cycle
|
|
138
|
-
* (events are the trigger, the ledger is the source of truth).
|
|
139
|
-
*
|
|
140
|
-
* @param requestId - The request whose attestation to look for.
|
|
141
|
-
* @returns The stored attestation record, or `undefined` when its event is
|
|
142
|
-
* not yet visible or its write not yet indexed.
|
|
143
|
-
* @throws Error when the signet contract has no state on-chain.
|
|
144
|
-
*/
|
|
145
|
-
poll(requestId: RequestIdHex): Promise<RespondBidirectional | undefined>;
|
|
146
|
-
/**
|
|
147
|
-
* Live wait: poll + sleep until `requestId`'s attestation is discoverable,
|
|
148
|
-
* and return it. Runs until `opts.signal` aborts — the caller owns the
|
|
149
|
-
* give-up policy (see the cli's poll-respond-bidirectional command).
|
|
150
|
-
*
|
|
151
|
-
* @param requestId - The request whose attestation to wait for.
|
|
152
|
-
* @param opts.signal - Abort to stop waiting.
|
|
153
|
-
* @returns The stored attestation record, or `undefined` when aborted
|
|
154
|
-
* before one was discovered.
|
|
155
|
-
* @throws Error when the signet contract has no state on-chain.
|
|
156
|
-
*/
|
|
157
|
-
attestation(requestId: RequestIdHex, opts?: {
|
|
158
|
-
signal?: AbortSignal;
|
|
159
|
-
}): Promise<RespondBidirectional | undefined>;
|
|
160
|
-
}
|
|
161
|
-
//# sourceMappingURL=signet-response-feed.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signet-response-feed.d.ts","sourceRoot":"","sources":["../src/signet-response-feed.ts"],"names":[],"mappings":"AAuBA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,4BAA4B,CAAC;AAOpC,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC7B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,YAAY,EACZ,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAE9B,8EAA8E;AAC9E,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAE3D,qDAAqD;AACrD,MAAM,WAAW,wBAAwB;IACvC,qFAAqF;IACrF,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,uGAAuG;IACvG,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,uBAAuB,CAAC;IAC7D,4GAA4G;IAC5G,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,oHAAoH;IACpH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;IACxE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAIxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAEhE;;;OAGG;gBACS,MAAM,EAAE,wBAAwB;IAiB5C,mEAAmE;IACnE,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;;;OAeG;IACG,IAAI,CACR,SAAS,EAAE,YAAY,EACvB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAoBtC;;;;;;;;;;;;;OAaG;IACI,QAAQ,CACb,SAAS,EAAE,YAAY,EACvB,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,qBAAqB,CAAC,wBAAwB,CAAC;IASlD;;;;;;;;;;;OAWG;IACG,mBAAmB,CACvB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,wBAAwB,CAAC;CAGrC;AAED,iEAAiE;AACjE,MAAM,WAAW,oCAAoC;IACnD;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,uBAAuB,CAAC;IAC7D,4GAA4G;IAC5G,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,mIAAmI;IACnI,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,8BAA8B;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiD;IAC1E,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAIxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiD;IAE9E;;;OAGG;gBACS,MAAM,EAAE,oCAAoC;IAcxD;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IA2B9E;;;;;;;;;;OAUG;IACG,WAAW,CACf,SAAS,EAAE,YAAY,EACvB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAU7C"}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
// The requesting client's entry point for discovering MPC signature responses
|
|
2
|
-
// by event observation: watch the central signet contract's
|
|
3
|
-
// SignatureRespondedEvent notifications, and when one announces a post for a
|
|
4
|
-
// request the client cares about, read the response log back and verify every
|
|
5
|
-
// post against the request — the response-direction mirror of
|
|
6
|
-
// signet-request-feed.ts. The event is only the TRIGGER for a state read; the
|
|
7
|
-
// verdicts come from the ledger via the same SignetRequestResponseReader all
|
|
8
|
-
// other consumers use, so an event/state indexing skew in either direction is
|
|
9
|
-
// tolerated (a post visible in state before its event is still yielded; an
|
|
10
|
-
// event whose write has not indexed yet is retried next cycle).
|
|
11
|
-
//
|
|
12
|
-
// Trust model (see "Signet Contract Ledger Layout" in Signet.compact): the
|
|
13
|
-
// response log is UNAUTHENTICATED — neither the event nor the stored record
|
|
14
|
-
// confers authenticity. Only the off-chain signature verification does, which
|
|
15
|
-
// is why the feed yields per-post VERDICTS rather than raw responses.
|
|
16
|
-
//
|
|
17
|
-
// The MPC's OTHER response kind — the respond-bidirectional attestation of a
|
|
18
|
-
// request's remote execution — gets the same event-gated treatment via
|
|
19
|
-
// SignetRespondBidirectionalFeed (RespondBidirectionalEvent → index read),
|
|
20
|
-
// but with the opposite trust model: the signet contract verified the
|
|
21
|
-
// attestation IN-CIRCUIT at post time, so the feed yields the stored record
|
|
22
|
-
// itself, no verdicts.
|
|
23
|
-
import { SignetEventObserver, sleepUnlessAborted, } from "./signet-event-observer.js";
|
|
24
|
-
import { respondBidirectionalEventCodec, signatureRespondedEventCodec, } from "./signet-events.js";
|
|
25
|
-
import { readSignetContractLedgerFromState, } from "./signet-contract-state-reader.js";
|
|
26
|
-
import { SignetRequestResponseReader, } from "./signet-request-response-reader.js";
|
|
27
|
-
/** Default gap between poll cycles of {@link SignetResponseFeed.verdicts}. */
|
|
28
|
-
export const DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS = 3000;
|
|
29
|
-
/**
|
|
30
|
-
* The event-driven signature response feed. Composes a
|
|
31
|
-
* {@link SignetEventObserver} of {@link SignatureRespondedEvent} notifications
|
|
32
|
-
* (discovery) with a {@link SignetRequestResponseReader} (verification),
|
|
33
|
-
* yielding one {@link SignatureResponseVerdict} per posted response, in count
|
|
34
|
-
* order, each exactly once per feed lifetime. Consumers act on the first
|
|
35
|
-
* valid verdict and surface the rejected ones as they see fit — the feed,
|
|
36
|
-
* like the reader, never logs.
|
|
37
|
-
*/
|
|
38
|
-
export class SignetResponseFeed {
|
|
39
|
-
observer;
|
|
40
|
-
reader;
|
|
41
|
-
pollIntervalMs;
|
|
42
|
-
// Post counts already yielded, per request. NOT a trust boundary (the
|
|
43
|
-
// verdicts are) — just an exactly-once gate so a post is not re-judged.
|
|
44
|
-
yielded = new Map();
|
|
45
|
-
/**
|
|
46
|
-
* @param config - The contract pair, combined event/state source, and
|
|
47
|
-
* resume floor.
|
|
48
|
-
*/
|
|
49
|
-
constructor(config) {
|
|
50
|
-
this.observer = new SignetEventObserver({
|
|
51
|
-
signetContractAddress: config.signetContractAddress,
|
|
52
|
-
source: config.source,
|
|
53
|
-
codec: signatureRespondedEventCodec,
|
|
54
|
-
fromEventId: config.fromEventId,
|
|
55
|
-
pollIntervalMs: config.pollIntervalMs,
|
|
56
|
-
});
|
|
57
|
-
this.reader = new SignetRequestResponseReader({
|
|
58
|
-
requesterContractAddress: config.requesterContractAddress,
|
|
59
|
-
signetContractAddress: config.signetContractAddress,
|
|
60
|
-
publicDataProvider: config.source,
|
|
61
|
-
});
|
|
62
|
-
this.pollIntervalMs =
|
|
63
|
-
config.pollIntervalMs ?? DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS;
|
|
64
|
-
}
|
|
65
|
-
/** The yielded-count set for `requestId`, created on first use. */
|
|
66
|
-
yieldedCounts(requestId) {
|
|
67
|
-
let counts = this.yielded.get(requestId);
|
|
68
|
-
if (counts === undefined) {
|
|
69
|
-
counts = new Set();
|
|
70
|
-
this.yielded.set(requestId, counts);
|
|
71
|
-
}
|
|
72
|
-
return counts;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* One-shot: the verdicts on every response post for `requestId` not yielded
|
|
76
|
-
* before, in count order. The response log is only read when a currently-
|
|
77
|
-
* visible event announces a post this feed has not yielded yet — no new
|
|
78
|
-
* event, no state query. Ledger posts the read then surfaces beyond the
|
|
79
|
-
* announced ones are yielded too (events are the trigger, the ledger is the
|
|
80
|
-
* source of truth), and a post whose event is visible but whose write has
|
|
81
|
-
* not indexed yet is simply retried next cycle.
|
|
82
|
-
*
|
|
83
|
-
* @param requestId - The request whose response posts to judge.
|
|
84
|
-
* @param expectedSigner - The EVM address (0x hex, any case) the genuine
|
|
85
|
-
* response must be signed by — the requester's MPC-derived address.
|
|
86
|
-
* @returns The newly-judged verdicts this cycle (possibly empty).
|
|
87
|
-
* @throws Error when either contract has no state, the request is not on
|
|
88
|
-
* the requester's ledger, or the responses ledger is inconsistent.
|
|
89
|
-
*/
|
|
90
|
-
async poll(requestId, expectedSigner) {
|
|
91
|
-
const events = await this.observer.currentEvents();
|
|
92
|
-
const counts = this.yieldedCounts(requestId);
|
|
93
|
-
const announcesNew = events.some((event) => event.requestId === requestId && !counts.has(event.count));
|
|
94
|
-
if (!announcesNew) {
|
|
95
|
-
return [];
|
|
96
|
-
}
|
|
97
|
-
const { verdicts } = await this.reader.getVerifiedSignatureResponse(requestId, expectedSigner);
|
|
98
|
-
const fresh = verdicts.filter((verdict) => !counts.has(verdict.count));
|
|
99
|
-
for (const verdict of fresh) {
|
|
100
|
-
counts.add(verdict.count);
|
|
101
|
-
}
|
|
102
|
-
return fresh;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Live stream: poll + sleep, yielding the verdict on each posted response
|
|
106
|
-
* exactly once, in count order, until `opts.signal` aborts. The natural
|
|
107
|
-
* consumption is to warn on each rejected verdict and act on the first
|
|
108
|
-
* valid one (see the cli's poll-signature-response command).
|
|
109
|
-
*
|
|
110
|
-
* @param requestId - The request whose response posts to judge.
|
|
111
|
-
* @param expectedSigner - The EVM address (0x hex, any case) the genuine
|
|
112
|
-
* response must be signed by — the requester's MPC-derived address.
|
|
113
|
-
* @param opts.signal - Abort to stop the stream.
|
|
114
|
-
* @yields Each post's verdict, in discovery order.
|
|
115
|
-
* @throws Error when either contract has no state, the request is not on
|
|
116
|
-
* the requester's ledger, or the responses ledger is inconsistent.
|
|
117
|
-
*/
|
|
118
|
-
async *verdicts(requestId, expectedSigner, opts) {
|
|
119
|
-
while (!opts?.signal?.aborted) {
|
|
120
|
-
const batch = await this.poll(requestId, expectedSigner);
|
|
121
|
-
for (const verdict of batch)
|
|
122
|
-
yield verdict;
|
|
123
|
-
if (opts?.signal?.aborted)
|
|
124
|
-
break;
|
|
125
|
-
await sleepUnlessAborted(this.pollIntervalMs, opts?.signal);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* The request record a verdict's response answers, read through the feed's
|
|
130
|
-
* own reader (cached after the first fetch — free after any {@link poll}
|
|
131
|
-
* that reached verification). What a consumer needs to assemble the signed
|
|
132
|
-
* transaction from a valid verdict via
|
|
133
|
-
* `signBidirectionalRequestToSignedEVMTransaction`.
|
|
134
|
-
*
|
|
135
|
-
* @param requestId - The request id to look up.
|
|
136
|
-
* @returns The stored request record.
|
|
137
|
-
* @throws Error when the requester contract has no state or holds no
|
|
138
|
-
* request under `requestId`.
|
|
139
|
-
*/
|
|
140
|
-
async getSignatureRequest(requestId) {
|
|
141
|
-
return this.reader.getSignatureRequest(requestId);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* The event-driven respond-bidirectional feed: composes a
|
|
146
|
-
* {@link SignetEventObserver} of {@link RespondBidirectionalEvent}
|
|
147
|
-
* notifications (discovery) with a read of the signet contract's
|
|
148
|
-
* respond-bidirectional index (the source of truth), yielding the MPC's
|
|
149
|
-
* attestation of a request's remote execution. No verdicts and no off-chain
|
|
150
|
-
* verification — the signet contract verified the attestation IN-CIRCUIT at
|
|
151
|
-
* post time (Schnorr over `(requestId, hash(serializedOutput, outputLen))`
|
|
152
|
-
* against its sealed MPC key), so the stored record is authentic by
|
|
153
|
-
* construction and there is exactly one per request (first valid write wins).
|
|
154
|
-
*/
|
|
155
|
-
export class SignetRespondBidirectionalFeed {
|
|
156
|
-
observer;
|
|
157
|
-
signetContractAddress;
|
|
158
|
-
source;
|
|
159
|
-
pollIntervalMs;
|
|
160
|
-
// Attestation records never change once stored (one authenticated slot per
|
|
161
|
-
// request, first valid write wins), so cache them across polls.
|
|
162
|
-
attestations = new Map();
|
|
163
|
-
/**
|
|
164
|
-
* @param config - The signet contract, combined event/state source, and
|
|
165
|
-
* resume floor.
|
|
166
|
-
*/
|
|
167
|
-
constructor(config) {
|
|
168
|
-
this.observer = new SignetEventObserver({
|
|
169
|
-
signetContractAddress: config.signetContractAddress,
|
|
170
|
-
source: config.source,
|
|
171
|
-
codec: respondBidirectionalEventCodec,
|
|
172
|
-
fromEventId: config.fromEventId,
|
|
173
|
-
pollIntervalMs: config.pollIntervalMs,
|
|
174
|
-
});
|
|
175
|
-
this.signetContractAddress = config.signetContractAddress;
|
|
176
|
-
this.source = config.source;
|
|
177
|
-
this.pollIntervalMs =
|
|
178
|
-
config.pollIntervalMs ?? DEFAULT_RESPONSE_FEED_POLL_INTERVAL_MS;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* One-shot: the attestation for `requestId`, or `undefined` while none is
|
|
182
|
-
* discoverable yet. The index is only read when a currently-visible event
|
|
183
|
-
* announces `requestId`'s attestation — no event, no state query. An event
|
|
184
|
-
* whose ledger write has not indexed yet is simply retried next cycle
|
|
185
|
-
* (events are the trigger, the ledger is the source of truth).
|
|
186
|
-
*
|
|
187
|
-
* @param requestId - The request whose attestation to look for.
|
|
188
|
-
* @returns The stored attestation record, or `undefined` when its event is
|
|
189
|
-
* not yet visible or its write not yet indexed.
|
|
190
|
-
* @throws Error when the signet contract has no state on-chain.
|
|
191
|
-
*/
|
|
192
|
-
async poll(requestId) {
|
|
193
|
-
const cached = this.attestations.get(requestId);
|
|
194
|
-
if (cached !== undefined) {
|
|
195
|
-
return cached;
|
|
196
|
-
}
|
|
197
|
-
const events = await this.observer.currentEvents();
|
|
198
|
-
if (!events.some((event) => event.requestId === requestId)) {
|
|
199
|
-
return undefined;
|
|
200
|
-
}
|
|
201
|
-
const state = await this.source.queryContractState(this.signetContractAddress);
|
|
202
|
-
if (!state?.data) {
|
|
203
|
-
throw new Error(`no state data found for signet contract '${this.signetContractAddress}' - is it deployed?`);
|
|
204
|
-
}
|
|
205
|
-
const record = readSignetContractLedgerFromState(state.data).respondBidirectionalIndex.get(requestId);
|
|
206
|
-
if (record === undefined) {
|
|
207
|
-
return undefined;
|
|
208
|
-
}
|
|
209
|
-
this.attestations.set(requestId, record);
|
|
210
|
-
return record;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Live wait: poll + sleep until `requestId`'s attestation is discoverable,
|
|
214
|
-
* and return it. Runs until `opts.signal` aborts — the caller owns the
|
|
215
|
-
* give-up policy (see the cli's poll-respond-bidirectional command).
|
|
216
|
-
*
|
|
217
|
-
* @param requestId - The request whose attestation to wait for.
|
|
218
|
-
* @param opts.signal - Abort to stop waiting.
|
|
219
|
-
* @returns The stored attestation record, or `undefined` when aborted
|
|
220
|
-
* before one was discovered.
|
|
221
|
-
* @throws Error when the signet contract has no state on-chain.
|
|
222
|
-
*/
|
|
223
|
-
async attestation(requestId, opts) {
|
|
224
|
-
while (!opts?.signal?.aborted) {
|
|
225
|
-
const record = await this.poll(requestId);
|
|
226
|
-
if (record !== undefined) {
|
|
227
|
-
return record;
|
|
228
|
-
}
|
|
229
|
-
await sleepUnlessAborted(this.pollIntervalMs, opts?.signal);
|
|
230
|
-
}
|
|
231
|
-
return undefined;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
//# sourceMappingURL=signet-response-feed.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signet-response-feed.js","sourceRoot":"","sources":["../src/signet-response-feed.ts"],"names":[],"mappings":"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"}
|
package/src/constants.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// MPC routing constants + the padded-ASCII codec for the signet request
|
|
2
|
-
// structs. Field widths mirror Signet.compact (the wire format —
|
|
3
|
-
// keep in lockstep); the string constants are the values the MPC network
|
|
4
|
-
// routes on. Ported from the MVP's contract-cli signet/constants.ts, adapted
|
|
5
|
-
// to the refactor's zero-padded convention (Compact `pad(N, "text")`) — the
|
|
6
|
-
// MVP's 2-byte length-prefixed codec is gone with the old layout.
|
|
7
|
-
//
|
|
8
|
-
// The routing constants belong in github.com/sig-net/signet.js — kept here
|
|
9
|
-
// until upstreamed.
|
|
10
|
-
|
|
11
|
-
/** Width of `SignBidirectionalRequest.caip2Id` (`Bytes<32>`). */
|
|
12
|
-
export const CAIP2_ID_BYTES = 32;
|
|
13
|
-
|
|
14
|
-
/** Width of `SignBidirectionalRequest.algo` (`Bytes<32>`). */
|
|
15
|
-
export const ALGO_BYTES = 32;
|
|
16
|
-
|
|
17
|
-
/** Width of `SignBidirectionalRequest.dest` (`Bytes<32>`). */
|
|
18
|
-
export const DEST_BYTES = 32;
|
|
19
|
-
|
|
20
|
-
/** Width of `SignBidirectionalRequest.params` (`Bytes<64>`). */
|
|
21
|
-
export const MPC_PARAMS_BYTES = 64;
|
|
22
|
-
|
|
23
|
-
/** Width of `SignBidirectionalRequest.outputDeserializationSchema` (`Bytes<128>`). */
|
|
24
|
-
export const OUTPUT_DESERIALIZATION_SCHEMA_BYTES = 128;
|
|
25
|
-
|
|
26
|
-
/** Width of `SignBidirectionalRequest.respondSerializationSchema` (`Bytes<128>`). */
|
|
27
|
-
export const RESPOND_SERIALIZATION_SCHEMA_BYTES = 128;
|
|
28
|
-
|
|
29
|
-
/** Width of `EVMCalldata.selector` (`Bytes<4>`) — the literal first 4 calldata bytes. */
|
|
30
|
-
export const SELECTOR_BYTES = 4;
|
|
31
|
-
|
|
32
|
-
/** Width of `RespondBidirectional.serializedOutput` (`Bytes<128>`). */
|
|
33
|
-
export const SERIALIZED_OUTPUT_BYTES = 128;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* The MPC's error sentinel: `serializedOutput` beginning with these four
|
|
37
|
-
* bytes marks a failed/absent remote execution (mirrors the sig-net MPC's
|
|
38
|
-
* MAGIC_ERROR_PREFIX).
|
|
39
|
-
*/
|
|
40
|
-
export const MPC_ERROR_SENTINEL = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Whether an attestation's serialized output reports a successful remote
|
|
44
|
-
* execution: the first byte is 1 — the little-endian encoding of the
|
|
45
|
-
* ABI-decoded success flag, matching the circuits'
|
|
46
|
-
* `serializedOutput as Field == 1` check.
|
|
47
|
-
*
|
|
48
|
-
* @param serializedOutput - The attestation's serialized output.
|
|
49
|
-
* @returns `true` when the remote call succeeded.
|
|
50
|
-
*/
|
|
51
|
-
export function executionSucceeded(serializedOutput: Uint8Array): boolean {
|
|
52
|
-
return serializedOutput[0] === 1;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Whether an attestation's serialized output is the MPC's error sentinel
|
|
57
|
-
* (see {@link MPC_ERROR_SENTINEL}) rather than a call result.
|
|
58
|
-
*
|
|
59
|
-
* @param serializedOutput - The attestation's serialized output.
|
|
60
|
-
* @returns `true` when the MPC reported an execution error.
|
|
61
|
-
*/
|
|
62
|
-
export function isExecutionError(serializedOutput: Uint8Array): boolean {
|
|
63
|
-
return MPC_ERROR_SENTINEL.every((byte, index) => serializedOutput[index] === byte);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Signature algorithm the MPC uses for EVM chains (`algo` field value). */
|
|
67
|
-
export const SIGNET_ALGO_ECDSA = "ecdsa";
|
|
68
|
-
|
|
69
|
-
/** Destination chain family for EVM requests (`dest` field value). */
|
|
70
|
-
export const SIGNET_DEST_ETHEREUM = "ethereum";
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Default MPC key version (`keyVersion` field value). Version 0 is the
|
|
74
|
-
* unsupported legacy format — the canonical MPC (and
|
|
75
|
-
* `constructSignBidirectionalRequest`) requires `keyVersion >= 1`.
|
|
76
|
-
*/
|
|
77
|
-
export const SIGNET_DEFAULT_KEY_VERSION = 1n;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Encode text as zero-padded ASCII bytes — the Compact `pad(N, "text")`
|
|
81
|
-
* convention every string-ish field of the request structs uses (consumers
|
|
82
|
-
* NUL-trim on decode).
|
|
83
|
-
*
|
|
84
|
-
* @param text - The ASCII text to encode.
|
|
85
|
-
* @param length - The fixed field width in bytes.
|
|
86
|
-
* @returns `text`'s bytes followed by zero padding to exactly `length`.
|
|
87
|
-
* @throws If the encoded text does not fit in `length` bytes.
|
|
88
|
-
*/
|
|
89
|
-
export function asciiPadded(text: string, length: number): Uint8Array {
|
|
90
|
-
const encoded = new TextEncoder().encode(text);
|
|
91
|
-
if (encoded.length > length) {
|
|
92
|
-
throw new Error(`"${text}" is ${encoded.length} bytes — does not fit the ${length}-byte field`);
|
|
93
|
-
}
|
|
94
|
-
const out = new Uint8Array(length);
|
|
95
|
-
out.set(encoded);
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
// Epsilon key derivation: contract address + path -> derived EVM account.
|
|
2
|
-
//
|
|
3
|
-
// This belongs in github.com/sig-net/signet.js — kept here until upstreamed.
|
|
4
|
-
// It is NOT imported from signet.js because signet.js's `deriveChildPublicKey`
|
|
5
|
-
// implements the v2.0.0 COLON-separated epsilon format
|
|
6
|
-
// (`sig.network v2.0.0 epsilon derivation:<chainId>:<requester>:<path>`),
|
|
7
|
-
// which is incompatible with the live sig-net response server's v1.0.0
|
|
8
|
-
// COMMA-separated format (see solana-signet-program
|
|
9
|
-
// clients/response-server/src/modules/CryptoUtils.ts). The two schemes hash
|
|
10
|
-
// different strings and therefore derive different accounts; this module
|
|
11
|
-
// matches the server.
|
|
12
|
-
|
|
13
|
-
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
14
|
-
import { computeAddress, keccak256, SigningKey, toUtf8Bytes } from "ethers";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Domain prefix of the sig-net v1.0.0 epsilon derivation scheme, as used by
|
|
18
|
-
* the live response server. The full derivation string is
|
|
19
|
-
* `<prefix>,<chainId>,<requester>,<path>` (comma-separated).
|
|
20
|
-
*/
|
|
21
|
-
export const EPSILON_DERIVATION_PREFIX = "sig.network v1.0.0 epsilon derivation";
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* CAIP-2 chain id under which the MPC derives keys for requests originating
|
|
25
|
-
* from Midnight contracts.
|
|
26
|
-
*/
|
|
27
|
-
export const MIDNIGHT_TESTNET_CHAIN_ID = "midnight:testnet";
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Derive the EVM address the MPC network signs from for a given Midnight
|
|
31
|
-
* contract and derivation path, using the sig-net v1.0.0 epsilon scheme:
|
|
32
|
-
* `epsilon = keccak256("<prefix>,<chainId>,<contractAddress>,<path>")` and
|
|
33
|
-
* `derivedPubKey = mpcRootPubKey + epsilon * G` on secp256k1.
|
|
34
|
-
*
|
|
35
|
-
* The MPC treats `path` as an opaque string: the vault's own account uses the
|
|
36
|
-
* literal path `"vault"`, a user's account uses the lowercase hex of their
|
|
37
|
-
* identity commitment.
|
|
38
|
-
*
|
|
39
|
-
* @param mpcSecp256k1PubkeyHex - The MPC root secp256k1 public key as 0x-hex
|
|
40
|
-
* (compressed or uncompressed; normalized internally).
|
|
41
|
-
* @param contractAddress - The Midnight contract address the request
|
|
42
|
-
* originates from (the "requester" in the derivation string).
|
|
43
|
-
* @param path - The derivation path string (e.g. `"vault"` or a commitment
|
|
44
|
-
* hex).
|
|
45
|
-
* @param chainId - CAIP-2 chain id component of the derivation string.
|
|
46
|
-
* @returns The derived EVM address as a 0x-prefixed EIP-55 checksummed string.
|
|
47
|
-
*/
|
|
48
|
-
export function deriveEvmAddress(
|
|
49
|
-
mpcSecp256k1PubkeyHex: string,
|
|
50
|
-
contractAddress: string,
|
|
51
|
-
path: string,
|
|
52
|
-
chainId: string = MIDNIGHT_TESTNET_CHAIN_ID,
|
|
53
|
-
): string {
|
|
54
|
-
const fullPath = `${EPSILON_DERIVATION_PREFIX},${chainId},${contractAddress},${path}`;
|
|
55
|
-
// Reduce mod n before multiplying: noble throws on scalars >= n, whereas the
|
|
56
|
-
// server's scalar arithmetic reduces implicitly.
|
|
57
|
-
const epsilon = BigInt(keccak256(toUtf8Bytes(fullPath))) % secp256k1.Point.Fn.ORDER;
|
|
58
|
-
const rootPubKeyHex = SigningKey.computePublicKey(mpcSecp256k1PubkeyHex, false);
|
|
59
|
-
const rootPoint = secp256k1.Point.fromHex(rootPubKeyHex.slice(2));
|
|
60
|
-
const derivedPoint = epsilon === 0n ? rootPoint : rootPoint.add(secp256k1.Point.BASE.multiply(epsilon));
|
|
61
|
-
return computeAddress(`0x${derivedPoint.toHex(false)}`);
|
|
62
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// Midnight-side sig-net integration. See README.md for the module plan:
|
|
2
|
-
// request-id, calldata-builder, tx-builder, codec, constants, schnorr,
|
|
3
|
-
// state-reader, response-poller — ported bit by bit from the old repo's
|
|
4
|
-
// boilerplate/contract-cli/src/signet/.
|
|
5
|
-
|
|
6
|
-
export * from "./signet-requests.ts";
|
|
7
|
-
export * from "./signature-state-reading.ts";
|
|
8
|
-
export * from "./signature-requests-state-reader.ts";
|
|
9
|
-
export * from "./signet-contract-state-reader.ts";
|
|
10
|
-
export * from "./signature-response-verification.ts";
|
|
11
|
-
export * from "./signet-request-response-reader.ts";
|
|
12
|
-
export * from "./signet-events.ts";
|
|
13
|
-
export * from "./signet-event-observer.ts";
|
|
14
|
-
export * from "./signet-request-resolver.ts";
|
|
15
|
-
export * from "./signet-request-feed.ts";
|
|
16
|
-
export * from "./signet-response-feed.ts";
|
|
17
|
-
export * from "./constants.ts";
|
|
18
|
-
export * from "./epsilon-derivation.ts";
|
|
19
|
-
export * from "./schnorr.ts";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Compiled pure circuits of Signet.compact (run `yarn compile` first): the
|
|
23
|
-
* executable reference implementation of the client-agnostic circuits —
|
|
24
|
-
* path<->identity checks, the attestation message, and the Schnorr challenge.
|
|
25
|
-
* Off-chain code MUST use these instead of re-porting the algorithms — they
|
|
26
|
-
* are the same compiled logic the contracts prove. The generic request
|
|
27
|
-
* circuits cannot be compiled here (type-parameterized): request construction
|
|
28
|
-
* is contract-only, and request-id hashing has a documented-deviation TS twin
|
|
29
|
-
* (`calculateRequestId` in signet-requests.ts).
|
|
30
|
-
*/
|
|
31
|
-
export { pureCircuits, type PureCircuits } from "./managed/contract/index.js";
|