@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.
- package/README.md +113 -49
- package/dist/constants.d.ts +55 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +85 -5
- package/dist/constants.js.map +1 -1
- package/dist/ecdsa-attestation.d.ts +6 -5
- package/dist/ecdsa-attestation.d.ts.map +1 -1
- package/dist/ecdsa-attestation.js +5 -4
- package/dist/ecdsa-attestation.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/managed/compiler/contract-manifest.json +2 -2
- package/dist/managed/contract/index.js +31 -31
- package/dist/managed/contract/index.js.map +1 -1
- package/dist/signature-requests-state-reader.d.ts +23 -5
- package/dist/signature-requests-state-reader.d.ts.map +1 -1
- package/dist/signature-requests-state-reader.js +50 -5
- package/dist/signature-requests-state-reader.js.map +1 -1
- package/dist/signature-response-verification.d.ts +1 -1
- package/dist/signature-response-verification.d.ts.map +1 -1
- package/dist/signature-response-verification.js +3 -3
- package/dist/signature-response-verification.js.map +1 -1
- package/dist/signature-state-reading.js +2 -2
- package/dist/signature-state-reading.js.map +1 -1
- package/dist/signet-contract-events.d.ts +262 -0
- package/dist/signet-contract-events.d.ts.map +1 -0
- package/dist/signet-contract-events.js +266 -0
- package/dist/signet-contract-events.js.map +1 -0
- package/dist/signet-evtype2tx-requests.d.ts +4 -4
- package/dist/signet-evtype2tx-requests.d.ts.map +1 -1
- package/dist/signet-evtype2tx-requests.js +3 -3
- package/dist/signet-request-feed.d.ts +59 -34
- package/dist/signet-request-feed.d.ts.map +1 -1
- package/dist/signet-request-feed.js +95 -62
- package/dist/signet-request-feed.js.map +1 -1
- package/dist/signet-request-response-reader.d.ts +62 -55
- package/dist/signet-request-response-reader.d.ts.map +1 -1
- package/dist/signet-request-response-reader.js +85 -99
- package/dist/signet-request-response-reader.js.map +1 -1
- package/dist/signet-requests.js +2 -2
- package/dist/signet-requests.js.map +1 -1
- package/package.json +2 -2
- package/src/Signet.compact +43 -36
- package/dist/signet-contract-state-reader.d.ts +0 -247
- package/dist/signet-contract-state-reader.d.ts.map +0 -1
- package/dist/signet-contract-state-reader.js +0 -363
- package/dist/signet-contract-state-reader.js.map +0 -1
- package/dist/signet-request-resolver.d.ts +0 -60
- package/dist/signet-request-resolver.d.ts.map +0 -1
- package/dist/signet-request-resolver.js +0 -78
- package/dist/signet-request-resolver.js.map +0 -1
|
@@ -1,50 +1,40 @@
|
|
|
1
1
|
// One-stop client-side reader for the signet request/response flow: fetch a
|
|
2
|
-
// request record from the requester contract's ledger,
|
|
3
|
-
// the signet contract
|
|
4
|
-
// against the request.
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
2
|
+
// request record from the requester contract's ledger, read the request's
|
|
3
|
+
// responses out of the contract events the signet contract emits, and verify
|
|
4
|
+
// each candidate against the request.
|
|
5
|
+
// A response is a Misc contract event that carries the request id it answers
|
|
6
|
+
// beside a signature. The id is UNAUTHENTICATED routing data: it scopes a
|
|
7
|
+
// read to one request's posts, and VERIFICATION establishes authenticity. A
|
|
8
|
+
// signature response answers a request exactly when it recovers to that
|
|
9
|
+
// request's derived signer over the request's transaction, and a
|
|
10
|
+
// respond-bidirectional post answers exactly when it verifies over
|
|
11
|
+
// (requestId, output) against the request's MPC response key. This class
|
|
12
|
+
// packages that flow so every consumer (CLI poller, integration tests, a
|
|
13
|
+
// future UI) shares one implementation. Single-shot by design: each call
|
|
14
|
+
// queries once, and the caller owns any poll loop.
|
|
11
15
|
import { lookupSignetRequestAt } from "./signature-requests-state-reader.js";
|
|
12
|
-
import {
|
|
16
|
+
import { decodeRespondBidirectionalEventPayload, decodeSignatureRespondedEventPayload, SignetEventName, } from "./signet-contract-events.js";
|
|
13
17
|
import { recoverSignatureResponseSigner } from "./signature-response-verification.js";
|
|
14
18
|
import { verifyRespondBidirectionalSignature, } from "./ecdsa-attestation.js";
|
|
15
19
|
import { signBidirectionalEventToSignedEvmTransaction, signBidirectionalEventToUnsignedEvmTransaction, } from "./signet-evtype2tx-requests.js";
|
|
16
|
-
import { requestIdBytes, } from "./signet-requests.js";
|
|
20
|
+
import { requestIdBytes, requestIdHex, } from "./signet-requests.js";
|
|
17
21
|
/**
|
|
18
22
|
* Reader over one requester contract / signet contract pair.
|
|
19
23
|
* Construct once per pair and reuse: fetched request records are cached (they
|
|
20
24
|
* are immutable, the ledger key is their hash), so repeated verification
|
|
21
|
-
* calls cost one
|
|
25
|
+
* calls cost one event query each.
|
|
22
26
|
*/
|
|
23
27
|
export class SignetRequestResponseReader {
|
|
24
28
|
config;
|
|
25
29
|
// Request records never change once stored, so cache them across calls.
|
|
26
30
|
requestCache = new Map();
|
|
27
31
|
/**
|
|
28
|
-
* @param config - The contract pair and
|
|
32
|
+
* @param config - The contract pair, state source and event source to read
|
|
33
|
+
* through.
|
|
29
34
|
*/
|
|
30
35
|
constructor(config) {
|
|
31
36
|
this.config = config;
|
|
32
37
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Query one contract's raw state, throwing a uniform error when absent.
|
|
35
|
-
*
|
|
36
|
-
* @param contractAddress - The contract to query.
|
|
37
|
-
* @param role - Human name of the contract for the error message.
|
|
38
|
-
* @returns The raw ledger state tree.
|
|
39
|
-
* @throws Error when the address holds no contract state.
|
|
40
|
-
*/
|
|
41
|
-
async queryRawState(contractAddress, role) {
|
|
42
|
-
const state = await this.config.publicDataProvider.queryContractState(contractAddress);
|
|
43
|
-
if (!state?.data) {
|
|
44
|
-
throw new Error(`no state data found for ${role} contract '${contractAddress}' (is it deployed?)`);
|
|
45
|
-
}
|
|
46
|
-
return state.data;
|
|
47
|
-
}
|
|
48
38
|
/**
|
|
49
39
|
* Fetch the request record for `requestId` from the requester contract's
|
|
50
40
|
* request index (at the configured `requesterRequestsPath`). Cached
|
|
@@ -60,8 +50,11 @@ export class SignetRequestResponseReader {
|
|
|
60
50
|
if (cached !== undefined) {
|
|
61
51
|
return cached;
|
|
62
52
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
53
|
+
const state = await this.config.publicDataProvider.queryContractState(this.config.requesterContractAddress);
|
|
54
|
+
if (!state?.data) {
|
|
55
|
+
throw new Error(`no state data found for requester contract '${this.config.requesterContractAddress}' (is it deployed?)`);
|
|
56
|
+
}
|
|
57
|
+
const request = lookupSignetRequestAt(state.data, this.config.requesterRequestsPath, requestId);
|
|
65
58
|
if (request === undefined) {
|
|
66
59
|
throw new Error(`request ${requestId} is not on the requester contract's ledger ` +
|
|
67
60
|
`(request index at path ${JSON.stringify(this.config.requesterRequestsPath)}): was it submitted?`);
|
|
@@ -70,69 +63,78 @@ export class SignetRequestResponseReader {
|
|
|
70
63
|
return request;
|
|
71
64
|
}
|
|
72
65
|
/**
|
|
73
|
-
* Fetch every
|
|
74
|
-
*
|
|
75
|
-
*
|
|
66
|
+
* Fetch every event of `name` the signet contract has emitted, decode each
|
|
67
|
+
* with `decode`, and keep the posts whose declared request id is
|
|
68
|
+
* `requestId`, in emission order. The declared id is routing data only:
|
|
69
|
+
* the verified getters run the actual authenticity checks.
|
|
76
70
|
*
|
|
77
|
-
* @param
|
|
78
|
-
* @
|
|
79
|
-
* @
|
|
80
|
-
*
|
|
71
|
+
* @param name - The signet event name to keep.
|
|
72
|
+
* @param decode - The payload decoder for that event kind.
|
|
73
|
+
* @param requestId - The request id the kept posts must declare.
|
|
74
|
+
* @returns The kept posts' records, oldest first.
|
|
81
75
|
*/
|
|
82
|
-
async
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
76
|
+
async getRespondPostsNamed(name, decode, requestId) {
|
|
77
|
+
const events = await this.config.eventSource.querySignetEvents(this.config.signetContractAddress);
|
|
78
|
+
return events
|
|
79
|
+
.filter((event) => event.name === name)
|
|
80
|
+
.map((event) => decode(event.payload))
|
|
81
|
+
.filter((post) => requestIdHex(post.requestId) === requestId)
|
|
82
|
+
.map((post) => post.event);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Fetch every signature response posted under `requestId`, in emission
|
|
86
|
+
* order. UNVERIFIED: the declared id is routing data on an unauthenticated
|
|
87
|
+
* event log, so any post may still be garbage (see
|
|
88
|
+
* {@link getVerifiedSignatureRespondedEvent}, where verification
|
|
89
|
+
* establishes authenticity).
|
|
90
|
+
*
|
|
91
|
+
* @param requestId - The request id the posts must declare.
|
|
92
|
+
* @returns The request's posted records, oldest first, empty when none yet.
|
|
93
|
+
*/
|
|
94
|
+
async getSignatureRespondedEvents(requestId) {
|
|
95
|
+
return this.getRespondPostsNamed(SignetEventName.SignatureRespondedEvent, decodeSignatureRespondedEventPayload, requestId);
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
* Fetch
|
|
99
|
-
* signature must recover to
|
|
100
|
-
* (compared case-insensitively) over the signing hash of
|
|
101
|
-
* the request record describes. The first valid post wins,
|
|
102
|
-
* gets a verdict so callers can report the noise.
|
|
98
|
+
* Fetch the signature responses posted under `requestId` and verify each
|
|
99
|
+
* against the request: a post's signature must recover to
|
|
100
|
+
* `expectedSigner` (compared case-insensitively) over the signing hash of
|
|
101
|
+
* the transaction the request record describes. The first valid post wins,
|
|
102
|
+
* and every candidate gets a verdict so callers can report the noise. The
|
|
103
|
+
* declared id only routes: this verification is what separates the genuine
|
|
104
|
+
* response from garbage posted under the same id.
|
|
103
105
|
*
|
|
104
106
|
* @param requestId - The request id to fetch a verified response for.
|
|
105
107
|
* @param expectedSigner - The EVM address (0x hex, any case) the genuine
|
|
106
108
|
* response must be signed by: the requester's MPC-derived address.
|
|
107
109
|
* @returns The first valid response (if any) plus per-post verdicts.
|
|
108
|
-
* @throws Error when
|
|
109
|
-
*
|
|
110
|
+
* @throws Error when the requester contract has no state or the request is
|
|
111
|
+
* not on its ledger.
|
|
110
112
|
*/
|
|
111
113
|
async getVerifiedSignatureRespondedEvent(requestId, expectedSigner) {
|
|
112
114
|
const request = await this.getSignatureRequest(requestId);
|
|
113
|
-
const responses = await this.
|
|
114
|
-
const verdicts = responses.map((response,
|
|
115
|
-
const
|
|
115
|
+
const responses = await this.getSignatureRespondedEvents(requestId);
|
|
116
|
+
const verdicts = responses.map((response, position) => {
|
|
117
|
+
const index = BigInt(position);
|
|
116
118
|
let signer;
|
|
117
119
|
try {
|
|
118
120
|
signer = recoverSignatureResponseSigner(request, response);
|
|
119
121
|
}
|
|
120
122
|
catch (error) {
|
|
121
123
|
return {
|
|
122
|
-
|
|
124
|
+
index,
|
|
123
125
|
response,
|
|
124
126
|
rejectedReason: `not a decodable signature (${String(error)})`,
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
129
|
if (signer.toLowerCase() !== expectedSigner.toLowerCase()) {
|
|
128
130
|
return {
|
|
129
|
-
|
|
131
|
+
index,
|
|
130
132
|
response,
|
|
131
133
|
signer,
|
|
132
134
|
rejectedReason: `signed by ${signer}, expected ${expectedSigner}`,
|
|
133
135
|
};
|
|
134
136
|
}
|
|
135
|
-
return {
|
|
137
|
+
return { index, response, signer };
|
|
136
138
|
});
|
|
137
139
|
return {
|
|
138
140
|
verified: verdicts.find((v) => v.rejectedReason === undefined)?.response,
|
|
@@ -142,7 +144,7 @@ export class SignetRequestResponseReader {
|
|
|
142
144
|
/**
|
|
143
145
|
* Rebuild the unsigned EIP-1559 transaction for `requestId`: the exact
|
|
144
146
|
* transaction the MPC signs, assembled from the request record's decomposed
|
|
145
|
-
* fields. No
|
|
147
|
+
* fields. No event query: this needs only the request record
|
|
146
148
|
* (fetched via {@link getSignatureRequest}, cached).
|
|
147
149
|
*
|
|
148
150
|
* @param requestId - The request id whose transaction to rebuild.
|
|
@@ -158,7 +160,7 @@ export class SignetRequestResponseReader {
|
|
|
158
160
|
* Assemble the broadcast-ready signed EIP-1559 transaction for `requestId`:
|
|
159
161
|
* rebuild the request's transaction and attach the first VERIFIED response
|
|
160
162
|
* signed by `expectedSigner` (see {@link getVerifiedSignatureRespondedEvent}:
|
|
161
|
-
* the
|
|
163
|
+
* the event log is unauthenticated, so an `expectedSigner` is required
|
|
162
164
|
* and unverified posts are never attached).
|
|
163
165
|
*
|
|
164
166
|
* @param requestId - The request id to produce a signed transaction for.
|
|
@@ -167,8 +169,8 @@ export class SignetRequestResponseReader {
|
|
|
167
169
|
* @returns The signed ethers transaction (`serialized` is the payload for
|
|
168
170
|
* `eth_sendRawTransaction`), or `undefined` when no valid response has
|
|
169
171
|
* been posted yet: poll again.
|
|
170
|
-
* @throws Error when
|
|
171
|
-
*
|
|
172
|
+
* @throws Error when the requester contract has no state or the request is
|
|
173
|
+
* not on its ledger.
|
|
172
174
|
*/
|
|
173
175
|
async getSignedEvmTransaction(requestId, expectedSigner) {
|
|
174
176
|
const { verified } = await this.getVerifiedSignatureRespondedEvent(requestId, expectedSigner);
|
|
@@ -181,56 +183,40 @@ export class SignetRequestResponseReader {
|
|
|
181
183
|
return signBidirectionalEventToSignedEvmTransaction(request, verified);
|
|
182
184
|
}
|
|
183
185
|
/**
|
|
184
|
-
* Fetch every respond-bidirectional response posted
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
186
|
+
* Fetch every respond-bidirectional response posted under `requestId`, in
|
|
187
|
+
* emission order. UNVERIFIED: the declared id is routing data on an
|
|
188
|
+
* unauthenticated event log, so verifying a post against the MPC response
|
|
189
|
+
* key you expect is still the only way to pick the genuine one: in-circuit
|
|
190
|
+
* at claim time, or off chain with
|
|
191
|
+
* {@link verifyRespondBidirectionalSignature} over the output you fetched.
|
|
192
|
+
* An empty array simply means none posted yet: poll again.
|
|
191
193
|
*
|
|
192
|
-
* @param requestId - The request id
|
|
193
|
-
* @returns The posted records,
|
|
194
|
-
* @throws Error when the signet contract has no state, or its counter
|
|
195
|
-
* disagrees with the log (inconsistent ledger).
|
|
194
|
+
* @param requestId - The request id the posts must declare.
|
|
195
|
+
* @returns The request's posted records, oldest first, empty when none yet.
|
|
196
196
|
*/
|
|
197
197
|
async getRespondBidirectionalEvents(requestId) {
|
|
198
|
-
|
|
199
|
-
const { respondBidirectionalCounterMap, respondBidirectionalMap } = readSignetContractLedgerFromState(raw);
|
|
200
|
-
const totalPosts = respondBidirectionalCounterMap.get(requestId) ?? 0n;
|
|
201
|
-
const responses = [];
|
|
202
|
-
for (let count = 0n; count < totalPosts; count++) {
|
|
203
|
-
const response = respondBidirectionalMap.get(signetMapEntryKey(requestId, count));
|
|
204
|
-
if (response === undefined) {
|
|
205
|
-
throw new Error(`respond-bidirectional log has no entry ${count} for request ${requestId} ` +
|
|
206
|
-
`despite its counter reading ${totalPosts}: ledger state is inconsistent`);
|
|
207
|
-
}
|
|
208
|
-
responses.push(response);
|
|
209
|
-
}
|
|
210
|
-
return responses;
|
|
198
|
+
return this.getRespondPostsNamed(SignetEventName.RespondBidirectionalEvent, decodeRespondBidirectionalEventPayload, requestId);
|
|
211
199
|
}
|
|
212
200
|
/**
|
|
213
|
-
* Fetch the respond-bidirectional posts
|
|
214
|
-
* first (
|
|
201
|
+
* Fetch the respond-bidirectional posts declared under `requestId` and
|
|
202
|
+
* return the first (oldest) one whose signature verifies over
|
|
215
203
|
* `serializedOutput` against `mpcResponseKey`: the off-chain twin of the
|
|
216
204
|
* check the client contract runs in-circuit, and the only way to pick a
|
|
217
|
-
* genuine post out of an unauthenticated log
|
|
218
|
-
* but a signature.
|
|
205
|
+
* genuine post out of an unauthenticated event log.
|
|
219
206
|
*
|
|
220
207
|
* The output must be the exact unpadded bytes the attestation commits to
|
|
221
208
|
* (the packed respond payload, recomputed from the execution output the
|
|
222
209
|
* client fetched), so a post that verifies here is the post that proves at
|
|
223
210
|
* claim time.
|
|
224
211
|
*
|
|
225
|
-
* @param requestId - The request id
|
|
212
|
+
* @param requestId - The request id the posts must declare and the
|
|
213
|
+
* attestation must commit to.
|
|
226
214
|
* @param serializedOutput - The serialised execution output the attestation
|
|
227
215
|
* must commit to, exact unpadded bytes.
|
|
228
216
|
* @param mpcResponseKey - The MPC response key the requesting contract
|
|
229
217
|
* pinned at deploy (see `deriveMidnightResponseKey`).
|
|
230
218
|
* @returns The first verifying post, or `undefined` when none has been
|
|
231
219
|
* posted yet (poll again) or none attests this output.
|
|
232
|
-
* @throws Error when the signet contract has no state, or its counter
|
|
233
|
-
* disagrees with the log (inconsistent ledger).
|
|
234
220
|
*/
|
|
235
221
|
async getVerifiedRespondBidirectionalEvent(requestId, serializedOutput, mpcResponseKey) {
|
|
236
222
|
const events = await this.getRespondBidirectionalEvents(requestId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signet-request-response-reader.js","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,
|
|
1
|
+
{"version":3,"file":"signet-request-response-reader.js","sourceRoot":"","sources":["../src/signet-request-response-reader.ts"],"names":[],"mappings":"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"}
|
package/dist/signet-requests.js
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
// the assertion, so any structural drift between the generated managed types
|
|
17
17
|
// and these twins fails that package's `yarn build` / `yarn test`.
|
|
18
18
|
//
|
|
19
|
-
// Read more:
|
|
20
|
-
//
|
|
19
|
+
// Read more: the module header in Signet.compact (key derivation, event
|
|
20
|
+
// flow) and this package's README ("Sign bidirectional flow").
|
|
21
21
|
import { CompactTypeBoolean, CompactTypeBytes, CompactTypeEnum, CompactTypeUnsignedInteger, } from "@midnight-ntwrk/compact-runtime";
|
|
22
22
|
/**
|
|
23
23
|
* Which transaction-param decomposition a request carries (Compact:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signet-requests.js","sourceRoot":"","sources":["../src/signet-requests.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,sEAAsE;AACtE,EAAE;AACF,iEAAiE;AACjE,2EAA2E;AAC3E,8EAA8E;AAC9E,gDAAgD;AAChD,EAAE;AACF,6EAA6E;AAC7E,mFAAmF;AACnF,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,wEAAwE;AACxE
|
|
1
|
+
{"version":3,"file":"signet-requests.js","sourceRoot":"","sources":["../src/signet-requests.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sig-net/midnight",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sig-net/midnight-integration",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@midnight-ntwrk/compact-runtime": "0.18.0-rc.1",
|
|
41
41
|
"@midnight-ntwrk/midnight-js-types": "5.0.0-beta.4",
|
|
42
42
|
"@noble/curves": "^2.2.0",
|
|
43
|
-
"@sig-net/midnight-serde": "^0.
|
|
43
|
+
"@sig-net/midnight-serde": "^0.16.0",
|
|
44
44
|
"ethers": "^6.17.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
package/src/Signet.compact
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
// Terms:
|
|
7
7
|
// - client contract(s): contracts on the Midnight blockchain that integrate with the Signet Distributed MPC
|
|
8
8
|
// to execute arbitrary transactions on foreign blockchains.
|
|
9
|
-
// - Signet singleton: a single contract on the Midnight blockchain
|
|
10
|
-
// signature requests and
|
|
11
|
-
//
|
|
9
|
+
// - Signet singleton: a single contract on the Midnight blockchain through which clients notify the MPC of
|
|
10
|
+
// signature requests, and through which the MPC posts back signatures and signed attestations
|
|
11
|
+
// of foreign executions. Each post is emitted as a contract event (the execution
|
|
12
|
+
// outputs themselves travel off chain).
|
|
12
13
|
//
|
|
13
14
|
// Usage:
|
|
14
15
|
// // Import this module at the start of a contract (resolved through node_modules via COMPACT_PATH):
|
|
@@ -28,28 +29,34 @@
|
|
|
28
29
|
// - SignBidirectionalEventNotification: Notification delivered by client contracts via cross contract call to Signet singleton
|
|
29
30
|
// (via SignetSigner interface) to notify the MPC of a SignBidirectionalEvent.
|
|
30
31
|
// - SignatureRespondedEvent: Counterpart to SignBidirectionalEvent containing MPC generated signature requested by a SignBidirectionalEvent.
|
|
31
|
-
// Posted by MPC
|
|
32
|
+
// Posted by the MPC through the Signet singleton, which emits it as a contract
|
|
33
|
+
// event. Clients extract it to build a signed transaction.
|
|
32
34
|
// - RespondBidirectionalEvent: Attestation of a transaction executed on a foreign blockchain: the MPC's ECDSA
|
|
33
35
|
// signature over the attestation digest of the request id and serialised output
|
|
34
36
|
// (see calculateSignetAttestationDigest), signed with the MPC's RESPONSE key for
|
|
35
37
|
// the requesting contract: the key derived from the client contract's address +
|
|
36
38
|
// the fixed path "midnight response key". Both the digest and the output itself
|
|
37
|
-
// travel off chain. Posted by MPC
|
|
38
|
-
//
|
|
39
|
-
// contract.
|
|
39
|
+
// travel off chain. Posted by the MPC through the Signet singleton, which
|
|
40
|
+
// emits it as a contract event. Clients extract it, verify it (see
|
|
41
|
+
// verifyRespondBidirectionalEvent) and deliver it back to the client contract.
|
|
40
42
|
//
|
|
41
43
|
// These key types are best understood within the sign bidirectional flow that they enable:
|
|
42
|
-
// 1. Client contract stores a SignBidirectionalEvent in a SignBidirectionalEventMap its own ledger
|
|
43
|
-
// (against the calculated RequestId) and requests a signature from the MPC
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
// 2. MPC polls the Signet singleton contract's
|
|
47
|
-
//
|
|
48
|
-
// signature and
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
44
|
+
// 1. Client contract stores a SignBidirectionalEvent in a SignBidirectionalEventMap in its own ledger
|
|
45
|
+
// (against the calculated RequestId) and requests a signature from the MPC via a cross contract call
|
|
46
|
+
// against the SignetSigner interface. The Signet singleton emits the
|
|
47
|
+
// SignBidirectionalEventNotification as a contract event.
|
|
48
|
+
// 2. MPC polls the Signet singleton contract's events for SignBidirectionalEventNotifications and uses
|
|
49
|
+
// each one to read the SignBidirectionalEvent signature requests from the named client's own ledger.
|
|
50
|
+
// It generates the signature and posts a SignatureRespondedEvent (the requested signature) through
|
|
51
|
+
// the Signet singleton, which emits it as a contract event.
|
|
52
|
+
// 3. Client polls the Signet singleton contract's SignatureRespondedEvent events. Each event carries
|
|
53
|
+
// the request id it answers beside the signature. The id is unauthenticated routing data: the client
|
|
54
|
+
// reads its own request's posts by id, verifies each candidate, and takes the first one whose
|
|
55
|
+
// signature recovers to its derived key. Then it broadcasts the signed txn to the destination chain.
|
|
56
|
+
// 4. MPC observes txn execution on destination chain and posts a RespondBidirectionalEvent attestation
|
|
57
|
+
// through the central Signet contract, which emits it as a contract event beside the request id.
|
|
58
|
+
// The client polls its request's posts and takes the first one that verifies over the request id
|
|
59
|
+
// and output.
|
|
53
60
|
// The client recovers the execution output itself off chain (for EVM: the mined
|
|
54
61
|
// call's return data via debug_traceTransaction, also served by the fakenet
|
|
55
62
|
// responder's /responses/{requestId} helper API) and hands output plus attestation
|
|
@@ -58,7 +65,8 @@
|
|
|
58
65
|
// Read more:
|
|
59
66
|
// - For full integration examples (such as an ERC20 cross chain vault example) see
|
|
60
67
|
// the Midnight Examples repository at: https://github.com/sig-net/midnight-examples.
|
|
61
|
-
// -
|
|
68
|
+
// - The sign bidirectional flow and key derivation: this package's README
|
|
69
|
+
// ("Sign bidirectional flow", "Derived keys").
|
|
62
70
|
// - Compact language reference (modules, types):
|
|
63
71
|
// https://docs.midnight.network/compact/reference/compact-reference
|
|
64
72
|
|
|
@@ -79,11 +87,15 @@ module Signet {
|
|
|
79
87
|
|
|
80
88
|
// MPC Key Derivation Parameters.
|
|
81
89
|
// Every key the MPC signs with is scoped by the requesting contract:
|
|
82
|
-
// derivedSigningKey = f(mpcRootKey[keyVersion], sender, path)
|
|
83
|
-
//
|
|
84
|
-
// for
|
|
85
|
-
//
|
|
86
|
-
//
|
|
90
|
+
// derivedSigningKey = f(mpcRootKey[keyVersion], caip2ChainId, sender, hex::encode(path))
|
|
91
|
+
// where caip2ChainId is the CAIP-2 id of the ORIGINATING chain (the Midnight
|
|
92
|
+
// variant for requests made from Midnight contracts), not this record's target
|
|
93
|
+
// caip2Id. The path is 32 opaque bytes of the client contract's choosing (e.g a
|
|
94
|
+
// fixed literal for a contract-owned account or a hash of a caller's secret for
|
|
95
|
+
// per-user accounts): no format is enforced, any 32 bytes are valid. CRITICAL:
|
|
96
|
+
// the MPC renders the path as hex::encode(path) before deriving (lowercase hex
|
|
97
|
+
// of the full 32 bytes, no trimming, no 0x prefix). The sender is always part
|
|
98
|
+
// of the derivation, so no contract can reach another contract's derived keys.
|
|
87
99
|
keyVersion: Uint<8>; // MPC root-key version to derive from. Set to 1.
|
|
88
100
|
path: Bytes<32>; // Key derivation path: 32 opaque bytes, client contract's choice.
|
|
89
101
|
|
|
@@ -203,7 +215,7 @@ module Signet {
|
|
|
203
215
|
// Versioned notification of the SignBidirectionalEvent
|
|
204
216
|
// (construct with constructSignBidirectionalEventNotificationV1).
|
|
205
217
|
notification: SignBidirectionalEventNotification
|
|
206
|
-
):
|
|
218
|
+
): [];
|
|
207
219
|
}
|
|
208
220
|
|
|
209
221
|
// Notification delivered by client contracts via cross contract call to Signet singleton
|
|
@@ -310,8 +322,10 @@ module Signet {
|
|
|
310
322
|
// signature = signSECP256k1(mpcResponseKey, attestationDigest)
|
|
311
323
|
//
|
|
312
324
|
// Where the MPC response key is a per-client-contract key derived using the same derivation function
|
|
313
|
-
// as request signing keys, with the path set to the fixed "midnight response key"
|
|
314
|
-
//
|
|
325
|
+
// as request signing keys, with the path set to the fixed "midnight response key" (a protocol
|
|
326
|
+
// string that enters the derivation verbatim, unlike a request's 32 path bytes which are
|
|
327
|
+
// hex-encoded first):
|
|
328
|
+
// mpcResponseKey = f(mpcRootKey[keyVersion], caip2ChainId, sender, "midnight response key")
|
|
315
329
|
//
|
|
316
330
|
// Storage & Verification:
|
|
317
331
|
// The execution output is of variable size, so it travels off chain, and the digest
|
|
@@ -319,19 +333,12 @@ module Signet {
|
|
|
319
333
|
// the attestation digest and verifies the signature in-circuit via
|
|
320
334
|
// verifyRespondBidirectionalEvent against its derived MPC response key. The signature
|
|
321
335
|
// is the ONLY thing that distinguishes a genuine post from garbage: the Signet
|
|
322
|
-
// singleton is an unauthenticated log and
|
|
336
|
+
// singleton is an unauthenticated log and emits every post unverified.
|
|
323
337
|
export struct RespondBidirectionalEvent {
|
|
324
338
|
// The MPC's ECDSA signature over the attestation digest.
|
|
325
339
|
signature: Signature;
|
|
326
340
|
}
|
|
327
341
|
|
|
328
|
-
// SignetMapKey used to locate SignBidirectionalEventNotifications, SignatureRespondedEvent and
|
|
329
|
-
// RespondBidirectionalEvents in Signet singleton contract storage.
|
|
330
|
-
export struct SignetMapKey {
|
|
331
|
-
count: Uint<64>;
|
|
332
|
-
requestId: RequestId;
|
|
333
|
-
};
|
|
334
|
-
|
|
335
342
|
// Calculates the 32-byte attestation digest for a remote execution output:
|
|
336
343
|
// attestationDigest = keccak256(requestId + serializedOutput)
|
|
337
344
|
//
|
|
@@ -371,7 +378,7 @@ module Signet {
|
|
|
371
378
|
// signatures, and one that is not simply fails to verify.
|
|
372
379
|
//
|
|
373
380
|
// Note: Client contracts must run this check before consuming outputs, as the Signet
|
|
374
|
-
// singleton
|
|
381
|
+
// singleton emits responses unverified.
|
|
375
382
|
export pure circuit verifyRespondBidirectionalEvent<#serializedOutputLength>(
|
|
376
383
|
requestId: RequestId,
|
|
377
384
|
serializedOutput: Bytes<serializedOutputLength>,
|