@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.
- package/README.md +53 -25
- package/dist/abi-serde.d.ts +198 -57
- package/dist/abi-serde.d.ts.map +1 -1
- package/dist/abi-serde.js +478 -367
- package/dist/abi-serde.js.map +1 -1
- package/dist/compact-descriptors.d.ts +25 -8
- package/dist/compact-descriptors.d.ts.map +1 -1
- package/dist/compact-descriptors.js +42 -32
- package/dist/compact-descriptors.js.map +1 -1
- package/dist/constants.d.ts +3 -22
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -25
- package/dist/constants.js.map +1 -1
- package/dist/ecdsa-attestation.d.ts +44 -16
- package/dist/ecdsa-attestation.d.ts.map +1 -1
- package/dist/ecdsa-attestation.js +49 -17
- package/dist/ecdsa-attestation.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/managed/compiler/contract-info.json +1759 -34
- package/dist/managed/compiler/contract-manifest.json +8 -8
- package/dist/managed/contract/index.d.ts +416 -7
- package/dist/managed/contract/index.js +1248 -193
- package/dist/managed/contract/index.js.map +1 -1
- package/dist/mpc-output-cache.d.ts +5 -29
- package/dist/mpc-output-cache.d.ts.map +1 -1
- package/dist/mpc-output-cache.js +8 -42
- package/dist/mpc-output-cache.js.map +1 -1
- package/dist/signature-requests-state-reader.js +3 -3
- package/dist/signature-requests-state-reader.js.map +1 -1
- package/dist/signet-contract-events.d.ts +52 -12
- package/dist/signet-contract-events.d.ts.map +1 -1
- package/dist/signet-contract-events.js +89 -34
- package/dist/signet-contract-events.js.map +1 -1
- package/dist/signet-evtype2tx-record-decoding.d.ts.map +1 -1
- package/dist/signet-evtype2tx-record-decoding.js +6 -5
- package/dist/signet-evtype2tx-record-decoding.js.map +1 -1
- package/dist/signet-evtype2tx-requests.d.ts +17 -12
- package/dist/signet-evtype2tx-requests.d.ts.map +1 -1
- package/dist/signet-evtype2tx-requests.js +92 -16
- package/dist/signet-evtype2tx-requests.js.map +1 -1
- package/dist/signet-request-id.d.ts +5 -2
- package/dist/signet-request-id.d.ts.map +1 -1
- package/dist/signet-request-id.js +27 -9
- package/dist/signet-request-id.js.map +1 -1
- package/dist/signet-request-response-reader.d.ts +10 -4
- package/dist/signet-request-response-reader.d.ts.map +1 -1
- package/dist/signet-request-response-reader.js +10 -12
- package/dist/signet-request-response-reader.js.map +1 -1
- package/dist/signet-requests.d.ts +48 -17
- package/dist/signet-requests.d.ts.map +1 -1
- package/dist/signet-requests.js +18 -6
- package/dist/signet-requests.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -8
- package/dist/testing.js.map +1 -1
- package/package.json +2 -2
- package/src/Signet.compact +299 -100
- 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
|
|
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) | `
|
|
55
|
-
| Build and store a signature request (runtime step 1) | `
|
|
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) | `
|
|
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 (`
|
|
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
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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.
|
package/dist/abi-serde.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
29
|
-
* accepts.
|
|
30
|
-
*
|
|
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
|
|
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
|
-
*
|
|
43
|
-
* numeric strings
|
|
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
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
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
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
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
|
|
89
|
+
export declare function deriveRespondSchema(schema: EvmSchemaInput): Schema;
|
|
71
90
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
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
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
84
|
-
* @
|
|
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
|
|
231
|
+
export declare function canonicalSchemaText(fields: readonly EvmSchemaField[]): string;
|
|
91
232
|
//# sourceMappingURL=abi-serde.d.ts.map
|
package/dist/abi-serde.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abi-serde.d.ts","sourceRoot":"","sources":["../src/abi-serde.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"abi-serde.d.ts","sourceRoot":"","sources":["../src/abi-serde.ts"],"names":[],"mappings":"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"}
|