@openzeppelin/guardian-client 0.18.3 → 0.19.0-rc.2
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 +127 -9
- package/dist/auth-request.d.ts +13 -0
- package/dist/auth-request.d.ts.map +1 -1
- package/dist/auth-request.js +26 -5
- package/dist/auth-request.js.map +1 -1
- package/dist/conversion.d.ts +8 -2
- package/dist/conversion.d.ts.map +1 -1
- package/dist/conversion.js +46 -3
- package/dist/conversion.js.map +1 -1
- package/dist/error-codes.d.ts +3 -5
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +23 -4
- package/dist/error-codes.js.map +1 -1
- package/dist/execution.d.ts +99 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +124 -0
- package/dist/execution.js.map +1 -0
- package/dist/http.d.ts +81 -5
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +179 -27
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/request-envelope.d.ts +22 -0
- package/dist/request-envelope.d.ts.map +1 -0
- package/dist/request-envelope.js +51 -0
- package/dist/request-envelope.js.map +1 -0
- package/dist/server-types.d.ts +33 -0
- package/dist/server-types.d.ts.map +1 -1
- package/dist/session-request.d.ts +104 -0
- package/dist/session-request.d.ts.map +1 -0
- package/dist/session-request.js +164 -0
- package/dist/session-request.js.map +1 -0
- package/dist/types.d.ts +124 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/auth-request.test.ts +12 -0
- package/src/auth-request.ts +37 -5
- package/src/conversion.test.ts +98 -0
- package/src/conversion.ts +59 -3
- package/src/dependencies.test.ts +25 -0
- package/src/error-codes.test.ts +14 -1
- package/src/error-codes.ts +23 -4
- package/src/execution.test.ts +145 -0
- package/src/execution.ts +206 -0
- package/src/http.test.ts +752 -19
- package/src/http.ts +244 -30
- package/src/index.ts +50 -1
- package/src/request-envelope.test.ts +30 -0
- package/src/request-envelope.ts +68 -0
- package/src/server-types.ts +35 -1
- package/src/session-request.test.ts +178 -0
- package/src/session-request.ts +191 -0
- package/src/types.ts +129 -4
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/guardian-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0-rc.2",
|
|
4
4
|
"description": "TypeScript HTTP client for Guardian server",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"vitest": "^5.0.0"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
|
-
"node": ">=
|
|
42
|
+
"node": ">=20"
|
|
43
43
|
},
|
|
44
44
|
"license": "MIT"
|
|
45
45
|
}
|
package/src/auth-request.test.ts
CHANGED
|
@@ -8,4 +8,16 @@ describe('RequestAuthPayload', () => {
|
|
|
8
8
|
|
|
9
9
|
expect(left.toCanonicalJson()).toEqual(right.toCanonicalJson());
|
|
10
10
|
});
|
|
11
|
+
|
|
12
|
+
it('prefixes an operation payload with its tag and a zero byte, and keeps the canonical JSON', () => {
|
|
13
|
+
const request = { proposal_id: '0x22', account_id: '0x11' };
|
|
14
|
+
const plain = RequestAuthPayload.fromRequest(request);
|
|
15
|
+
const tagged = RequestAuthPayload.forOperation('ExecuteDeltaProposal', request);
|
|
16
|
+
|
|
17
|
+
const tag = new TextEncoder().encode('guardian.ExecuteDeltaProposal');
|
|
18
|
+
const json = new TextEncoder().encode('{"account_id":"0x11","proposal_id":"0x22"}');
|
|
19
|
+
expect(Array.from(tagged.toBytes())).toEqual([...tag, 0, ...json]);
|
|
20
|
+
expect(Array.from(plain.toBytes())).toEqual([...json]);
|
|
21
|
+
expect(tagged.toCanonicalJson()).toBe(plain.toCanonicalJson());
|
|
22
|
+
});
|
|
11
23
|
});
|
package/src/auth-request.ts
CHANGED
|
@@ -6,13 +6,40 @@ type JsonValue =
|
|
|
6
6
|
| JsonValue[]
|
|
7
7
|
| { [key: string]: JsonValue };
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* An operation whose signed payload is domain-separated from every other request's, so a
|
|
11
|
+
* signature over one never authenticates another request with the same body. Mirrors the Rust
|
|
12
|
+
* `SignedOperation`.
|
|
13
|
+
*/
|
|
14
|
+
export type SignedOperation = 'ExecuteDeltaProposal';
|
|
15
|
+
|
|
16
|
+
function operationTag(operation: SignedOperation): string {
|
|
17
|
+
switch (operation) {
|
|
18
|
+
case 'ExecuteDeltaProposal':
|
|
19
|
+
return 'guardian.ExecuteDeltaProposal\0';
|
|
20
|
+
default: {
|
|
21
|
+
const unreachable: never = operation;
|
|
22
|
+
throw new Error(`Unknown signed operation: ${JSON.stringify(unreachable)}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
9
27
|
export class RequestAuthPayload {
|
|
10
|
-
private constructor(
|
|
28
|
+
private constructor(
|
|
29
|
+
private readonly canonicalJson: string,
|
|
30
|
+
private readonly tag: string,
|
|
31
|
+
) {}
|
|
11
32
|
|
|
12
33
|
static fromRequest(requestPayload: unknown): RequestAuthPayload {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
return new RequestAuthPayload(RequestAuthPayload.canonicalJsonOf(requestPayload), '');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The payload of `requestPayload` signed as `operation`: the bytes are the operation's tag
|
|
39
|
+
* followed by the canonical JSON, as the Rust `AuthRequestPayload::for_operation` builds them.
|
|
40
|
+
*/
|
|
41
|
+
static forOperation(operation: SignedOperation, requestPayload: unknown): RequestAuthPayload {
|
|
42
|
+
return new RequestAuthPayload(RequestAuthPayload.canonicalJsonOf(requestPayload), operationTag(operation));
|
|
16
43
|
}
|
|
17
44
|
|
|
18
45
|
toCanonicalJson(): string {
|
|
@@ -20,7 +47,12 @@ export class RequestAuthPayload {
|
|
|
20
47
|
}
|
|
21
48
|
|
|
22
49
|
toBytes(): Uint8Array {
|
|
23
|
-
return new TextEncoder().encode(this.canonicalJson);
|
|
50
|
+
return new TextEncoder().encode(this.tag + this.canonicalJson);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private static canonicalJsonOf(requestPayload: unknown): string {
|
|
54
|
+
const normalized = RequestAuthPayload.normalizeJson(requestPayload);
|
|
55
|
+
return JSON.stringify(RequestAuthPayload.canonicalizeJson(normalized));
|
|
24
56
|
}
|
|
25
57
|
|
|
26
58
|
private static normalizeJson(value: unknown): JsonValue {
|
package/src/conversion.test.ts
CHANGED
|
@@ -237,9 +237,51 @@ describe('conversion', () => {
|
|
|
237
237
|
|
|
238
238
|
expect(result.newCommitment).toBeUndefined();
|
|
239
239
|
expect(result.deltaPayload.metadata).toBeUndefined();
|
|
240
|
+
expect(result.deltaPayload.transactionRequest).toBeUndefined();
|
|
240
241
|
expect(result.ackSig).toBeUndefined();
|
|
241
242
|
});
|
|
242
243
|
|
|
244
|
+
it('round-trips the stored transaction request from a read back into a push', () => {
|
|
245
|
+
const envelope = { format_version: 1, protocol_line: '0.17', checksum: '0xabc', bytes: 'AQID' };
|
|
246
|
+
const server: ServerDeltaObject = {
|
|
247
|
+
account_id: '0xaccount',
|
|
248
|
+
nonce: 1,
|
|
249
|
+
prev_commitment: '0xprev',
|
|
250
|
+
delta_payload: {
|
|
251
|
+
tx_summary: { data: 'base64data' },
|
|
252
|
+
signatures: [],
|
|
253
|
+
transaction_request: envelope,
|
|
254
|
+
},
|
|
255
|
+
status: { status: 'pending', timestamp: '2024-01-01T00:00:00Z', proposer_id: '0xp', cosigner_sigs: [] },
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const fetched = fromServerDeltaObject(server);
|
|
259
|
+
expect(fetched.deltaPayload.transactionRequest).toEqual(envelope);
|
|
260
|
+
|
|
261
|
+
const reposted = toServerDeltaProposalRequest({
|
|
262
|
+
accountId: fetched.accountId,
|
|
263
|
+
nonce: fetched.nonce,
|
|
264
|
+
deltaPayload: fetched.deltaPayload,
|
|
265
|
+
});
|
|
266
|
+
expect(reposted.delta_payload.transaction_request).toEqual(envelope);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('refuses a stored transaction request with a missing field', () => {
|
|
270
|
+
const server = {
|
|
271
|
+
account_id: '0xaccount',
|
|
272
|
+
nonce: 1,
|
|
273
|
+
prev_commitment: '0xprev',
|
|
274
|
+
delta_payload: {
|
|
275
|
+
tx_summary: { data: 'base64data' },
|
|
276
|
+
signatures: [],
|
|
277
|
+
transaction_request: { format_version: 1, protocol_line: '0.17', bytes: 'AQID' },
|
|
278
|
+
},
|
|
279
|
+
status: { status: 'pending', timestamp: '2024-01-01T00:00:00Z', proposer_id: '0xp', cosigner_sigs: [] },
|
|
280
|
+
} as unknown as ServerDeltaObject;
|
|
281
|
+
|
|
282
|
+
expect(() => fromServerDeltaObject(server)).toThrow(/invalid checksum/);
|
|
283
|
+
});
|
|
284
|
+
|
|
243
285
|
it('converts StateObject', () => {
|
|
244
286
|
const server: ServerStateObject = {
|
|
245
287
|
account_id: '0xaccount',
|
|
@@ -360,6 +402,45 @@ describe('conversion', () => {
|
|
|
360
402
|
});
|
|
361
403
|
});
|
|
362
404
|
|
|
405
|
+
it('carries per-signer schemes in ProposalMetadata both ways (issue #563)', () => {
|
|
406
|
+
const server: ServerProposalMetadata = {
|
|
407
|
+
proposal_type: 'add_signer',
|
|
408
|
+
target_threshold: 2,
|
|
409
|
+
signer_commitments: ['0x1', '0x2'],
|
|
410
|
+
signer_schemes: ['falcon', 'ecdsa'],
|
|
411
|
+
};
|
|
412
|
+
const meta = fromServerProposalMetadata(server);
|
|
413
|
+
expect(meta.signerSchemes).toEqual(['falcon', 'ecdsa']);
|
|
414
|
+
expect(toServerProposalMetadata(meta).signer_schemes).toEqual(['falcon', 'ecdsa']);
|
|
415
|
+
|
|
416
|
+
// Absent on the wire stays absent: single-scheme proposals are unchanged.
|
|
417
|
+
const legacy = toServerProposalMetadata(
|
|
418
|
+
fromServerProposalMetadata({ proposal_type: 'add_signer', signer_commitments: ['0x1'] }),
|
|
419
|
+
);
|
|
420
|
+
expect(JSON.parse(JSON.stringify(legacy))).toEqual({
|
|
421
|
+
proposal_type: 'add_signer',
|
|
422
|
+
signer_commitments: ['0x1'],
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('passes a per-signer-scheme Miden auth through ConfigureRequest unchanged', () => {
|
|
427
|
+
const auth = {
|
|
428
|
+
Miden: {
|
|
429
|
+
cosigners: [
|
|
430
|
+
{ commitment: '0x1', scheme: 'falcon' as const },
|
|
431
|
+
{ commitment: '0x2', scheme: 'ecdsa' as const },
|
|
432
|
+
],
|
|
433
|
+
guardian_scheme: 'ecdsa' as const,
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
const result = toServerConfigureRequest({
|
|
437
|
+
accountId: '0xaccount',
|
|
438
|
+
auth,
|
|
439
|
+
initialState: { data: 'statedata', accountId: '0xaccount' },
|
|
440
|
+
});
|
|
441
|
+
expect(result.auth).toEqual(auth);
|
|
442
|
+
});
|
|
443
|
+
|
|
363
444
|
it('converts ConfigureRequest', () => {
|
|
364
445
|
const req: ConfigureRequest = {
|
|
365
446
|
accountId: '0xaccount',
|
|
@@ -394,6 +475,23 @@ describe('conversion', () => {
|
|
|
394
475
|
expect(result.delta_payload.tx_summary.data).toBe('base64data');
|
|
395
476
|
expect(result.delta_payload.signatures[0].signer_id).toBe('0xsig');
|
|
396
477
|
expect(result.delta_payload.metadata?.proposal_type).toBe('add_signer');
|
|
478
|
+
expect('base_commitment' in result.delta_payload).toBe(false);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it('carries the base a proposal was built on in its payload', () => {
|
|
482
|
+
const base = '0x' + 'c'.repeat(64);
|
|
483
|
+
const result = toServerDeltaProposalRequest({
|
|
484
|
+
accountId: '0xaccount',
|
|
485
|
+
nonce: 6,
|
|
486
|
+
deltaPayload: {
|
|
487
|
+
txSummary: { data: 'base64data' },
|
|
488
|
+
signatures: [],
|
|
489
|
+
baseCommitment: base,
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
expect(result.delta_payload.base_commitment).toBe(base);
|
|
494
|
+
expect(Object.keys(result)).toEqual(['account_id', 'nonce', 'delta_payload']);
|
|
397
495
|
});
|
|
398
496
|
|
|
399
497
|
it('converts SignProposalRequest', () => {
|
package/src/conversion.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SESSION_REQUEST_VERSION,
|
|
3
|
+
assertSupportedSessionPolicy,
|
|
4
|
+
} from './session-request.js';
|
|
1
5
|
import type {
|
|
2
6
|
CanonicalNonce,
|
|
3
7
|
CosignerSignature,
|
|
@@ -17,6 +21,7 @@ import type {
|
|
|
17
21
|
ProposalMetadata,
|
|
18
22
|
SignProposalRequest,
|
|
19
23
|
StateObject,
|
|
24
|
+
StateTail,
|
|
20
25
|
} from './types.js';
|
|
21
26
|
import type {
|
|
22
27
|
ServerCanonicalNonceResponse,
|
|
@@ -37,12 +42,15 @@ import type {
|
|
|
37
42
|
ServerProposalMetadata,
|
|
38
43
|
ServerSignProposalRequest,
|
|
39
44
|
ServerStateObject,
|
|
45
|
+
ServerStateTail,
|
|
40
46
|
} from './server-types.js';
|
|
47
|
+
import { decodeTransactionRequestEnvelope, type TransactionRequestEnvelope } from './request-envelope.js';
|
|
41
48
|
|
|
42
49
|
type ServerProposalDeltaPayload = {
|
|
43
50
|
tx_summary: { data: string };
|
|
44
51
|
signatures?: Array<{ signer_id: string; signature: ServerProposalSignature }>;
|
|
45
52
|
metadata?: ServerProposalMetadata;
|
|
53
|
+
transaction_request?: unknown;
|
|
46
54
|
};
|
|
47
55
|
|
|
48
56
|
type ServerExecutionDeltaPayload = {
|
|
@@ -57,11 +65,16 @@ function extractDeltaPayload(payload: ServerDeltaPayload): {
|
|
|
57
65
|
txSummary: { data: string };
|
|
58
66
|
signatures: Array<{ signer_id: string; signature: ServerProposalSignature }>;
|
|
59
67
|
metadata?: ServerProposalMetadata;
|
|
68
|
+
transactionRequest?: TransactionRequestEnvelope;
|
|
60
69
|
} {
|
|
61
70
|
const txSummary = 'tx_summary' in payload ? payload.tx_summary : { data: payload.data };
|
|
62
71
|
const signatures = 'signatures' in payload && Array.isArray(payload.signatures) ? payload.signatures : [];
|
|
63
72
|
const metadata = 'metadata' in payload ? payload.metadata : undefined;
|
|
64
|
-
|
|
73
|
+
const transactionRequest =
|
|
74
|
+
'transaction_request' in payload && payload.transaction_request !== undefined && payload.transaction_request !== null
|
|
75
|
+
? decodeTransactionRequestEnvelope(payload.transaction_request)
|
|
76
|
+
: undefined;
|
|
77
|
+
return { txSummary, signatures, metadata, transactionRequest };
|
|
65
78
|
}
|
|
66
79
|
|
|
67
80
|
export function fromServerSignature(signature: ServerProposalSignature): ProposalSignature {
|
|
@@ -110,6 +123,7 @@ export function fromServerProposalMetadata(server: ServerProposalMetadata): Prop
|
|
|
110
123
|
targetThreshold: server.target_threshold,
|
|
111
124
|
requiredSignatures: server.required_signatures,
|
|
112
125
|
signerCommitments: server.signer_commitments,
|
|
126
|
+
signerSchemes: server.signer_schemes,
|
|
113
127
|
targetProcedure: server.target_procedure,
|
|
114
128
|
salt: server.salt,
|
|
115
129
|
description: server.description,
|
|
@@ -130,7 +144,9 @@ export function fromServerProposalMetadata(server: ServerProposalMetadata): Prop
|
|
|
130
144
|
}
|
|
131
145
|
|
|
132
146
|
export function fromServerDeltaObject(server: ServerDeltaObject): DeltaObject {
|
|
133
|
-
const { txSummary, signatures, metadata } = extractDeltaPayload(
|
|
147
|
+
const { txSummary, signatures, metadata, transactionRequest } = extractDeltaPayload(
|
|
148
|
+
server.delta_payload as ServerDeltaPayload
|
|
149
|
+
);
|
|
134
150
|
|
|
135
151
|
return {
|
|
136
152
|
accountId: server.account_id,
|
|
@@ -144,6 +160,7 @@ export function fromServerDeltaObject(server: ServerDeltaObject): DeltaObject {
|
|
|
144
160
|
signature: fromServerSignature(s.signature),
|
|
145
161
|
})),
|
|
146
162
|
metadata: metadata ? fromServerProposalMetadata(metadata) : undefined,
|
|
163
|
+
...(transactionRequest ? { transactionRequest } : {}),
|
|
147
164
|
},
|
|
148
165
|
ackSig: server.ack_sig,
|
|
149
166
|
ackPubkey: server.ack_pubkey,
|
|
@@ -163,6 +180,28 @@ export function fromServerStateObject(server: ServerStateObject): StateObject {
|
|
|
163
180
|
};
|
|
164
181
|
}
|
|
165
182
|
|
|
183
|
+
export function fromServerStateTail(server: ServerStateTail): StateTail {
|
|
184
|
+
if (typeof server.accepts_submissions !== 'boolean') {
|
|
185
|
+
throw new Error(
|
|
186
|
+
`Invalid accepts_submissions from server: ${String(server.accepts_submissions)}`,
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
state: fromServerStateObject(server.state),
|
|
191
|
+
acceptsSubmissions: server.accepts_submissions,
|
|
192
|
+
queue: server.queue.map((candidate) => {
|
|
193
|
+
if (!Number.isSafeInteger(candidate.nonce) || candidate.nonce < 0) {
|
|
194
|
+
throw new Error(`Invalid queued candidate nonce from server: ${String(candidate.nonce)}`);
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
nonce: candidate.nonce,
|
|
198
|
+
prevCommitment: candidate.prev_commitment,
|
|
199
|
+
newCommitment: candidate.new_commitment,
|
|
200
|
+
};
|
|
201
|
+
}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
166
205
|
export function fromServerCanonicalNonce(server: ServerCanonicalNonceResponse): CanonicalNonce {
|
|
167
206
|
if (!Number.isSafeInteger(server.nonce) || server.nonce < 0) {
|
|
168
207
|
throw new Error(`Invalid canonical nonce from server: ${String(server.nonce)}`);
|
|
@@ -238,6 +277,7 @@ export function toServerProposalMetadata(meta: ProposalMetadata): ServerProposal
|
|
|
238
277
|
target_threshold: meta.targetThreshold,
|
|
239
278
|
required_signatures: meta.requiredSignatures,
|
|
240
279
|
signer_commitments: meta.signerCommitments,
|
|
280
|
+
signer_schemes: meta.signerSchemes,
|
|
241
281
|
target_procedure: meta.targetProcedure,
|
|
242
282
|
salt: meta.salt,
|
|
243
283
|
description: meta.description,
|
|
@@ -283,10 +323,20 @@ export function toServerCreateSessionRequest(req: CreateSessionRequest): ServerC
|
|
|
283
323
|
};
|
|
284
324
|
}
|
|
285
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Throws `UnsupportedAuthVersionError` unless the server reports the
|
|
328
|
+
* session request version this client signs: such a server would refuse
|
|
329
|
+
* every session request.
|
|
330
|
+
*/
|
|
286
331
|
export function fromServerCreateSessionResponse(
|
|
287
332
|
server: ServerCreateSessionResponse
|
|
288
333
|
): CreateSessionResponse {
|
|
289
|
-
|
|
334
|
+
assertSupportedSessionPolicy({ requestAuthVersion: server.request_auth_version });
|
|
335
|
+
return {
|
|
336
|
+
signerCommitment: server.signer_commitment,
|
|
337
|
+
expiresAt: server.expires_at,
|
|
338
|
+
requestAuthVersion: SESSION_REQUEST_VERSION,
|
|
339
|
+
};
|
|
290
340
|
}
|
|
291
341
|
|
|
292
342
|
export function toServerDeltaProposalRequest(req: DeltaProposalRequest): ServerDeltaProposalRequest {
|
|
@@ -300,6 +350,12 @@ export function toServerDeltaProposalRequest(req: DeltaProposalRequest): ServerD
|
|
|
300
350
|
signature: toServerSignature(s.signature),
|
|
301
351
|
})),
|
|
302
352
|
metadata: req.deltaPayload.metadata ? toServerProposalMetadata(req.deltaPayload.metadata) : undefined,
|
|
353
|
+
...(req.deltaPayload.transactionRequest
|
|
354
|
+
? { transaction_request: req.deltaPayload.transactionRequest }
|
|
355
|
+
: {}),
|
|
356
|
+
...(req.deltaPayload.baseCommitment !== undefined
|
|
357
|
+
? { base_commitment: req.deltaPayload.baseCommitment }
|
|
358
|
+
: {}),
|
|
303
359
|
},
|
|
304
360
|
};
|
|
305
361
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Requesting and observing Guardian execution must need no Miden capability, so this package
|
|
8
|
+
* stays dependency-free and never reaches for the Miden SDK. A caller brings its own signer.
|
|
9
|
+
*/
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
describe('the base client has no Miden capability', () => {
|
|
13
|
+
it('declares no runtime dependencies', () => {
|
|
14
|
+
const manifest = JSON.parse(readFileSync(join(here, '../package.json'), 'utf8'));
|
|
15
|
+
expect(manifest.dependencies ?? {}).toEqual({});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('imports nothing from the Miden SDK', () => {
|
|
19
|
+
const sources = readdirSync(here).filter((name) => name.endsWith('.ts') && !name.endsWith('.test.ts'));
|
|
20
|
+
expect(sources.length).toBeGreaterThan(0);
|
|
21
|
+
for (const file of sources) {
|
|
22
|
+
expect(readFileSync(join(here, file), 'utf8'), file).not.toMatch(/from\s+'@miden-sdk\//);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
package/src/error-codes.test.ts
CHANGED
|
@@ -54,7 +54,20 @@ describe('drift guard against GuardianError::code()', () => {
|
|
|
54
54
|
const nextFn = errorRs.indexOf('pub fn', codeFnStart + 1);
|
|
55
55
|
const codeFn = errorRs.slice(codeFnStart, nextFn === -1 ? undefined : nextFn);
|
|
56
56
|
|
|
57
|
-
const
|
|
57
|
+
const executionRs = readFileSync(
|
|
58
|
+
join(here, '../../../crates/shared/src/execution.rs'),
|
|
59
|
+
'utf8'
|
|
60
|
+
);
|
|
61
|
+
const refusalCodes = new Map(
|
|
62
|
+
[...executionRs.matchAll(/pub const ([A-Z_]+): &str =\s*"([A-Z_]+)"/g)].map((m) => [m[1], m[2]])
|
|
63
|
+
);
|
|
64
|
+
const literalCodes = [...codeFn.matchAll(/"([A-Za-z_]+)"/g)].map((m) => m[1]);
|
|
65
|
+
const constantCodes = [...codeFn.matchAll(/refusal_codes::([A-Z_]+)/g)].map((m) => {
|
|
66
|
+
const wire = refusalCodes.get(m[1]);
|
|
67
|
+
expect(wire, `refusal_codes::${m[1]} is defined in guardian-shared`).toBeDefined();
|
|
68
|
+
return wire as string;
|
|
69
|
+
});
|
|
70
|
+
const serverWireCodes = [...literalCodes, ...constantCodes];
|
|
58
71
|
expect(serverWireCodes.length).toBeGreaterThan(0);
|
|
59
72
|
|
|
60
73
|
const normalizedServerCodes = new Set(
|
package/src/error-codes.ts
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
* Typed vocabulary of Guardian's stable, machine-readable error codes
|
|
3
3
|
* (issue #318). Mirrors `GuardianError::code()` in
|
|
4
4
|
* `crates/server/src/error.rs` — a drift-guard test asserts the two stay in
|
|
5
|
-
* sync. The
|
|
6
|
-
*
|
|
7
|
-
* `GUARDIAN_INSUFFICIENT_OPERATOR_PERMISSION`, `GUARDIAN_CANDIDATE_LANDED`)
|
|
8
|
-
* are normalized to snake_case here so the union has one consistent shape; use
|
|
5
|
+
* sync. The codes the server emits in SCREAMING_SNAKE wire form (see
|
|
6
|
+
* `WIRE_ALIASES`) are normalized to snake_case here so the union has one consistent shape; use
|
|
9
7
|
* {@link normalizeGuardianErrorCode} at the wire boundary.
|
|
10
8
|
*/
|
|
11
9
|
export const GUARDIAN_ERROR_CODES = [
|
|
@@ -14,6 +12,7 @@ export const GUARDIAN_ERROR_CODES = [
|
|
|
14
12
|
'account_not_found',
|
|
15
13
|
'account_paused',
|
|
16
14
|
'account_released',
|
|
15
|
+
'account_request_capacity_exceeded',
|
|
17
16
|
'authentication_failed',
|
|
18
17
|
'authentication_replay',
|
|
19
18
|
'authorization_failed',
|
|
@@ -24,6 +23,9 @@ export const GUARDIAN_ERROR_CODES = [
|
|
|
24
23
|
'conflict_pending_proposal',
|
|
25
24
|
'data_unavailable',
|
|
26
25
|
'delta_not_found',
|
|
26
|
+
'execution_busy',
|
|
27
|
+
'execution_conflict',
|
|
28
|
+
'execution_not_found',
|
|
27
29
|
'insufficient_operator_permission',
|
|
28
30
|
'insufficient_signatures',
|
|
29
31
|
'invalid_account_id',
|
|
@@ -40,7 +42,12 @@ export const GUARDIAN_ERROR_CODES = [
|
|
|
40
42
|
'network_error',
|
|
41
43
|
'pending_proposals_limit',
|
|
42
44
|
'proposal_already_signed',
|
|
45
|
+
'proposal_executes_locally',
|
|
46
|
+
'proposal_missing_transaction_request',
|
|
43
47
|
'proposal_not_found',
|
|
48
|
+
'proposal_not_ready',
|
|
49
|
+
'proposal_request_too_large',
|
|
50
|
+
'proving_unavailable',
|
|
44
51
|
'rate_limit_exceeded',
|
|
45
52
|
'rpc_unavailable',
|
|
46
53
|
'rpc_validation_failed',
|
|
@@ -50,8 +57,11 @@ export const GUARDIAN_ERROR_CODES = [
|
|
|
50
57
|
'signer_not_authorized',
|
|
51
58
|
'signing_error',
|
|
52
59
|
'state_not_found',
|
|
60
|
+
'state_not_on_chain',
|
|
53
61
|
'storage_error',
|
|
62
|
+
'timestamp_out_of_window',
|
|
54
63
|
'unsupported_evm_chain',
|
|
64
|
+
'unsupported_auth_version',
|
|
55
65
|
'unsupported_for_network',
|
|
56
66
|
'wallet_signature_required',
|
|
57
67
|
] as const;
|
|
@@ -75,6 +85,15 @@ const WIRE_ALIASES: Readonly<Record<string, GuardianErrorCode>> = {
|
|
|
75
85
|
GUARDIAN_ACCOUNT_RELEASED: 'account_released',
|
|
76
86
|
GUARDIAN_INSUFFICIENT_OPERATOR_PERMISSION: 'insufficient_operator_permission',
|
|
77
87
|
GUARDIAN_CANDIDATE_LANDED: 'candidate_landed',
|
|
88
|
+
GUARDIAN_PROVING_UNAVAILABLE: 'proving_unavailable',
|
|
89
|
+
GUARDIAN_PROPOSAL_MISSING_TRANSACTION_REQUEST: 'proposal_missing_transaction_request',
|
|
90
|
+
GUARDIAN_PROPOSAL_EXECUTES_LOCALLY: 'proposal_executes_locally',
|
|
91
|
+
GUARDIAN_PROPOSAL_NOT_READY: 'proposal_not_ready',
|
|
92
|
+
GUARDIAN_EXECUTION_CONFLICT: 'execution_conflict',
|
|
93
|
+
GUARDIAN_EXECUTION_BUSY: 'execution_busy',
|
|
94
|
+
GUARDIAN_EXECUTION_NOT_FOUND: 'execution_not_found',
|
|
95
|
+
GUARDIAN_PROPOSAL_REQUEST_TOO_LARGE: 'proposal_request_too_large',
|
|
96
|
+
GUARDIAN_ACCOUNT_REQUEST_CAPACITY_EXCEEDED: 'account_request_capacity_exceeded',
|
|
78
97
|
};
|
|
79
98
|
|
|
80
99
|
/** Type guard narrowing an arbitrary string to {@link GuardianErrorCode}. */
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import {
|
|
6
|
+
EXECUTION_FAILURE_CODES,
|
|
7
|
+
EXECUTION_STATES,
|
|
8
|
+
EXECUTION_UNAVAILABLE_REASONS,
|
|
9
|
+
EXPIRATION_BOUNDS,
|
|
10
|
+
FOREIGN_ACCOUNT_UNAVAILABLE_REASONS,
|
|
11
|
+
REQUEST_INVALID_REASONS,
|
|
12
|
+
fromServerExecution,
|
|
13
|
+
fromServerExecutionCapability,
|
|
14
|
+
isTerminalExecutionState,
|
|
15
|
+
type ServerProposalExecution,
|
|
16
|
+
} from './execution.js';
|
|
17
|
+
|
|
18
|
+
const executionRs = readFileSync(
|
|
19
|
+
join(dirname(fileURLToPath(import.meta.url)), '../../../crates/shared/src/execution.rs'),
|
|
20
|
+
'utf8'
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
function snake(variant: string): string {
|
|
24
|
+
return variant.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function rustVariants(enumName: string): string[] {
|
|
28
|
+
const start = executionRs.indexOf(`pub enum ${enumName} {`);
|
|
29
|
+
expect(start, `${enumName} is defined in guardian-shared`).toBeGreaterThan(-1);
|
|
30
|
+
const body = executionRs.slice(start, executionRs.indexOf('}', start));
|
|
31
|
+
return [...body.matchAll(/^\s+([A-Z][A-Za-z]+)[,(]/gm)].map((m) => m[1]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function envelope(overrides: Partial<ServerProposalExecution>): ServerProposalExecution {
|
|
35
|
+
return {
|
|
36
|
+
account_id: '0xacc',
|
|
37
|
+
proposal_id: '0xprop',
|
|
38
|
+
state: 'pending',
|
|
39
|
+
newly_accepted: false,
|
|
40
|
+
proposal_exists: true,
|
|
41
|
+
ignored_signatures: 0,
|
|
42
|
+
updated_at: '2026-09-30T12:00:00Z',
|
|
43
|
+
...overrides,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
describe('drift guard against guardian_shared::execution', () => {
|
|
48
|
+
it('the states and meta value sets match the Rust enums', () => {
|
|
49
|
+
expect([...EXECUTION_STATES]).toEqual(rustVariants('ExecutionState').map(snake));
|
|
50
|
+
expect([...REQUEST_INVALID_REASONS]).toEqual(rustVariants('RequestInvalidReason').map(snake));
|
|
51
|
+
expect([...EXPIRATION_BOUNDS]).toEqual(rustVariants('ExpirationBound').map(snake));
|
|
52
|
+
expect([...FOREIGN_ACCOUNT_UNAVAILABLE_REASONS]).toEqual(
|
|
53
|
+
rustVariants('ForeignAccountUnavailableReason').map(snake)
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('the execution-unavailable reasons match the server enum', () => {
|
|
58
|
+
const configRs = readFileSync(
|
|
59
|
+
join(dirname(fileURLToPath(import.meta.url)), '../../../crates/server/src/config/execution.rs'),
|
|
60
|
+
'utf8'
|
|
61
|
+
);
|
|
62
|
+
const body = configRs.slice(configRs.indexOf('pub enum ExecutionUnavailable {'));
|
|
63
|
+
const variants = [...body.slice(0, body.indexOf('\n}')).matchAll(/^\s{4}([A-Z][A-Za-z]+),$/gm)].map((m) => m[1]);
|
|
64
|
+
expect([...EXECUTION_UNAVAILABLE_REASONS]).toEqual(variants.map(snake));
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('the failure codes match ExecutionFailureCode::as_str', () => {
|
|
68
|
+
const start = executionRs.indexOf('pub fn as_str(&self) -> &\'static str {', executionRs.indexOf('impl ExecutionFailureCode'));
|
|
69
|
+
const body = executionRs.slice(start, executionRs.indexOf('pub fn meta', start));
|
|
70
|
+
const rustCodes = [...body.matchAll(/"(GUARDIAN_EXECUTION_[A-Z_]+)"/g)].map((m) => m[1]);
|
|
71
|
+
expect([...EXECUTION_FAILURE_CODES].sort()).toEqual(rustCodes.sort());
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('never carries the codes the design withdrew', () => {
|
|
75
|
+
for (const withdrawn of ['ANCHOR_EXPIRED', 'NO_FINITE_EXPIRATION', 'FOREIGN_INPUTS_UNSUPPORTED']) {
|
|
76
|
+
expect(EXECUTION_FAILURE_CODES.some((code) => code.endsWith(withdrawn))).toBe(false);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('fromServerExecution', () => {
|
|
82
|
+
it('decodes a failure with its typed meta', () => {
|
|
83
|
+
const execution = fromServerExecution(
|
|
84
|
+
envelope({
|
|
85
|
+
state: 'failed',
|
|
86
|
+
proposal_exists: false,
|
|
87
|
+
error: {
|
|
88
|
+
code: 'GUARDIAN_EXECUTION_EXPIRATION_REACHED',
|
|
89
|
+
message: 'expired',
|
|
90
|
+
meta: { bound: 'transaction' },
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
expect(execution.error).toEqual({
|
|
95
|
+
code: 'GUARDIAN_EXECUTION_EXPIRATION_REACHED',
|
|
96
|
+
message: 'expired',
|
|
97
|
+
bound: 'transaction',
|
|
98
|
+
});
|
|
99
|
+
expect(execution.proposalExists).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('refuses an unknown state, an unknown reason and a failure without its error', () => {
|
|
103
|
+
expect(() => fromServerExecution(envelope({ state: 'queued' }))).toThrow();
|
|
104
|
+
expect(() =>
|
|
105
|
+
fromServerExecution(
|
|
106
|
+
envelope({
|
|
107
|
+
state: 'failed',
|
|
108
|
+
error: { code: 'GUARDIAN_EXECUTION_REQUEST_INVALID', message: 'x', meta: { reason: 'other' } },
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
).toThrow();
|
|
112
|
+
expect(() => fromServerExecution(envelope({ state: 'failed' }))).toThrow();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('maps nothing in flight and an absent nonce to null', () => {
|
|
116
|
+
expect(fromServerExecution(envelope({})).deltaNonce).toBeNull();
|
|
117
|
+
expect(fromServerExecution(envelope({ delta_nonce: 4 })).deltaNonce).toBe(4);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('isTerminalExecutionState', () => {
|
|
122
|
+
it('matches ExecutionState::is_terminal', () => {
|
|
123
|
+
expect(EXECUTION_STATES.filter(isTerminalExecutionState)).toEqual(['committed', 'failed']);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('fromServerExecutionCapability', () => {
|
|
128
|
+
it('decodes both shapes', () => {
|
|
129
|
+
expect(fromServerExecutionCapability({ enabled: true })).toEqual({ enabled: true });
|
|
130
|
+
expect(fromServerExecutionCapability({ enabled: false, reason: 'disabled' })).toEqual({
|
|
131
|
+
enabled: false,
|
|
132
|
+
reason: 'disabled',
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('refuses an unknown reason, a missing field and a reason on an enabled capability', () => {
|
|
137
|
+
expect(() => fromServerExecutionCapability({ enabled: false, reason: 'gone_fishing' })).toThrow(
|
|
138
|
+
/unknown execution unavailable reason/
|
|
139
|
+
);
|
|
140
|
+
expect(() => fromServerExecutionCapability({ enabled: false })).toThrow(/unknown execution unavailable reason/);
|
|
141
|
+
expect(() => fromServerExecutionCapability({ enabled: 'yes' })).toThrow(/boolean enabled/);
|
|
142
|
+
expect(() => fromServerExecutionCapability('yes' as never)).toThrow(/malformed execution capability/);
|
|
143
|
+
expect(() => fromServerExecutionCapability({ enabled: true, reason: 'disabled' })).toThrow(/with a reason/);
|
|
144
|
+
});
|
|
145
|
+
});
|