@sig-net/midnight 0.24.0-rc.1 → 0.24.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +53 -25
  2. package/dist/abi-serde.d.ts +198 -57
  3. package/dist/abi-serde.d.ts.map +1 -1
  4. package/dist/abi-serde.js +478 -367
  5. package/dist/abi-serde.js.map +1 -1
  6. package/dist/compact-descriptors.d.ts +25 -8
  7. package/dist/compact-descriptors.d.ts.map +1 -1
  8. package/dist/compact-descriptors.js +42 -32
  9. package/dist/compact-descriptors.js.map +1 -1
  10. package/dist/constants.d.ts +3 -22
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +3 -25
  13. package/dist/constants.js.map +1 -1
  14. package/dist/ecdsa-attestation.d.ts +44 -16
  15. package/dist/ecdsa-attestation.d.ts.map +1 -1
  16. package/dist/ecdsa-attestation.js +49 -17
  17. package/dist/ecdsa-attestation.js.map +1 -1
  18. package/dist/index.d.ts +6 -6
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +5 -5
  21. package/dist/index.js.map +1 -1
  22. package/dist/managed/compiler/contract-info.json +1759 -34
  23. package/dist/managed/compiler/contract-manifest.json +8 -8
  24. package/dist/managed/contract/index.d.ts +416 -7
  25. package/dist/managed/contract/index.js +1248 -193
  26. package/dist/managed/contract/index.js.map +1 -1
  27. package/dist/mpc-output-cache.d.ts +5 -29
  28. package/dist/mpc-output-cache.d.ts.map +1 -1
  29. package/dist/mpc-output-cache.js +8 -42
  30. package/dist/mpc-output-cache.js.map +1 -1
  31. package/dist/signature-requests-state-reader.js +3 -3
  32. package/dist/signature-requests-state-reader.js.map +1 -1
  33. package/dist/signet-contract-events.d.ts +52 -12
  34. package/dist/signet-contract-events.d.ts.map +1 -1
  35. package/dist/signet-contract-events.js +89 -34
  36. package/dist/signet-contract-events.js.map +1 -1
  37. package/dist/signet-evtype2tx-record-decoding.d.ts.map +1 -1
  38. package/dist/signet-evtype2tx-record-decoding.js +6 -5
  39. package/dist/signet-evtype2tx-record-decoding.js.map +1 -1
  40. package/dist/signet-evtype2tx-requests.d.ts +17 -12
  41. package/dist/signet-evtype2tx-requests.d.ts.map +1 -1
  42. package/dist/signet-evtype2tx-requests.js +92 -16
  43. package/dist/signet-evtype2tx-requests.js.map +1 -1
  44. package/dist/signet-request-id.d.ts +5 -2
  45. package/dist/signet-request-id.d.ts.map +1 -1
  46. package/dist/signet-request-id.js +27 -9
  47. package/dist/signet-request-id.js.map +1 -1
  48. package/dist/signet-request-response-reader.d.ts +10 -4
  49. package/dist/signet-request-response-reader.d.ts.map +1 -1
  50. package/dist/signet-request-response-reader.js +10 -12
  51. package/dist/signet-request-response-reader.js.map +1 -1
  52. package/dist/signet-requests.d.ts +48 -17
  53. package/dist/signet-requests.d.ts.map +1 -1
  54. package/dist/signet-requests.js +18 -6
  55. package/dist/signet-requests.js.map +1 -1
  56. package/dist/testing.d.ts +1 -1
  57. package/dist/testing.d.ts.map +1 -1
  58. package/dist/testing.js +3 -8
  59. package/dist/testing.js.map +1 -1
  60. package/package.json +2 -2
  61. package/src/Signet.compact +299 -100
  62. package/src/circuits.compact +88 -14
package/README.md CHANGED
@@ -35,7 +35,7 @@ The protocol and integration documentation lives in the [sig-net/midnight-integr
35
35
 
36
36
  - [Sign Bidirectional Flow](https://github.com/sig-net/midnight-integration/blob/main/README.md#sign-bidirectional-protocol-flow): the 5-step protocol this package speaks, with diagram, failure handling and output recovery.
37
37
  - [Derived keys](https://github.com/sig-net/midnight-integration/blob/main/README.md#derived-keys): the request signing key and the response key, and how the MPC derives them.
38
- - [Handling Failure](https://github.com/sig-net/midnight-integration/blob/main/README.md#handling-failure): the fixed 5-byte failure payload the MPC attests for a failed foreign transaction, how a contract tells it apart from a success, and which respond schemas cannot.
38
+ - [Handling Failure](https://github.com/sig-net/midnight-integration/blob/main/README.md#handling-failure): the empty output and failure output kind the MPC attests for a failed foreign transaction, and how a contract routes on the verified kind.
39
39
  - [Integrator Guide](https://github.com/sig-net/midnight-integration/blob/main/README.md#integrator-guide): the once-off setup and the per-request runtime steps, built on this package's exports.
40
40
  - [EVM Type 2 transactions and ABI calldata words](https://github.com/sig-net/midnight-integration/blob/main/README.md#evm-type-2-transactions-and-abi-calldata-words): building calldata words in-circuit and deserialising respond payloads.
41
41
 
@@ -51,11 +51,12 @@ What your contract imports with `import "@sig-net/midnight/src/Signet"`:
51
51
 
52
52
  | Task | Exports |
53
53
  |---|---|
54
- | Declare the protocol ledger state (setup step 3) | `SignBidirectionalEventMap` (the request map the MPC reads) and `SignetSigner` (the Signet singleton's cross-contract-call interface, pinned at deploy). |
55
- | Build and store a signature request (runtime step 1) | `constructSignBidirectionalEvent` and `calculateRequestId`, over the request structs `EvmType2TxParams`, `EvmCalldata` and `EvmAccessListEntry`. |
54
+ | Declare the protocol ledger state (setup step 3) | `SignBidirectionalEventMapV1` (the request map the MPC reads) and `SignetSigner` (the Signet singleton's cross-contract-call interface, pinned at deploy). |
55
+ | Build and store a signature request (runtime step 1) | `constructSignBidirectionalEventV1` and `calculateEvmType2RequestIdV1`, over the request structs `EvmType2TxParams`, `EvmCalldata` and `EvmAccessListEntry`. The id hashes `calculateEvmType2TxParamsDigestV1`, a digest over the transaction's used entries only, so it ignores your struct's capacities and unused slots. |
56
56
  | Notify the MPC of the request (runtime step 1) | `constructSignBidirectionalEventNotificationV1`: packs your contract's address and the request map's ledger-tree path. |
57
+ | Narrow an attested `uint256` in-circuit | `checkedTruncationU128`: the `Bytes<32>` the MPC attests (little-endian) to a `Uint<128>`, aborting unless the high 16 bytes are zero (see [Output Recovery and Serialisation](https://github.com/sig-net/midnight-integration/blob/main/README.md#output-recovery-and-serialisation)). |
57
58
  | Build and read calldata words in-circuit | The builders `evmAddressAbiWord`, `numericAbiWord` and `boolAbiWord`, and the readers `abiWordToUint128` and `abiWordToBool` (see [EVM Type 2 transactions and ABI calldata words](https://github.com/sig-net/midnight-integration/blob/main/README.md#evm-type-2-transactions-and-abi-calldata-words)). |
58
- | Verify the execution attestation (runtime step 5) | `verifyRespondBidirectionalEvent`: recomputes the attestation digest from the output bytes and checks the MPC's signature against your pinned response key. |
59
+ | Verify the execution attestation (runtime step 5) | `verifyRespondBidirectionalEventV1`: recomputes the attestation digest from the output bytes and the posted request id, output kind and block height, and checks the MPC's signature against your pinned response key. |
59
60
 
60
61
  ### TypeScript library
61
62
 
@@ -69,12 +70,16 @@ What clients import from `@sig-net/midnight`:
69
70
  | Derive the response key your deploy pins | `deriveMidnightResponseKey`: the key `initialise` stores (setup step 4), derived from your contract's address. |
70
71
  | Look up published counterparty values | `MidnightNetwork`, `getMpcRootPublicKey` and `getSignetContractAddress`: the fixed per-network values (see the notes in [Runtime](https://github.com/sig-net/midnight-integration/blob/main/README.md#runtime)). |
71
72
  | Accept an MPC public key in any published spelling | `parseSecp256k1PublicKey` (to a Compact `Secp256k1Point`) and `normaliseSecp256k1PublicKey` (to the canonical `0x04…` uncompressed SEC1 hex): both take SEC1 hex, compressed or uncompressed with an optional `0x`, and NEAR's `secp256k1:<base58>`. |
72
- | Read a text field of a request record | `asciiUnpadded`: the inverse of `asciiPadded`, for the zero-padded text fields (`caip2Id`, the two schemas). |
73
+ | Read a text field of a request record | `asciiUnpadded`: the inverse of `asciiPadded`, for the zero-padded text fields (`executionDest`, `outputDeserializationSchema`). |
73
74
  | Compute a request id off chain | `calculateRequestId`: the TS twin of the on-chain circuit, plus `requestIdHex` and `parseRequestIdHex` for the hex form. |
74
75
  | Compose expected calldata words off chain (UIs, expected-record builders, tests) | The builders `numericAbiWord`, `evmAddressAbiWord` and `boolAbiWord`, and the readers `abiWordToUint128` and `abiWordToBool`: TS twins of the circuits under identical names. |
75
- | Convert a foreign execution output into respond bytes | `deserializeEvmOutput` (raw EVM return data to named values) and `serializeRespondOutput` (named values to the packed respond payload the MPC attests): together they rebuild the `serializedOutput` of steps 4 and 5. |
76
- | Recognise a failed remote execution | `MPC_FAILURE_OUTPUT` and `isMpcFailureOutput`: the MPC's fixed 5-byte failure payload for reverted or replaced transactions (see [Handling Failure](https://github.com/sig-net/midnight-integration/blob/main/README.md#handling-failure)). |
77
- | Read the attested output from the MPC's output cache | `MpcOutputCacheReader` (`fetchAttestedOutput` returns the block height and the output; `encodeAttestedOutput` / `decodeAttestedOutput` are the object format): one reader per network and Signet singleton pair, over the public bucket an MPC configured with output storage writes each request's exact attested bytes to before posting, defaulting to the bucket `getMpcOutputCacheUrl` publishes for the network. `fetchSerializedOutput` yields the bytes step 5 verifies, `undefined` while the object is not written yet. |
76
+ | Digest a transaction decomposition off chain | `calculateEvmType2TxParamsDigest`: the TS twin of the circuit, what `calculateRequestId` hashes in place of the parameters. |
77
+ | Rebuild the respond bytes the MPC attests for an executed EVM transaction | `executedEvmRespondOutput`: the request's `outputDeserializationSchema`, whether the transaction was a contract call (`isEvmContractCall` over its calldata) and its traced return data (`EvmTraceOutput`, read off a `debug_traceTransaction` callTracer frame by `evmTraceOutputFromCallFrame`) give the exact `serializedOutput` of steps 4 and 5, empty for an empty output schema. |
78
+ | Convert a foreign execution output into respond bytes | `deserializeEvmOutput` (raw EVM return data to named values) and `serializeRespondOutput` (named values to the attested Borsh bytes): the two conversions `executedEvmRespondOutput` runs on a contract call's return data. |
79
+ | Know what an output schema attests to | `deriveRespondSchema` (the Borsh struct the MPC serialises with), `respondOutputWidth` (the `Bytes<N>` width a settle circuit declares) and `unsupportedEvmOutputFields` (the fields that make the MPC drop a request, without throwing). |
80
+ | Recognise a failed remote execution | `OutputKind` on the verified `RespondBidirectionalEvent`: `failed` or `unviable` beside an empty output (see [Handling Failure](https://github.com/sig-net/midnight-integration/blob/main/README.md#handling-failure)). |
81
+ | Read the attested output bytes from the MPC's output cache | `MpcOutputCacheReader`: one reader per network and Signet singleton pair, over the public bucket an MPC configured with output storage writes each request's exact attested bytes to before posting, defaulting to the bucket `getMpcOutputCacheUrl` publishes for the network. `fetchSerializedOutput` yields the bytes step 5 verifies, `undefined` while the object is not written yet. |
82
+ | Hand a verified attestation to your verify circuit (runtime step 5) | `respondBidirectionalEventToCircuitInput`: flips the wire event's big-endian `bigR.x` and `s` into the little-endian record `verifyRespondBidirectionalEventV1` reads. |
78
83
  | Verify attestations without the reader | `verifyRespondBidirectionalSignature`: the check the reader runs internally, exposed for custom pipelines. |
79
84
  | Mint attestations in your contract's unit tests | The `@sig-net/midnight/testing` entry point, see [Testing entry point](#testing-entry-point). |
80
85
  | Discover requests MPC-side (responders, background workers) | The discovery primitives: decode the signet contract's emitted notification events with `decodeSignetEventNamed(event, SignetEventName.SignBidirectionalEvent)` (or every kind at once with `decodeSignetEvent`, which throws on an undecodable payload anyone can emit, or its non-throwing sibling `tryDecodeSignetEvent`), then resolve each pointer against the named caller's own request map with `lookupSignetRequestAt` (the authenticated read). The polling loop belongs to the responder. |
@@ -96,23 +101,16 @@ stack and no MPC:
96
101
 
97
102
  ```ts
98
103
  import { verifyRespondBidirectionalSignature } from "@sig-net/midnight"; // runtime
99
- import {
100
- calculateSignetAttestationDigest,
101
- ecdsaSignatureToMpcSignature,
102
- secp256k1PublicKeyOf,
103
- signAttestationDigest,
104
- } from "@sig-net/midnight/testing"; // tests only
105
-
106
- // A real RespondBidirectionalEvent for (requestId, output), signed by secretKey.
107
- // It verifies, in-circuit and off chain, against secp256k1PublicKeyOf(secretKey).
108
- const event = {
109
- signature: ecdsaSignatureToMpcSignature(
110
- signAttestationDigest(
111
- calculateSignetAttestationDigest(requestId, serializedOutput),
112
- secretKey,
113
- ),
114
- ),
115
- };
104
+ import { attestRespondBidirectional, secp256k1PublicKeyOf } from "@sig-net/midnight/testing"; // tests only
105
+
106
+ // A real RespondBidirectionalEvent for (requestId, blockHeight, outputKind,
107
+ // serializedOutput), signed by secretKey: the request id, block height, kind,
108
+ // output width, attestation digest and signature the MPC would post. It
109
+ // verifies, in-circuit and off chain, against secp256k1PublicKeyOf(secretKey).
110
+ const event = attestRespondBidirectional(
111
+ { requestId, blockHeight, outputKind, serializedOutput },
112
+ secretKey,
113
+ );
116
114
  ```
117
115
 
118
116
  ## Related packages
@@ -121,3 +119,33 @@ const event = {
121
119
  - [`@sig-net/midnight-contract-deploy`](https://www.npmjs.com/package/@sig-net/midnight-contract-deploy): deploy tooling for that contract plus generic Midnight deploy/wallet plumbing.
122
120
 
123
121
  Developed in [sig-net/midnight-integration](https://github.com/sig-net/midnight-integration).
122
+
123
+ ## Protocol hash domains
124
+
125
+ `HashDomain` is the shared append-only enum exported by the Compact module
126
+ and the TypeScript SDK. Its indices are `requestId = 0`,
127
+ `attestationDigest = 1`, `evmType2TxHeader = 2`, `evmType2TxWord = 3`,
128
+ `evmType2TxAccessEntry = 4` and `evmType2TxStorageKey = 5`. Each protocol
129
+ hash input starts with its domain tag. Off-chain recomputation must use
130
+ the same tags and field order as the circuits.
131
+
132
+ `constructSignBidirectionalEventV1` rejects a `signatureDest` other than
133
+ `MPCDestination.unused` and any non-zero byte in `params`. Both fields
134
+ are reserved and remain outside the request id.
135
+
136
+ ## EVM output and Borsh responses
137
+
138
+ `outputDeserializationSchema` is an ethers-compatible ABI field array whose field names are unique Solidity identifiers (`[A-Za-z_$][A-Za-z0-9_$]*`, never `__proto__`) and whose types are ABI type strings `ethers.ParamType` accepts, matched literally against the table below (`uint256`, never `uint`). Its on-chain bytes are canonical: `canonicalSchemaText(fields)` (`JSON.stringify` of `{name, type}` per field in order, no whitespace) followed by NUL padding only, with `[]` or an all-NUL field for the empty schema. Every reader in this module refuses text or bytes in any other form. It is the only schema a request carries: `respondSerializationSchema` is reserved, pinned to `Bytes<0>` by `constructSignBidirectionalEventV1`. The MPC derives the Borsh schema of the attested bytes from the output schema, one struct member per field in schema order, under a closed mapping:
139
+
140
+ | ABI type | Borsh | Compact | Width |
141
+ | --- | --- | --- | --- |
142
+ | `bool` | `bool` | `Boolean` | 1 |
143
+ | `uint256` | `[u8; 32]`, little-endian | `Bytes<32>`, narrowed in-circuit with `checkedTruncationU128` | 32 |
144
+ | `address` | `[u8; 20]` | `Bytes<20>` | 20 |
145
+ | `bytes1` to `bytes32` | `[u8; N]` | `Bytes<N>` | N |
146
+
147
+ Every other ABI type is unsupported. `unsupportedEvmOutputFields` names the offending fields without throwing (the MPC drops such a request), and `deriveRespondSchema`, `respondOutputWidth` and `serializeRespondOutput` throw on them. For example, `[{"name":"success","type":"bool"},{"name":"amount","type":"uint256"}]` derives `{"struct":{"success":"bool","amount":{"array":{"type":"u8","len":32}}}}`, 33 bytes.
148
+
149
+ `serializeRespondOutput` converts the decoded values (ethers' bigint, boolean and hex forms, plus plain numbers and decimal strings for `uint256`) into that struct and calls `@sig-net/midnight-serde`. A `uint256` is carried whole as 32 little-endian bytes, the byte order of every Borsh and Compact integer and the ABI wire word reversed: nothing is narrowed off chain, and a value outside `0 <= v < 2^256` is rejected. `executedEvmRespondOutput` requires the output schema and the return data to agree: an empty schema with no return data (a plain transfer, or a call that returned nothing) attests an EMPTY output, a non-empty schema with return data runs the two conversions, and either mismatch throws. The return data must be canonical ABI (whole words, a `bool` word of 0 or 1, zero high bytes on an `address`, zero padding after a `bytesN`), checked before the lenient ABI decode. Words past the declared fields are ignored. The schema's types are checked on every path, a plain transfer included.
150
+
151
+ Output schema JSON accepts text or UTF-8 bytes and trims NUL padding in either form. Blank text is the empty schema, and malformed JSON fails with schema context.
@@ -1,46 +1,23 @@
1
+ import { type Schema } from "@sig-net/midnight-serde";
1
2
  import { ethers } from "ethers";
2
- /** Fixed-width schema types: the byte size follows entirely from the type. */
3
- export type AbiFixedType = "bool" | "address" | "field" | `uint${number}` | `bytes${number}`;
4
- /** A fixed-width schema field: its byte size follows entirely from its type. */
5
- export interface AbiFixedField {
6
- name: string;
7
- type: AbiFixedType;
8
- }
9
- /** A dynamic string/bytes field. `maxBytes` is the fixed Compact buffer capacity. */
10
- export interface AbiDynamicField {
11
- name: string;
12
- type: "string" | "bytes";
13
- maxBytes: number;
14
- }
15
- /** A dynamic array field. `maxItems` is the fixed Compact vector capacity. */
16
- export interface AbiArrayField {
17
- name: string;
18
- type: `${AbiFixedType}[]`;
19
- maxItems: number;
20
- }
21
- /** One respond-schema field: fixed-width, dynamic string/bytes, or array. */
22
- export type AbiSchemaField = AbiFixedField | AbiDynamicField | AbiArrayField;
23
- /** An ABI-style schema exactly as carried on chain (JSON array of fields). */
24
- export type AbiSchema = AbiSchemaField[];
25
- /** Any form a respond schema arrives in: parsed, JSON text, or NUL-padded raw bytes. */
26
- export type AbiSchemaInput = AbiSchema | string | Uint8Array;
27
3
  /**
28
- * A decode-side schema field: `type` is ANY type string the ABI library
29
- * accepts. The restricted {@link AbiSchemaField} vocabulary is a respond-side
30
- * concern only, and is assignable to this shape.
4
+ * One field of an outputDeserializationSchema: `type` is an ABI type string
5
+ * `ethers.ParamType` accepts. {@link deserializeEvmOutput} decodes every
6
+ * such type, while the respond side ({@link deriveRespondSchema}) accepts
7
+ * only the {@link EvmOutputTypeKind} subset, matched on the raw string.
31
8
  */
32
9
  export interface EvmSchemaField {
33
10
  name: string;
34
11
  type: string;
35
12
  }
36
- /** Any form a decode schema arrives in: parsed, JSON text, or NUL-padded raw bytes. */
13
+ /** Any form an outputDeserializationSchema arrives in: parsed, JSON text, or NUL-padded raw bytes. */
37
14
  export type EvmSchemaInput = readonly EvmSchemaField[] | string | Uint8Array;
38
15
  /**
39
16
  * Decoded output values, keyed by schema field name. Numerics are bigint,
40
17
  * bools boolean, address/bytesN/bytes/string are the forms ethers produces
41
18
  * (hex or text strings) or Uint8Array, arrays are plain arrays.
42
- * `serializeRespondOutput` accepts all of these (plus plain numbers and
43
- * numeric strings, the forms indexer JSON typically yields).
19
+ * {@link serializeRespondOutput} additionally accepts plain numbers and
20
+ * numeric strings for `uint256`, the forms indexer JSON typically yields.
44
21
  */
45
22
  export type AbiDecodedValue = bigint | boolean | number | string | Uint8Array | AbiDecodedValue[];
46
23
  /** Decoded output values keyed by schema field name (see {@link AbiDecodedValue}). */
@@ -50,10 +27,10 @@ export type AbiDecodedOutput = Record<string, AbiDecodedValue>;
50
27
  * into named values, driven by the request's outputDeserializationSchema.
51
28
  * The decode-side counterpart of {@link serializeRespondOutput}. Type
52
29
  * validation is FULLY delegated to ethers: this function checks the schema's
53
- * shape only. An empty schema decodes to an empty object (a plain transfer
54
- * has no output), matching the MPC's empty-schema handling. Returns a plain
55
- * object (never an ethers `Result`), so it survives JSON round-trips and
56
- * structural comparison.
30
+ * shape only, so it decodes ABI types the respond side refuses. An empty
31
+ * schema decodes to an empty object. Returns a plain object (never an
32
+ * ethers `Result`), so it survives JSON round-trips and structural
33
+ * comparison.
57
34
  *
58
35
  * @param schema - The outputDeserializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
59
36
  * @param callResult - The ABI-encoded return data (hex string or bytes).
@@ -61,31 +38,195 @@ export type AbiDecodedOutput = Record<string, AbiDecodedValue>;
61
38
  */
62
39
  export declare function deserializeEvmOutput(schema: EvmSchemaInput, callResult: ethers.BytesLike): AbiDecodedOutput;
63
40
  /**
64
- * Ceiling on a respond schema's total packed byte width. Schemas are
65
- * requester-authored on-chain data, so unbounded maxBytes/maxItems would let
66
- * a hostile request demand giant allocations from the responder. A real
67
- * respond payload must fit its consumer contract's fixed `deserialize<T, N>`
68
- * width, orders of magnitude below this.
41
+ * The ABI output types the MPC attests, and what each maps to. The respond
42
+ * bytes are the Borsh serialisation of a struct with one member per output
43
+ * field, in schema order, typed by this mapping:
44
+ *
45
+ * - {@link EvmOutputTypeKind.Bool}: ABI `bool`, Borsh `bool`, Compact `Boolean` (1 byte).
46
+ * - {@link EvmOutputTypeKind.Uint256}: ABI `uint256`, Borsh `[u8; 32]`
47
+ * holding the value LITTLE-endian, the byte order of every Borsh and
48
+ * Compact integer, Compact `Bytes<32>` (32 bytes). A circuit that wants a
49
+ * number narrows it with `checkedTruncationU128`, which aborts above
50
+ * 2^128 - 1. The ABI wire word is big-endian: the MPC reverses it once,
51
+ * here, so no circuit has to.
52
+ * - {@link EvmOutputTypeKind.Address}: ABI `address`, Borsh `[u8; 20]`
53
+ * holding the address bytes, Compact `Bytes<20>` (20 bytes).
54
+ * - {@link EvmOutputTypeKind.FixedBytes}: ABI `bytes1` to `bytes32`, Borsh
55
+ * `[u8; N]`, Compact `Bytes<N>` (N bytes).
56
+ *
57
+ * Every other ABI type is unsupported: the MPC drops a request whose output
58
+ * schema names one, and {@link deriveRespondSchema} throws on it.
59
+ */
60
+ export declare enum EvmOutputTypeKind {
61
+ Bool = "bool",
62
+ Uint256 = "uint256",
63
+ Address = "address",
64
+ FixedBytes = "bytesN"
65
+ }
66
+ /**
67
+ * The fields of an outputDeserializationSchema whose ABI type is outside the
68
+ * supported subset ({@link EvmOutputTypeKind}). The check itself never
69
+ * throws on an unsupported type: an empty result means the MPC attests the
70
+ * request, a non-empty one means it drops it.
71
+ *
72
+ * @param schema - The outputDeserializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
73
+ * @returns The unsupported fields in schema order, empty when every field is supported.
74
+ * @throws {Error} If the schema is not an array of uniquely named fields (its shape, not its types).
75
+ */
76
+ export declare function unsupportedEvmOutputFields(schema: EvmSchemaInput): EvmSchemaField[];
77
+ /**
78
+ * The Borsh schema the respond bytes of an executed call are serialised
79
+ * with: a struct with one member per output field, in schema order, each
80
+ * typed by {@link EvmOutputTypeKind}. An empty output schema derives an
81
+ * empty struct, which serialises to zero bytes. Borsh writes struct members
82
+ * in the struct object's key order, which equals schema order because field
83
+ * names are Solidity identifiers (see {@link parseSchemaShape}).
84
+ *
85
+ * @param schema - The outputDeserializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
86
+ * @returns The derived Borsh struct schema.
87
+ * @throws {Error} If the schema is malformed or names an unsupported ABI type.
69
88
  */
70
- export declare const MAX_RESPOND_PACKED_BYTES = 65536;
89
+ export declare function deriveRespondSchema(schema: EvmSchemaInput): Schema;
71
90
  /**
72
- * Encode decoded output values into the respond payload, driven by the
73
- * request's respondSerializationSchema: the bytes a consumer contract reads
74
- * with `deserialize<T, N>` and the MPC attests. The respond-side counterpart
75
- * of {@link deserializeEvmOutput}.
91
+ * The byte width of the respond bytes an output schema derives: the sum of
92
+ * its fields' widths under {@link EvmOutputTypeKind}, what a settle circuit
93
+ * declares as its `Bytes<N>` output argument.
76
94
  *
77
- * The result is the PACKED value, unpadded and unbounded: its length follows
78
- * entirely from the schema, and padding to a fixed container width is the
79
- * caller's concern. Strict: values are range-checked, dynamic payloads must
80
- * fit their capacity with no silent truncation, and signed integer types are
81
- * rejected.
95
+ * @param schema - The outputDeserializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
96
+ * @returns The exact serialised width, 0 for an empty schema.
97
+ * @throws {Error} If the schema is malformed or names an unsupported ABI type.
98
+ */
99
+ export declare function respondOutputWidth(schema: EvmSchemaInput): number;
100
+ /**
101
+ * Serialise ABI-decoded output into the respond bytes the MPC attests: the
102
+ * Borsh encoding of {@link deriveRespondSchema}'s struct over the output's
103
+ * values. A `uint256` is carried whole as 32 little-endian bytes, so no
104
+ * value is narrowed off chain: a circuit that wants a number narrows the
105
+ * `Bytes<32>` with `checkedTruncationU128`.
106
+ *
107
+ * @param schema - The outputDeserializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
108
+ * @param output - The decoded values keyed by field name, as {@link deserializeEvmOutput} returns them.
109
+ * @returns The unpadded respond bytes, {@link respondOutputWidth} long.
110
+ * @throws {Error} If the schema is malformed or names an unsupported type, a
111
+ * field is missing from `output`, or a value is outside its type.
112
+ */
113
+ export declare function serializeRespondOutput(schema: EvmSchemaInput, output: AbiDecodedOutput): Uint8Array;
114
+ /**
115
+ * Whether an EVM transaction is a contract call, decided over its input
116
+ * bytes exactly as the MPC decides it (`is_contract_call` in its
117
+ * `chain-ethereum/src/event_parsing.rs`): more than two bytes of input, so a
118
+ * one- or two-byte input is NOT a contract call. The answer selects the
119
+ * branch of {@link executedEvmRespondOutput}.
120
+ *
121
+ * Pass the signed transaction's `data`, or, from the request record alone,
122
+ * `assembleCalldata(request.txParams.calldata)`, which yields the same bytes
123
+ * (`"0x"` for a request without calldata).
124
+ *
125
+ * @param input - The transaction's input bytes (hex string or bytes).
126
+ * @returns True when the MPC treats the transaction as a contract call.
127
+ * @throws {Error} If `input` is neither bytes nor valid 0x hex.
128
+ */
129
+ export declare function isEvmContractCall(input: ethers.BytesLike): boolean;
130
+ /**
131
+ * How a `debug_traceTransaction` (callTracer) read of a transaction's top
132
+ * call frame came back: the MPC's `TraceOutput`. Carried by
133
+ * {@link EvmTraceOutput}.
134
+ */
135
+ export declare enum EvmTraceOutputKind {
136
+ /** The transaction was not traced: the MPC traces contract calls only. */
137
+ NotTraced = "NotTraced",
138
+ /** The top call frame carries a string `output` field: the return data, possibly empty (`0x`). */
139
+ Output = "Output",
140
+ /** The top call frame carries no string `output` field. */
141
+ NoReturnData = "NoReturnData"
142
+ }
143
+ /**
144
+ * The traced return data of an EVM transaction, as the MPC models it: a top
145
+ * call frame's string `output` field (even `0x`) is
146
+ * {@link EvmTraceOutputKind.Output}, an absent or non-string one is
147
+ * {@link EvmTraceOutputKind.NoReturnData}. {@link evmTraceOutputFromCallFrame}
148
+ * reads it off a frame.
149
+ */
150
+ export type EvmTraceOutput = {
151
+ /** The frame carried an `output` field. */
152
+ readonly kind: EvmTraceOutputKind.Output;
153
+ /** The frame's `output`: the ABI-encoded return data (hex string or bytes). */
154
+ readonly returnData: ethers.BytesLike;
155
+ } | {
156
+ /** The frame carried no `output` field. */
157
+ readonly kind: EvmTraceOutputKind.NoReturnData;
158
+ } | {
159
+ /** No trace was taken. */
160
+ readonly kind: EvmTraceOutputKind.NotTraced;
161
+ };
162
+ /**
163
+ * The exact respond output the MPC attests for an EVM transaction that
164
+ * executed (the payload of an `OutputKind.executed` attestation), derived
165
+ * from the request's outputDeserializationSchema alone. The schema and the
166
+ * execution's return data MUST agree: an empty schema declares that the
167
+ * execution returns nothing, a non-empty schema that it returns data.
168
+ *
169
+ * - Not a contract call (a plain transfer): there is no return data, so the
170
+ * schema must be empty and the output is EMPTY.
171
+ * - A contract call whose trace carries no return data, or empty return
172
+ * data (`0x`): the schema must be empty and the output is EMPTY.
173
+ * - A contract call that returned data: the schema must be non-empty, and
174
+ * the output is the return data decoded by {@link deserializeEvmOutput}
175
+ * and serialised by {@link serializeRespondOutput}.
176
+ *
177
+ * The schema's types are checked on every path, a plain transfer included,
178
+ * so a request the MPC should have dropped never attests anything. A failed
179
+ * or unviable execution is attested over an empty output instead, which
180
+ * needs no call. An empty output under `executed` is therefore ordinary for
181
+ * an empty schema: its settle circuit verifies at width 0 and must route on
182
+ * the verified `outputKind`, never on the width.
183
+ *
184
+ * @param schema - The request's outputDeserializationSchema (a request record's field satisfies this).
185
+ * @param isContractCall - Whether the transaction is a contract call, as {@link isEvmContractCall} decides it.
186
+ * @param trace - The transaction's traced return data (`NotTraced` for an untraced plain transfer).
187
+ * @returns The respond bytes, unpadded, empty for an empty schema.
188
+ * @throws {Error} Exactly where the MPC refuses to attest an execution: a
189
+ * malformed schema or an unsupported output type, a contract call not
190
+ * traced, return data under an empty schema, no or empty return data
191
+ * under a non-empty schema, return data that is not canonical ABI
192
+ * ({@link checkCanonicalReturnData}) or that the schema cannot decode, and
193
+ * every {@link serializeRespondOutput} rejection.
194
+ */
195
+ export declare function executedEvmRespondOutput(schema: EvmSchemaInput, isContractCall: boolean, trace: EvmTraceOutput): Uint8Array;
196
+ /** A parsed JSON object. */
197
+ export interface JsonObject {
198
+ readonly [key: string]: JsonValue;
199
+ }
200
+ /** Any parsed JSON value: the shape of a JSON-RPC `result`. */
201
+ export type JsonValue = null | boolean | number | string | readonly JsonValue[] | JsonObject;
202
+ /**
203
+ * The {@link EvmTraceOutput} of a `debug_traceTransaction` callTracer top
204
+ * call frame, read exactly as the MPC reads it (`trace_output_to_bytes` in
205
+ * its `chain-ethereum/src/rpc.rs`):
206
+ *
207
+ * - The frame must be a JSON object with a `type` field (of any value).
208
+ * - A non-empty string `error` refuses the frame, naming a non-empty string
209
+ * `revertReason` beside it. Any other `error` is ignored.
210
+ * - A string `output` is {@link EvmTraceOutputKind.Output}, its hex decoded
211
+ * after one optional lowercase `0x` prefix (`0x` and `""` are empty return
212
+ * data). An absent or non-string `output` is
213
+ * {@link EvmTraceOutputKind.NoReturnData}.
214
+ *
215
+ * @param frame - The JSON-RPC `result` of `debug_traceTransaction` with the callTracer.
216
+ * @returns The frame's traced return data, for {@link executedEvmRespondOutput}.
217
+ * @throws {Error} If the frame is not an object, has no `type`, reports an
218
+ * `error`, or carries an `output` that is not even-length hex.
219
+ */
220
+ export declare function evmTraceOutputFromCallFrame(frame: JsonValue): EvmTraceOutput;
221
+ /**
222
+ * The canonical text of an output schema: `JSON.stringify` of its fields
223
+ * reduced to `{name, type}` in schema order, with no whitespace. A schema's
224
+ * on-chain bytes must be exactly this text followed by NUL padding, so one
225
+ * schema has exactly one byte form. Write a contract's schema literal with
226
+ * this function's output.
82
227
  *
83
- * @param schema - The respondSerializationSchema: parsed, JSON text, or the raw NUL-padded on-chain bytes.
84
- * @param output - Decoded values keyed by field name (from {@link deserializeEvmOutput} or any source using the same forms).
85
- * @returns The packed respond bytes.
86
- * @throws {Error} If the schema is empty or malformed, packs to more than
87
- * {@link MAX_RESPOND_PACKED_BYTES} bytes, a value falls outside its declared
88
- * range, or a dynamic payload exceeds its capacity.
228
+ * @param fields - The schema's fields in order.
229
+ * @returns The canonical JSON text, `[]` for an empty schema.
89
230
  */
90
- export declare function serializeRespondOutput(schema: AbiSchemaInput, output: AbiDecodedOutput): Uint8Array;
231
+ export declare function canonicalSchemaText(fields: readonly EvmSchemaField[]): string;
91
232
  //# sourceMappingURL=abi-serde.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"abi-serde.d.ts","sourceRoot":"","sources":["../src/abi-serde.ts"],"names":[],"mappings":"AAyDA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,MAAM,EAAE,GAAG,QAAQ,MAAM,EAAE,CAAC;AAE7F,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,YAAY,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,eAAe,GAAG,aAAa,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC;AAEzC,wFAAwF;AACxF,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG,SAAS,cAAc,EAAE,GAAG,MAAM,GAAG,UAAU,CAAC;AAM7E;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,eAAe,EAAE,CAAC;AAElG,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAM/D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,CAAC,SAAS,GAC3B,gBAAgB,CAclB;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,gBAAgB,GACvB,UAAU,CAqBZ"}
1
+ {"version":3,"file":"abi-serde.d.ts","sourceRoot":"","sources":["../src/abi-serde.ts"],"names":[],"mappings":"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"}