@agirails/sdk 4.4.9 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builders/DeliveryProofBuilder.d.ts +224 -13
- package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
- package/dist/builders/DeliveryProofBuilder.js +247 -13
- package/dist/builders/DeliveryProofBuilder.js.map +1 -1
- package/dist/cli/agirails.d.ts +85 -1
- package/dist/cli/agirails.d.ts.map +1 -1
- package/dist/cli/agirails.js +429 -154
- package/dist/cli/agirails.js.map +1 -1
- package/dist/cli/commands/init.d.ts +95 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +338 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/publish.d.ts +19 -0
- package/dist/cli/commands/publish.d.ts.map +1 -1
- package/dist/cli/commands/publish.js +14 -1
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/receipt.d.ts +70 -2
- package/dist/cli/commands/receipt.d.ts.map +1 -1
- package/dist/cli/commands/receipt.js +218 -3
- package/dist/cli/commands/receipt.js.map +1 -1
- package/dist/cli/commands/test.d.ts +77 -1
- package/dist/cli/commands/test.d.ts.map +1 -1
- package/dist/cli/commands/test.js +264 -2
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/lib/runRequest.d.ts +90 -0
- package/dist/cli/lib/runRequest.d.ts.map +1 -1
- package/dist/cli/lib/runRequest.js +300 -9
- package/dist/cli/lib/runRequest.js.map +1 -1
- package/dist/cli/lib/sentinelReflections.d.ts +111 -0
- package/dist/cli/lib/sentinelReflections.d.ts.map +1 -0
- package/dist/cli/lib/sentinelReflections.js +193 -0
- package/dist/cli/lib/sentinelReflections.js.map +1 -0
- package/dist/delivery/MockDeliveryChannel.d.ts +208 -0
- package/dist/delivery/MockDeliveryChannel.d.ts.map +1 -0
- package/dist/delivery/MockDeliveryChannel.js +445 -0
- package/dist/delivery/MockDeliveryChannel.js.map +1 -0
- package/dist/delivery/RelayDeliveryChannel.d.ts +176 -0
- package/dist/delivery/RelayDeliveryChannel.d.ts.map +1 -0
- package/dist/delivery/RelayDeliveryChannel.js +377 -0
- package/dist/delivery/RelayDeliveryChannel.js.map +1 -0
- package/dist/delivery/channel.d.ts +282 -0
- package/dist/delivery/channel.d.ts.map +1 -0
- package/dist/delivery/channel.js +76 -0
- package/dist/delivery/channel.js.map +1 -0
- package/dist/delivery/channelLog.d.ts +115 -0
- package/dist/delivery/channelLog.d.ts.map +1 -0
- package/dist/delivery/channelLog.js +94 -0
- package/dist/delivery/channelLog.js.map +1 -0
- package/dist/delivery/crypto.d.ts +312 -0
- package/dist/delivery/crypto.d.ts.map +1 -0
- package/dist/delivery/crypto.js +495 -0
- package/dist/delivery/crypto.js.map +1 -0
- package/dist/delivery/eip712.d.ts +248 -0
- package/dist/delivery/eip712.d.ts.map +1 -0
- package/dist/delivery/eip712.js +397 -0
- package/dist/delivery/eip712.js.map +1 -0
- package/dist/delivery/envelopeBuilder.d.ts +531 -0
- package/dist/delivery/envelopeBuilder.d.ts.map +1 -0
- package/dist/delivery/envelopeBuilder.js +832 -0
- package/dist/delivery/envelopeBuilder.js.map +1 -0
- package/dist/delivery/index.d.ts +53 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +143 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/delivery/keys.d.ts +344 -0
- package/dist/delivery/keys.d.ts.map +1 -0
- package/dist/delivery/keys.js +513 -0
- package/dist/delivery/keys.js.map +1 -0
- package/dist/delivery/nonce-keys.d.ts +93 -0
- package/dist/delivery/nonce-keys.d.ts.map +1 -0
- package/dist/delivery/nonce-keys.js +88 -0
- package/dist/delivery/nonce-keys.js.map +1 -0
- package/dist/delivery/setupBuilder.d.ts +403 -0
- package/dist/delivery/setupBuilder.d.ts.map +1 -0
- package/dist/delivery/setupBuilder.js +554 -0
- package/dist/delivery/setupBuilder.js.map +1 -0
- package/dist/delivery/types.d.ts +722 -0
- package/dist/delivery/types.d.ts.map +1 -0
- package/dist/delivery/types.js +150 -0
- package/dist/delivery/types.js.map +1 -0
- package/dist/delivery/validate.d.ts +288 -0
- package/dist/delivery/validate.d.ts.map +1 -0
- package/dist/delivery/validate.js +648 -0
- package/dist/delivery/validate.js.map +1 -0
- package/dist/level1/Agent.d.ts +130 -0
- package/dist/level1/Agent.d.ts.map +1 -1
- package/dist/level1/Agent.js +248 -0
- package/dist/level1/Agent.js.map +1 -1
- package/dist/level1/types/Options.d.ts +62 -0
- package/dist/level1/types/Options.d.ts.map +1 -1
- package/dist/level1/types/Options.js +22 -0
- package/dist/level1/types/Options.js.map +1 -1
- package/dist/runtime/MockRuntime.d.ts +32 -0
- package/dist/runtime/MockRuntime.d.ts.map +1 -1
- package/dist/runtime/MockRuntime.js +44 -0
- package/dist/runtime/MockRuntime.js.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIP-16 Delivery Surface — EIP-712 Domain, Types & Recovery (Phase 2a)
|
|
3
|
+
* ======================================================================
|
|
4
|
+
*
|
|
5
|
+
* Canonical EIP-712 contract surface for the AGIRAILS delivery layer
|
|
6
|
+
* (AIP-16 Rev 5). This module is the *single source of truth* for:
|
|
7
|
+
*
|
|
8
|
+
* - the EIP-712 domain name + version used by all delivery signatures,
|
|
9
|
+
* - the typed-data schemas (`DeliverySetupSignedV1`,
|
|
10
|
+
* `DeliveryEnvelopeSignedV1`) — field order is IMMUTABLE,
|
|
11
|
+
* - network → chainId resolution,
|
|
12
|
+
* - domain object construction with `verifyingContract` anchored to the
|
|
13
|
+
* ACTP kernel address (the relay-allowlist anchor — see DEC-10),
|
|
14
|
+
* - signature recovery helpers wrapping `ethers.verifyTypedData`.
|
|
15
|
+
*
|
|
16
|
+
* ## Domain separation
|
|
17
|
+
*
|
|
18
|
+
* The delivery domain (`"AGIRAILS Delivery"`) is DELIBERATELY distinct
|
|
19
|
+
* from the negotiation domain (`"AGIRAILS"`) and the receipts domain
|
|
20
|
+
* (`"AGIRAILS Receipts"`). Domain reuse across AIP features enables
|
|
21
|
+
* cross-feature signature replay (e.g. a quote signature being replayed
|
|
22
|
+
* as a delivery setup); we keep the three domains strictly partitioned.
|
|
23
|
+
*
|
|
24
|
+
* ## Smart-wallet auth (verification responsibility)
|
|
25
|
+
*
|
|
26
|
+
* Recovery here only returns the EOA that produced the signature. The
|
|
27
|
+
* caller MUST then perform the two-step check:
|
|
28
|
+
* 1. recovered === payload.signerAddress
|
|
29
|
+
* 2. signerAddress === participantAddress OR
|
|
30
|
+
* computeSmartWalletFromSigner(signerAddress) === participantAddress
|
|
31
|
+
*
|
|
32
|
+
* That second check is intentionally NOT in this module — it's a
|
|
33
|
+
* cross-cutting auth concern shared with receipts V2
|
|
34
|
+
* (`Platform/agirails.app/web/lib/receipts/auth.ts`) and is performed
|
|
35
|
+
* by the dedicated verifier modules in later phases.
|
|
36
|
+
*
|
|
37
|
+
* ## Kernel allowlist (verification responsibility)
|
|
38
|
+
*
|
|
39
|
+
* Recovery helpers take `kernelAddress` directly from the payload so the
|
|
40
|
+
* EIP-712 domain matches what was signed. Callers MUST independently
|
|
41
|
+
* verify the `kernelAddress` against their own allowlist BEFORE trusting
|
|
42
|
+
* the recovered signer; otherwise an attacker could sign against an
|
|
43
|
+
* attacker-controlled kernel and the recovery would succeed trivially.
|
|
44
|
+
*
|
|
45
|
+
* @module delivery/eip712
|
|
46
|
+
* @see {@link https://eips.ethereum.org/EIPS/eip-712 EIP-712}
|
|
47
|
+
* @see ./types — the underlying signed payload interfaces
|
|
48
|
+
*/
|
|
49
|
+
import { type TypedDataField } from 'ethers';
|
|
50
|
+
import type { DeliveryEnvelopeSignedV1, DeliveryNetwork, DeliverySetupSignedV1 } from './types';
|
|
51
|
+
/**
|
|
52
|
+
* EIP-712 domain `name` for ALL delivery surface signatures.
|
|
53
|
+
*
|
|
54
|
+
* Distinct from `"AGIRAILS"` (negotiation, AIP-2.1) and
|
|
55
|
+
* `"AGIRAILS Receipts"` (AIP-3 receipts) so that a signature produced
|
|
56
|
+
* for one feature cannot be replayed as another. Changing this string
|
|
57
|
+
* is a breaking SDK and Platform change.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DELIVERY_DOMAIN_NAME = "AGIRAILS Delivery";
|
|
60
|
+
/**
|
|
61
|
+
* EIP-712 domain `version` for the v1 delivery schemas. The version
|
|
62
|
+
* field is bumped only on incompatible schema changes (e.g. addition
|
|
63
|
+
* of new required fields, reordering, or semantic shifts). Adding a
|
|
64
|
+
* new scheme value via the `string` field does NOT require a version
|
|
65
|
+
* bump.
|
|
66
|
+
*/
|
|
67
|
+
export declare const DELIVERY_DOMAIN_VERSION = "1";
|
|
68
|
+
/**
|
|
69
|
+
* EIP-712 type schema for {@link DeliverySetupSignedV1}.
|
|
70
|
+
*
|
|
71
|
+
* 11 fields, field order IMMUTABLE. Matches the JSDoc schema documented
|
|
72
|
+
* on `DeliverySetupSignedV1`.
|
|
73
|
+
*/
|
|
74
|
+
export declare const DELIVERY_SETUP_TYPES_V1: Record<string, TypedDataField[]>;
|
|
75
|
+
/**
|
|
76
|
+
* EIP-712 type schema for {@link DeliveryEnvelopeSignedV1}.
|
|
77
|
+
*
|
|
78
|
+
* 12 fields, field order IMMUTABLE. Matches the JSDoc schema documented
|
|
79
|
+
* on `DeliveryEnvelopeSignedV1`.
|
|
80
|
+
*
|
|
81
|
+
* The encryption-related fields (`providerEphemeralPubkey`, `nonce`,
|
|
82
|
+
* `tag`) are signed under their canonical-empty values for
|
|
83
|
+
* `scheme: "public-v1"`; the type schema itself is invariant across
|
|
84
|
+
* schemes — only the *values* differ.
|
|
85
|
+
*/
|
|
86
|
+
export declare const DELIVERY_ENVELOPE_TYPES_V1: Record<string, TypedDataField[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Error thrown by the delivery EIP-712 helpers when inputs are
|
|
89
|
+
* malformed (unknown network, non-address kernel, empty / malformed
|
|
90
|
+
* signature, etc.).
|
|
91
|
+
*
|
|
92
|
+
* Mirrors the {@link SignatureVerificationError} pattern from
|
|
93
|
+
* `src/errors/index.ts` but is intentionally a plain `Error` subclass
|
|
94
|
+
* rather than an `ACTPError` extension — this module is part of the
|
|
95
|
+
* pre-builder foundation layer and we keep its dependency surface
|
|
96
|
+
* minimal (no `ACTPError` import, no `State` import). The higher-level
|
|
97
|
+
* delivery error class extending `ACTPError` is introduced alongside
|
|
98
|
+
* the builders/verifiers in a later phase.
|
|
99
|
+
*
|
|
100
|
+
* `code` mirrors the structured-code style used elsewhere in the SDK
|
|
101
|
+
* so callers can branch on stable identifiers.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* try {
|
|
106
|
+
* const signer = recoverSetupSigner(payload, sig, kernel);
|
|
107
|
+
* } catch (err) {
|
|
108
|
+
* if (err instanceof DeliveryEip712Error && err.code === 'INVALID_KERNEL_ADDRESS') {
|
|
109
|
+
* // surface to user
|
|
110
|
+
* }
|
|
111
|
+
* throw err;
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare class DeliveryEip712Error extends Error {
|
|
116
|
+
/** Stable machine-actionable error code. */
|
|
117
|
+
readonly code: string;
|
|
118
|
+
/** Optional structured details for debugging (expected vs actual, etc.). */
|
|
119
|
+
readonly details?: Record<string, unknown>;
|
|
120
|
+
constructor(code: string, message: string, details?: Record<string, unknown>);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve an EVM chainId from a {@link DeliveryNetwork}.
|
|
124
|
+
*
|
|
125
|
+
* - `"base-sepolia"` → `84532`
|
|
126
|
+
* - `"base-mainnet"` → `8453`
|
|
127
|
+
* - `"mock"` → throws — the mock runtime has no EIP-712 chain, and
|
|
128
|
+
* producing a signature against an arbitrary placeholder chainId
|
|
129
|
+
* could be replayed against a real network if the same signer ever
|
|
130
|
+
* used the same key there. Callers exercising delivery in mock mode
|
|
131
|
+
* should branch *before* calling into the EIP-712 layer.
|
|
132
|
+
*
|
|
133
|
+
* @param network - Target delivery network.
|
|
134
|
+
* @returns Numeric chainId suitable for the EIP-712 domain.
|
|
135
|
+
* @throws {DeliveryEip712Error} `UNKNOWN_NETWORK` if `network` is not
|
|
136
|
+
* one of the recognized delivery networks, or `MOCK_NETWORK_NOT_SUPPORTED`
|
|
137
|
+
* if the caller passed `"mock"`.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* chainIdForNetwork('base-sepolia'); // 84532
|
|
142
|
+
* chainIdForNetwork('base-mainnet'); // 8453
|
|
143
|
+
* chainIdForNetwork('mock'); // throws DeliveryEip712Error
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function chainIdForNetwork(network: DeliveryNetwork): number;
|
|
147
|
+
/**
|
|
148
|
+
* Construct the EIP-712 domain object for a delivery signature.
|
|
149
|
+
*
|
|
150
|
+
* Per AIP-16 Rev 5 DEC-10, the domain MUST anchor `verifyingContract`
|
|
151
|
+
* to the ACTP kernel address on the target chain. Relays validate
|
|
152
|
+
* `verifyingContract` against their kernel allowlist before accepting
|
|
153
|
+
* a setup or envelope; this prevents an attacker from registering an
|
|
154
|
+
* attacker-controlled kernel address in the domain and producing
|
|
155
|
+
* signatures the relay would otherwise accept.
|
|
156
|
+
*
|
|
157
|
+
* The returned object is shaped for direct use with
|
|
158
|
+
* `ethers.verifyTypedData` and `ethers.signTypedData`.
|
|
159
|
+
*
|
|
160
|
+
* @param chainId - EVM chainId (see {@link chainIdForNetwork}).
|
|
161
|
+
* @param kernelAddress - Address of the ACTP kernel contract on `chainId`.
|
|
162
|
+
* Must be a syntactically valid Ethereum address.
|
|
163
|
+
* @returns Fully populated EIP-712 domain object.
|
|
164
|
+
* @throws {DeliveryEip712Error} `INVALID_CHAIN_ID` if `chainId` is
|
|
165
|
+
* not a positive integer, or `INVALID_KERNEL_ADDRESS` if
|
|
166
|
+
* `kernelAddress` is not a valid address.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const domain = buildDeliveryDomain(84532, '0x469CBADbACFFE096270594F0a31f0EEC53753411');
|
|
171
|
+
* // {
|
|
172
|
+
* // name: 'AGIRAILS Delivery',
|
|
173
|
+
* // version: '1',
|
|
174
|
+
* // chainId: 84532,
|
|
175
|
+
* // verifyingContract: '0x469CBADbACFFE096270594F0a31f0EEC53753411',
|
|
176
|
+
* // }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export declare function buildDeliveryDomain(chainId: number, kernelAddress: string): {
|
|
180
|
+
name: string;
|
|
181
|
+
version: string;
|
|
182
|
+
chainId: number;
|
|
183
|
+
verifyingContract: string;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Recover the EOA that produced a {@link DeliverySetupSignedV1}
|
|
187
|
+
* signature.
|
|
188
|
+
*
|
|
189
|
+
* Wraps `ethers.verifyTypedData` with the canonical delivery domain
|
|
190
|
+
* (`"AGIRAILS Delivery"` / version `"1"`) anchored to the provided
|
|
191
|
+
* `kernelAddress` and `payload.chainId`.
|
|
192
|
+
*
|
|
193
|
+
* ## Caller responsibilities (NOT performed here)
|
|
194
|
+
*
|
|
195
|
+
* 1. **Allowlist `kernelAddress`** against the set of known ACTP
|
|
196
|
+
* kernels for the target network. Recovery here uses whatever
|
|
197
|
+
* address the caller supplies; an attacker controlling
|
|
198
|
+
* `kernelAddress` could trivially produce valid recoveries.
|
|
199
|
+
*
|
|
200
|
+
* 2. **Compare recovered to `payload.signerAddress`** (case-insensitive).
|
|
201
|
+
* Mismatch indicates either a forged signature or a buggy signer
|
|
202
|
+
* that signed a different payload than it claimed.
|
|
203
|
+
*
|
|
204
|
+
* 3. **Smart-wallet equality check** between `payload.signerAddress`
|
|
205
|
+
* and `payload.requesterAddress`. The recovered EOA may be the
|
|
206
|
+
* controller of a Smart Wallet contract whose address is the
|
|
207
|
+
* `requesterAddress`. Use the SDK's `computeSmartWalletFromSigner`
|
|
208
|
+
* helper (or the platform-side equivalent) to derive the Smart
|
|
209
|
+
* Wallet address and compare.
|
|
210
|
+
*
|
|
211
|
+
* @param payload - The signed projection (NOT the wire envelope).
|
|
212
|
+
* @param signature - Hex-encoded EIP-712 signature, 0x-prefixed.
|
|
213
|
+
* @param kernelAddress - Kernel address to anchor the EIP-712 domain
|
|
214
|
+
* to. SHOULD equal `payload.kernelAddress`; passing them separately
|
|
215
|
+
* here forces the caller to think about the allowlist.
|
|
216
|
+
* @returns The recovered EOA address (checksummed).
|
|
217
|
+
* @throws {DeliveryEip712Error} `INVALID_KERNEL_ADDRESS`,
|
|
218
|
+
* `INVALID_CHAIN_ID`, or `INVALID_SIGNATURE` on bad inputs.
|
|
219
|
+
* @throws {Error} Re-thrown from ethers if the typed-data hash cannot
|
|
220
|
+
* be computed (e.g. malformed payload).
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const recovered = recoverSetupSigner(payload, sig, KERNEL);
|
|
225
|
+
* if (recovered.toLowerCase() !== payload.signerAddress.toLowerCase()) {
|
|
226
|
+
* throw new Error('signer_self_mismatch');
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export declare function recoverSetupSigner(payload: DeliverySetupSignedV1, signature: string, kernelAddress: string): string;
|
|
231
|
+
/**
|
|
232
|
+
* Recover the EOA that produced a {@link DeliveryEnvelopeSignedV1}
|
|
233
|
+
* signature.
|
|
234
|
+
*
|
|
235
|
+
* See {@link recoverSetupSigner} — same shape, same caller
|
|
236
|
+
* responsibilities (allowlist kernel, compare recovered to
|
|
237
|
+
* `payload.signerAddress`, smart-wallet equality between
|
|
238
|
+
* `signerAddress` and `providerAddress`).
|
|
239
|
+
*
|
|
240
|
+
* @param payload - The signed projection (NOT the wire envelope).
|
|
241
|
+
* @param signature - Hex-encoded EIP-712 signature, 0x-prefixed.
|
|
242
|
+
* @param kernelAddress - Kernel address to anchor the EIP-712 domain.
|
|
243
|
+
* @returns The recovered EOA address (checksummed).
|
|
244
|
+
* @throws {DeliveryEip712Error} `INVALID_KERNEL_ADDRESS`,
|
|
245
|
+
* `INVALID_CHAIN_ID`, or `INVALID_SIGNATURE` on bad inputs.
|
|
246
|
+
*/
|
|
247
|
+
export declare function recoverEnvelopeSigner(payload: DeliveryEnvelopeSignedV1, signature: string, kernelAddress: string): string;
|
|
248
|
+
//# sourceMappingURL=eip712.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip712.d.ts","sourceRoot":"","sources":["../../src/delivery/eip712.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAC;AAErD,OAAO,KAAK,EACV,wBAAwB,EACxB,eAAe,EACf,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAMjB;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAsB3C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAkBpE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAmBvE,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,4CAA4C;IAC5C,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEtC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQ7E;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CA0BlE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GACpB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAuBA;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,EAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,MAAM,CAgBR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,wBAAwB,EACjC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,MAAM,CAgBR"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AIP-16 Delivery Surface — EIP-712 Domain, Types & Recovery (Phase 2a)
|
|
4
|
+
* ======================================================================
|
|
5
|
+
*
|
|
6
|
+
* Canonical EIP-712 contract surface for the AGIRAILS delivery layer
|
|
7
|
+
* (AIP-16 Rev 5). This module is the *single source of truth* for:
|
|
8
|
+
*
|
|
9
|
+
* - the EIP-712 domain name + version used by all delivery signatures,
|
|
10
|
+
* - the typed-data schemas (`DeliverySetupSignedV1`,
|
|
11
|
+
* `DeliveryEnvelopeSignedV1`) — field order is IMMUTABLE,
|
|
12
|
+
* - network → chainId resolution,
|
|
13
|
+
* - domain object construction with `verifyingContract` anchored to the
|
|
14
|
+
* ACTP kernel address (the relay-allowlist anchor — see DEC-10),
|
|
15
|
+
* - signature recovery helpers wrapping `ethers.verifyTypedData`.
|
|
16
|
+
*
|
|
17
|
+
* ## Domain separation
|
|
18
|
+
*
|
|
19
|
+
* The delivery domain (`"AGIRAILS Delivery"`) is DELIBERATELY distinct
|
|
20
|
+
* from the negotiation domain (`"AGIRAILS"`) and the receipts domain
|
|
21
|
+
* (`"AGIRAILS Receipts"`). Domain reuse across AIP features enables
|
|
22
|
+
* cross-feature signature replay (e.g. a quote signature being replayed
|
|
23
|
+
* as a delivery setup); we keep the three domains strictly partitioned.
|
|
24
|
+
*
|
|
25
|
+
* ## Smart-wallet auth (verification responsibility)
|
|
26
|
+
*
|
|
27
|
+
* Recovery here only returns the EOA that produced the signature. The
|
|
28
|
+
* caller MUST then perform the two-step check:
|
|
29
|
+
* 1. recovered === payload.signerAddress
|
|
30
|
+
* 2. signerAddress === participantAddress OR
|
|
31
|
+
* computeSmartWalletFromSigner(signerAddress) === participantAddress
|
|
32
|
+
*
|
|
33
|
+
* That second check is intentionally NOT in this module — it's a
|
|
34
|
+
* cross-cutting auth concern shared with receipts V2
|
|
35
|
+
* (`Platform/agirails.app/web/lib/receipts/auth.ts`) and is performed
|
|
36
|
+
* by the dedicated verifier modules in later phases.
|
|
37
|
+
*
|
|
38
|
+
* ## Kernel allowlist (verification responsibility)
|
|
39
|
+
*
|
|
40
|
+
* Recovery helpers take `kernelAddress` directly from the payload so the
|
|
41
|
+
* EIP-712 domain matches what was signed. Callers MUST independently
|
|
42
|
+
* verify the `kernelAddress` against their own allowlist BEFORE trusting
|
|
43
|
+
* the recovered signer; otherwise an attacker could sign against an
|
|
44
|
+
* attacker-controlled kernel and the recovery would succeed trivially.
|
|
45
|
+
*
|
|
46
|
+
* @module delivery/eip712
|
|
47
|
+
* @see {@link https://eips.ethereum.org/EIPS/eip-712 EIP-712}
|
|
48
|
+
* @see ./types — the underlying signed payload interfaces
|
|
49
|
+
*/
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.recoverEnvelopeSigner = exports.recoverSetupSigner = exports.buildDeliveryDomain = exports.chainIdForNetwork = exports.DeliveryEip712Error = exports.DELIVERY_ENVELOPE_TYPES_V1 = exports.DELIVERY_SETUP_TYPES_V1 = exports.DELIVERY_DOMAIN_VERSION = exports.DELIVERY_DOMAIN_NAME = void 0;
|
|
52
|
+
const ethers_1 = require("ethers");
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Domain Constants
|
|
55
|
+
// ============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* EIP-712 domain `name` for ALL delivery surface signatures.
|
|
58
|
+
*
|
|
59
|
+
* Distinct from `"AGIRAILS"` (negotiation, AIP-2.1) and
|
|
60
|
+
* `"AGIRAILS Receipts"` (AIP-3 receipts) so that a signature produced
|
|
61
|
+
* for one feature cannot be replayed as another. Changing this string
|
|
62
|
+
* is a breaking SDK and Platform change.
|
|
63
|
+
*/
|
|
64
|
+
exports.DELIVERY_DOMAIN_NAME = 'AGIRAILS Delivery';
|
|
65
|
+
/**
|
|
66
|
+
* EIP-712 domain `version` for the v1 delivery schemas. The version
|
|
67
|
+
* field is bumped only on incompatible schema changes (e.g. addition
|
|
68
|
+
* of new required fields, reordering, or semantic shifts). Adding a
|
|
69
|
+
* new scheme value via the `string` field does NOT require a version
|
|
70
|
+
* bump.
|
|
71
|
+
*/
|
|
72
|
+
exports.DELIVERY_DOMAIN_VERSION = '1';
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// EIP-712 Typed-Data Schemas
|
|
75
|
+
// ============================================================================
|
|
76
|
+
//
|
|
77
|
+
// IMMUTABILITY NOTE
|
|
78
|
+
// -----------------
|
|
79
|
+
// The field order in both `DELIVERY_SETUP_TYPES_V1` and
|
|
80
|
+
// `DELIVERY_ENVELOPE_TYPES_V1` is part of the EIP-712 type hash. Both
|
|
81
|
+
// the signer (this SDK) and every verifier (Platform server, peer
|
|
82
|
+
// SDKs in other languages, the Python SDK) MUST encode byte-for-byte
|
|
83
|
+
// identical typed-data structures. Reordering, renaming, or changing
|
|
84
|
+
// the Solidity type of any field is a HARD-BREAKING schema change.
|
|
85
|
+
// Such changes require a domain version bump and a new exported
|
|
86
|
+
// `*_V2` schema.
|
|
87
|
+
//
|
|
88
|
+
// These arrays mirror the schema documented in
|
|
89
|
+
// `src/delivery/types.ts` (search "EIP-712 schema (signed)" in the
|
|
90
|
+
// type-level JSDoc) — they are kept in lock-step.
|
|
91
|
+
//
|
|
92
|
+
/**
|
|
93
|
+
* EIP-712 type schema for {@link DeliverySetupSignedV1}.
|
|
94
|
+
*
|
|
95
|
+
* 11 fields, field order IMMUTABLE. Matches the JSDoc schema documented
|
|
96
|
+
* on `DeliverySetupSignedV1`.
|
|
97
|
+
*/
|
|
98
|
+
exports.DELIVERY_SETUP_TYPES_V1 = {
|
|
99
|
+
DeliverySetupSignedV1: [
|
|
100
|
+
{ name: 'version', type: 'uint8' },
|
|
101
|
+
{ name: 'txId', type: 'bytes32' },
|
|
102
|
+
{ name: 'chainId', type: 'uint256' },
|
|
103
|
+
{ name: 'kernelAddress', type: 'address' },
|
|
104
|
+
{ name: 'requesterAddress', type: 'address' },
|
|
105
|
+
{ name: 'signerAddress', type: 'address' },
|
|
106
|
+
{ name: 'buyerEphemeralPubkey', type: 'bytes32' },
|
|
107
|
+
{ name: 'acceptedChannels', type: 'string[]' },
|
|
108
|
+
{ name: 'expectedPrivacy', type: 'string' },
|
|
109
|
+
{ name: 'createdAt', type: 'uint64' },
|
|
110
|
+
{ name: 'expiresAt', type: 'uint64' },
|
|
111
|
+
// H4 fix (AIP-16 Phase 3 HIGH): appended at END of field list so
|
|
112
|
+
// existing field indices stay stable. Default value `0` reproduces
|
|
113
|
+
// the legacy hard-coded nonce-0 smart-wallet derivation.
|
|
114
|
+
{ name: 'smartWalletNonce', type: 'uint256' },
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* EIP-712 type schema for {@link DeliveryEnvelopeSignedV1}.
|
|
119
|
+
*
|
|
120
|
+
* 12 fields, field order IMMUTABLE. Matches the JSDoc schema documented
|
|
121
|
+
* on `DeliveryEnvelopeSignedV1`.
|
|
122
|
+
*
|
|
123
|
+
* The encryption-related fields (`providerEphemeralPubkey`, `nonce`,
|
|
124
|
+
* `tag`) are signed under their canonical-empty values for
|
|
125
|
+
* `scheme: "public-v1"`; the type schema itself is invariant across
|
|
126
|
+
* schemes — only the *values* differ.
|
|
127
|
+
*/
|
|
128
|
+
exports.DELIVERY_ENVELOPE_TYPES_V1 = {
|
|
129
|
+
DeliveryEnvelopeSignedV1: [
|
|
130
|
+
{ name: 'version', type: 'uint8' },
|
|
131
|
+
{ name: 'txId', type: 'bytes32' },
|
|
132
|
+
{ name: 'chainId', type: 'uint256' },
|
|
133
|
+
{ name: 'kernelAddress', type: 'address' },
|
|
134
|
+
{ name: 'providerAddress', type: 'address' },
|
|
135
|
+
{ name: 'signerAddress', type: 'address' },
|
|
136
|
+
{ name: 'scheme', type: 'string' },
|
|
137
|
+
{ name: 'providerEphemeralPubkey', type: 'bytes32' },
|
|
138
|
+
{ name: 'nonce', type: 'bytes12' },
|
|
139
|
+
{ name: 'payloadHash', type: 'bytes32' },
|
|
140
|
+
{ name: 'tag', type: 'bytes16' },
|
|
141
|
+
{ name: 'createdAt', type: 'uint64' },
|
|
142
|
+
// H4 fix (AIP-16 Phase 3 HIGH): appended at END of field list so
|
|
143
|
+
// existing field indices stay stable. Default value `0` reproduces
|
|
144
|
+
// the legacy hard-coded nonce-0 smart-wallet derivation.
|
|
145
|
+
{ name: 'smartWalletNonce', type: 'uint256' },
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Error Class
|
|
150
|
+
// ============================================================================
|
|
151
|
+
/**
|
|
152
|
+
* Error thrown by the delivery EIP-712 helpers when inputs are
|
|
153
|
+
* malformed (unknown network, non-address kernel, empty / malformed
|
|
154
|
+
* signature, etc.).
|
|
155
|
+
*
|
|
156
|
+
* Mirrors the {@link SignatureVerificationError} pattern from
|
|
157
|
+
* `src/errors/index.ts` but is intentionally a plain `Error` subclass
|
|
158
|
+
* rather than an `ACTPError` extension — this module is part of the
|
|
159
|
+
* pre-builder foundation layer and we keep its dependency surface
|
|
160
|
+
* minimal (no `ACTPError` import, no `State` import). The higher-level
|
|
161
|
+
* delivery error class extending `ACTPError` is introduced alongside
|
|
162
|
+
* the builders/verifiers in a later phase.
|
|
163
|
+
*
|
|
164
|
+
* `code` mirrors the structured-code style used elsewhere in the SDK
|
|
165
|
+
* so callers can branch on stable identifiers.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* try {
|
|
170
|
+
* const signer = recoverSetupSigner(payload, sig, kernel);
|
|
171
|
+
* } catch (err) {
|
|
172
|
+
* if (err instanceof DeliveryEip712Error && err.code === 'INVALID_KERNEL_ADDRESS') {
|
|
173
|
+
* // surface to user
|
|
174
|
+
* }
|
|
175
|
+
* throw err;
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
class DeliveryEip712Error extends Error {
|
|
180
|
+
constructor(code, message, details) {
|
|
181
|
+
super(message);
|
|
182
|
+
this.name = 'DeliveryEip712Error';
|
|
183
|
+
this.code = code;
|
|
184
|
+
this.details = details;
|
|
185
|
+
// Restore prototype chain for `instanceof` after transpilation to ES5.
|
|
186
|
+
Object.setPrototypeOf(this, DeliveryEip712Error.prototype);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.DeliveryEip712Error = DeliveryEip712Error;
|
|
190
|
+
// ============================================================================
|
|
191
|
+
// Network → ChainId
|
|
192
|
+
// ============================================================================
|
|
193
|
+
/**
|
|
194
|
+
* Resolve an EVM chainId from a {@link DeliveryNetwork}.
|
|
195
|
+
*
|
|
196
|
+
* - `"base-sepolia"` → `84532`
|
|
197
|
+
* - `"base-mainnet"` → `8453`
|
|
198
|
+
* - `"mock"` → throws — the mock runtime has no EIP-712 chain, and
|
|
199
|
+
* producing a signature against an arbitrary placeholder chainId
|
|
200
|
+
* could be replayed against a real network if the same signer ever
|
|
201
|
+
* used the same key there. Callers exercising delivery in mock mode
|
|
202
|
+
* should branch *before* calling into the EIP-712 layer.
|
|
203
|
+
*
|
|
204
|
+
* @param network - Target delivery network.
|
|
205
|
+
* @returns Numeric chainId suitable for the EIP-712 domain.
|
|
206
|
+
* @throws {DeliveryEip712Error} `UNKNOWN_NETWORK` if `network` is not
|
|
207
|
+
* one of the recognized delivery networks, or `MOCK_NETWORK_NOT_SUPPORTED`
|
|
208
|
+
* if the caller passed `"mock"`.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* chainIdForNetwork('base-sepolia'); // 84532
|
|
213
|
+
* chainIdForNetwork('base-mainnet'); // 8453
|
|
214
|
+
* chainIdForNetwork('mock'); // throws DeliveryEip712Error
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
function chainIdForNetwork(network) {
|
|
218
|
+
switch (network) {
|
|
219
|
+
case 'base-sepolia':
|
|
220
|
+
return 84532;
|
|
221
|
+
case 'base-mainnet':
|
|
222
|
+
return 8453;
|
|
223
|
+
case 'mock':
|
|
224
|
+
throw new DeliveryEip712Error('MOCK_NETWORK_NOT_SUPPORTED', 'Delivery EIP-712 signatures are not defined for the mock network; ' +
|
|
225
|
+
'use a real test network (base-sepolia) or branch before reaching ' +
|
|
226
|
+
'the EIP-712 layer.', { network });
|
|
227
|
+
default: {
|
|
228
|
+
// Exhaustiveness guard — if a new `DeliveryNetwork` value is added
|
|
229
|
+
// to the union without a matching case here, the compiler will
|
|
230
|
+
// flag this assignment as a type error.
|
|
231
|
+
const exhaustive = network;
|
|
232
|
+
throw new DeliveryEip712Error('UNKNOWN_NETWORK', `Unknown delivery network: ${String(exhaustive)}`, { network: exhaustive });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exports.chainIdForNetwork = chainIdForNetwork;
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Domain Builder
|
|
239
|
+
// ============================================================================
|
|
240
|
+
/**
|
|
241
|
+
* Construct the EIP-712 domain object for a delivery signature.
|
|
242
|
+
*
|
|
243
|
+
* Per AIP-16 Rev 5 DEC-10, the domain MUST anchor `verifyingContract`
|
|
244
|
+
* to the ACTP kernel address on the target chain. Relays validate
|
|
245
|
+
* `verifyingContract` against their kernel allowlist before accepting
|
|
246
|
+
* a setup or envelope; this prevents an attacker from registering an
|
|
247
|
+
* attacker-controlled kernel address in the domain and producing
|
|
248
|
+
* signatures the relay would otherwise accept.
|
|
249
|
+
*
|
|
250
|
+
* The returned object is shaped for direct use with
|
|
251
|
+
* `ethers.verifyTypedData` and `ethers.signTypedData`.
|
|
252
|
+
*
|
|
253
|
+
* @param chainId - EVM chainId (see {@link chainIdForNetwork}).
|
|
254
|
+
* @param kernelAddress - Address of the ACTP kernel contract on `chainId`.
|
|
255
|
+
* Must be a syntactically valid Ethereum address.
|
|
256
|
+
* @returns Fully populated EIP-712 domain object.
|
|
257
|
+
* @throws {DeliveryEip712Error} `INVALID_CHAIN_ID` if `chainId` is
|
|
258
|
+
* not a positive integer, or `INVALID_KERNEL_ADDRESS` if
|
|
259
|
+
* `kernelAddress` is not a valid address.
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const domain = buildDeliveryDomain(84532, '0x469CBADbACFFE096270594F0a31f0EEC53753411');
|
|
264
|
+
* // {
|
|
265
|
+
* // name: 'AGIRAILS Delivery',
|
|
266
|
+
* // version: '1',
|
|
267
|
+
* // chainId: 84532,
|
|
268
|
+
* // verifyingContract: '0x469CBADbACFFE096270594F0a31f0EEC53753411',
|
|
269
|
+
* // }
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
function buildDeliveryDomain(chainId, kernelAddress) {
|
|
273
|
+
if (!Number.isInteger(chainId) || chainId <= 0) {
|
|
274
|
+
throw new DeliveryEip712Error('INVALID_CHAIN_ID', `chainId must be a positive integer, got ${String(chainId)}`, { chainId });
|
|
275
|
+
}
|
|
276
|
+
if (typeof kernelAddress !== 'string' || !ethers_1.ethers.isAddress(kernelAddress)) {
|
|
277
|
+
throw new DeliveryEip712Error('INVALID_KERNEL_ADDRESS', `kernelAddress is not a valid Ethereum address: ${String(kernelAddress)}`, { kernelAddress });
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
name: exports.DELIVERY_DOMAIN_NAME,
|
|
281
|
+
version: exports.DELIVERY_DOMAIN_VERSION,
|
|
282
|
+
chainId,
|
|
283
|
+
verifyingContract: kernelAddress,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
exports.buildDeliveryDomain = buildDeliveryDomain;
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// Signature Recovery
|
|
289
|
+
// ============================================================================
|
|
290
|
+
/**
|
|
291
|
+
* Internal helper: validate signature shape before handing off to
|
|
292
|
+
* `ethers.verifyTypedData`. Ethers will throw on malformed signatures
|
|
293
|
+
* but with low-level messages; we wrap to produce a consistent
|
|
294
|
+
* structured error.
|
|
295
|
+
*/
|
|
296
|
+
function assertSignatureShape(signature) {
|
|
297
|
+
if (typeof signature !== 'string' || signature.length === 0) {
|
|
298
|
+
throw new DeliveryEip712Error('INVALID_SIGNATURE', 'signature must be a non-empty hex string', { signature });
|
|
299
|
+
}
|
|
300
|
+
// EIP-712 produces 65-byte signatures: r(32) || s(32) || v(1) = 130 hex + "0x".
|
|
301
|
+
// Some wallets return 64-byte EIP-2098 compact sigs (128 hex + "0x"); accept both.
|
|
302
|
+
if (!/^0x[0-9a-fA-F]+$/.test(signature)) {
|
|
303
|
+
throw new DeliveryEip712Error('INVALID_SIGNATURE', `signature is not a valid hex string: ${signature.slice(0, 12)}…`, { signature });
|
|
304
|
+
}
|
|
305
|
+
const hexLen = signature.length - 2;
|
|
306
|
+
if (hexLen !== 130 && hexLen !== 128) {
|
|
307
|
+
throw new DeliveryEip712Error('INVALID_SIGNATURE', `signature has unexpected length ${hexLen} hex chars (expected 128 or 130)`, { signature, hexLength: hexLen });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Recover the EOA that produced a {@link DeliverySetupSignedV1}
|
|
312
|
+
* signature.
|
|
313
|
+
*
|
|
314
|
+
* Wraps `ethers.verifyTypedData` with the canonical delivery domain
|
|
315
|
+
* (`"AGIRAILS Delivery"` / version `"1"`) anchored to the provided
|
|
316
|
+
* `kernelAddress` and `payload.chainId`.
|
|
317
|
+
*
|
|
318
|
+
* ## Caller responsibilities (NOT performed here)
|
|
319
|
+
*
|
|
320
|
+
* 1. **Allowlist `kernelAddress`** against the set of known ACTP
|
|
321
|
+
* kernels for the target network. Recovery here uses whatever
|
|
322
|
+
* address the caller supplies; an attacker controlling
|
|
323
|
+
* `kernelAddress` could trivially produce valid recoveries.
|
|
324
|
+
*
|
|
325
|
+
* 2. **Compare recovered to `payload.signerAddress`** (case-insensitive).
|
|
326
|
+
* Mismatch indicates either a forged signature or a buggy signer
|
|
327
|
+
* that signed a different payload than it claimed.
|
|
328
|
+
*
|
|
329
|
+
* 3. **Smart-wallet equality check** between `payload.signerAddress`
|
|
330
|
+
* and `payload.requesterAddress`. The recovered EOA may be the
|
|
331
|
+
* controller of a Smart Wallet contract whose address is the
|
|
332
|
+
* `requesterAddress`. Use the SDK's `computeSmartWalletFromSigner`
|
|
333
|
+
* helper (or the platform-side equivalent) to derive the Smart
|
|
334
|
+
* Wallet address and compare.
|
|
335
|
+
*
|
|
336
|
+
* @param payload - The signed projection (NOT the wire envelope).
|
|
337
|
+
* @param signature - Hex-encoded EIP-712 signature, 0x-prefixed.
|
|
338
|
+
* @param kernelAddress - Kernel address to anchor the EIP-712 domain
|
|
339
|
+
* to. SHOULD equal `payload.kernelAddress`; passing them separately
|
|
340
|
+
* here forces the caller to think about the allowlist.
|
|
341
|
+
* @returns The recovered EOA address (checksummed).
|
|
342
|
+
* @throws {DeliveryEip712Error} `INVALID_KERNEL_ADDRESS`,
|
|
343
|
+
* `INVALID_CHAIN_ID`, or `INVALID_SIGNATURE` on bad inputs.
|
|
344
|
+
* @throws {Error} Re-thrown from ethers if the typed-data hash cannot
|
|
345
|
+
* be computed (e.g. malformed payload).
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```typescript
|
|
349
|
+
* const recovered = recoverSetupSigner(payload, sig, KERNEL);
|
|
350
|
+
* if (recovered.toLowerCase() !== payload.signerAddress.toLowerCase()) {
|
|
351
|
+
* throw new Error('signer_self_mismatch');
|
|
352
|
+
* }
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
function recoverSetupSigner(payload, signature, kernelAddress) {
|
|
356
|
+
assertSignatureShape(signature);
|
|
357
|
+
const domain = buildDeliveryDomain(payload.chainId, kernelAddress);
|
|
358
|
+
// H4 fix: smartWalletNonce is OPTIONAL on the TS interface for backwards
|
|
359
|
+
// compatibility with pre-H4 fixtures. Normalize undefined → 0 before
|
|
360
|
+
// recovery so ethers always sees a complete typed-data structure.
|
|
361
|
+
const normalized = {
|
|
362
|
+
...payload,
|
|
363
|
+
smartWalletNonce: payload.smartWalletNonce ?? 0,
|
|
364
|
+
};
|
|
365
|
+
return ethers_1.ethers.verifyTypedData(domain, exports.DELIVERY_SETUP_TYPES_V1, normalized, signature);
|
|
366
|
+
}
|
|
367
|
+
exports.recoverSetupSigner = recoverSetupSigner;
|
|
368
|
+
/**
|
|
369
|
+
* Recover the EOA that produced a {@link DeliveryEnvelopeSignedV1}
|
|
370
|
+
* signature.
|
|
371
|
+
*
|
|
372
|
+
* See {@link recoverSetupSigner} — same shape, same caller
|
|
373
|
+
* responsibilities (allowlist kernel, compare recovered to
|
|
374
|
+
* `payload.signerAddress`, smart-wallet equality between
|
|
375
|
+
* `signerAddress` and `providerAddress`).
|
|
376
|
+
*
|
|
377
|
+
* @param payload - The signed projection (NOT the wire envelope).
|
|
378
|
+
* @param signature - Hex-encoded EIP-712 signature, 0x-prefixed.
|
|
379
|
+
* @param kernelAddress - Kernel address to anchor the EIP-712 domain.
|
|
380
|
+
* @returns The recovered EOA address (checksummed).
|
|
381
|
+
* @throws {DeliveryEip712Error} `INVALID_KERNEL_ADDRESS`,
|
|
382
|
+
* `INVALID_CHAIN_ID`, or `INVALID_SIGNATURE` on bad inputs.
|
|
383
|
+
*/
|
|
384
|
+
function recoverEnvelopeSigner(payload, signature, kernelAddress) {
|
|
385
|
+
assertSignatureShape(signature);
|
|
386
|
+
const domain = buildDeliveryDomain(payload.chainId, kernelAddress);
|
|
387
|
+
// H4 fix: smartWalletNonce is OPTIONAL on the TS interface for backwards
|
|
388
|
+
// compatibility with pre-H4 fixtures. Normalize undefined → 0 before
|
|
389
|
+
// recovery so ethers always sees a complete typed-data structure.
|
|
390
|
+
const normalized = {
|
|
391
|
+
...payload,
|
|
392
|
+
smartWalletNonce: payload.smartWalletNonce ?? 0,
|
|
393
|
+
};
|
|
394
|
+
return ethers_1.ethers.verifyTypedData(domain, exports.DELIVERY_ENVELOPE_TYPES_V1, normalized, signature);
|
|
395
|
+
}
|
|
396
|
+
exports.recoverEnvelopeSigner = recoverEnvelopeSigner;
|
|
397
|
+
//# sourceMappingURL=eip712.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip712.js","sourceRoot":"","sources":["../../src/delivery/eip712.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;;;AAEH,mCAAqD;AAQrD,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;;GAOG;AACU,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAExD;;;;;;GAMG;AACU,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAE3C,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAC/E,EAAE;AACF,oBAAoB;AACpB,oBAAoB;AACpB,wDAAwD;AACxD,sEAAsE;AACtE,kEAAkE;AAClE,qEAAqE;AACrE,qEAAqE;AACrE,mEAAmE;AACnE,gEAAgE;AAChE,iBAAiB;AACjB,EAAE;AACF,+CAA+C;AAC/C,mEAAmE;AACnE,kDAAkD;AAClD,EAAE;AAEF;;;;;GAKG;AACU,QAAA,uBAAuB,GAAqC;IACvE,qBAAqB,EAAE;QACrB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE;QAClC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;QACjC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1C,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE;QAC7C,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1C,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,SAAS,EAAE;QACjD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU,EAAE;QAC9C,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3C,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,iEAAiE;QACjE,mEAAmE;QACnE,yDAAyD;QACzD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE;KAC9C;CACF,CAAC;AAEF;;;;;;;;;;GAUG;AACU,QAAA,0BAA0B,GAAqC;IAC1E,wBAAwB,EAAE;QACxB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE;QAClC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;QACjC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1C,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,SAAS,EAAE;QAC5C,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;QAClC,EAAE,IAAI,EAAE,yBAAyB,EAAE,IAAI,EAAE,SAAS,EAAE;QACpD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;QAClC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;QACxC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE;QAChC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,iEAAiE;QACjE,mEAAmE;QACnE,yDAAyD;QACzD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE;KAC9C;CACF,CAAC;AAEF,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAM5C,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiC;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,uEAAuE;QACvE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAdD,kDAcC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,iBAAiB,CAAC,OAAwB;IACxD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,cAAc;YACjB,OAAO,KAAK,CAAC;QACf,KAAK,cAAc;YACjB,OAAO,IAAI,CAAC;QACd,KAAK,MAAM;YACT,MAAM,IAAI,mBAAmB,CAC3B,4BAA4B,EAC5B,oEAAoE;gBAClE,mEAAmE;gBACnE,oBAAoB,EACtB,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,OAAO,CAAC,CAAC,CAAC;YACR,mEAAmE;YACnE,+DAA+D;YAC/D,wCAAwC;YACxC,MAAM,UAAU,GAAU,OAAO,CAAC;YAClC,MAAM,IAAI,mBAAmB,CAC3B,iBAAiB,EACjB,6BAA6B,MAAM,CAAC,UAAU,CAAC,EAAE,EACjD,EAAE,OAAO,EAAE,UAAU,EAAE,CACxB,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AA1BD,8CA0BC;AAED,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,mBAAmB,CACjC,OAAe,EACf,aAAqB;IAOrB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,mBAAmB,CAC3B,kBAAkB,EAClB,2CAA2C,MAAM,CAAC,OAAO,CAAC,EAAE,EAC5D,EAAE,OAAO,EAAE,CACZ,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,eAAM,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,mBAAmB,CAC3B,wBAAwB,EACxB,kDAAkD,MAAM,CAAC,aAAa,CAAC,EAAE,EACzE,EAAE,aAAa,EAAE,CAClB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,4BAAoB;QAC1B,OAAO,EAAE,+BAAuB;QAChC,OAAO;QACP,iBAAiB,EAAE,aAAa;KACjC,CAAC;AACJ,CAAC;AA/BD,kDA+BC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,SAAiB;IAC7C,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,mBAAmB,CAC3B,mBAAmB,EACnB,0CAA0C,EAC1C,EAAE,SAAS,EAAE,CACd,CAAC;IACJ,CAAC;IACD,gFAAgF;IAChF,mFAAmF;IACnF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,mBAAmB,CAC3B,mBAAmB,EACnB,wCAAwC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EACjE,EAAE,SAAS,EAAE,CACd,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACrC,MAAM,IAAI,mBAAmB,CAC3B,mBAAmB,EACnB,mCAAmC,MAAM,kCAAkC,EAC3E,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,CACjC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,SAAgB,kBAAkB,CAChC,OAA8B,EAC9B,SAAiB,EACjB,aAAqB;IAErB,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACnE,yEAAyE;IACzE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,UAAU,GAA0B;QACxC,GAAG,OAAO;QACV,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,CAAC;KAChD,CAAC;IACF,OAAO,eAAM,CAAC,eAAe,CAC3B,MAAM,EACN,+BAAuB,EACvB,UAAU,EACV,SAAS,CACV,CAAC;AACJ,CAAC;AApBD,gDAoBC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,qBAAqB,CACnC,OAAiC,EACjC,SAAiB,EACjB,aAAqB;IAErB,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACnE,yEAAyE;IACzE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,UAAU,GAA6B;QAC3C,GAAG,OAAO;QACV,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,CAAC;KAChD,CAAC;IACF,OAAO,eAAM,CAAC,eAAe,CAC3B,MAAM,EACN,kCAA0B,EAC1B,UAAU,EACV,SAAS,CACV,CAAC;AACJ,CAAC;AApBD,sDAoBC"}
|