You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/adr/ADR-0003-typed-transactions-sponsorship.md
+48-1Lines changed: 48 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -125,6 +125,53 @@ Operational constraints:
125
125
* Intrinsic gas MUST be computed over **all** calls in the batch (calldata, cold access per call, CREATE cost, and any signature-related costs).
126
126
* If any call fails, all state changes from previous calls in the batch MUST be reverted.
127
127
128
+
## Sponsorship Flow (Genesis → Sponsor Signature)
129
+
130
+
This section describes an end-to-end flow for creating a sponsored `0x76` transaction, from initial intent to sponsor signing and submission. It complements (but does not replace) the rules in “Signatures and Hashing”.
131
+
132
+
### 0) Pre-conditions / Genesis State
133
+
- The executor has a key pair, nonce space, and required permissions for the calls.
134
+
- The sponsor has funds and is willing to pay gas for the executor’s intent.
135
+
- The protocol does **not** implement an automated fee-paying system; sponsorship is arranged off-chain.
136
+
- A sponsorship service **may** be used to provide fee sponsorship, but for now this is the responsibility of the chain.
137
+
138
+
### 1) Executor Builds the Unsponsored Payload (Intent)
139
+
- The executor constructs `EvNodeTransaction` with:
140
+
-`fee_payer_signature = None`
141
+
- all call data, gas params, and access list
142
+
- The executor signs the **executor signature hash**:
143
+
-`hash_exec = keccak256(0x76 || rlp(payload_fields... with fee_payer_signature = 0x80))`
144
+
- The executor produces `executor_signature` (secp256k1), forming `Signed<EvNodeTransaction>`.
145
+
146
+
### 2) Sponsor-Ready Envelope (Unsigned by Sponsor)
147
+
- The executor shares the payload + executor signature with a sponsor (directly or via a service).
148
+
- The payload is unchanged; `fee_payer_signature` remains empty.
149
+
-**Broadcast readiness:** at this point the tx is valid but **unsponsored** and can be broadcast as a normal executor-paid transaction.
150
+
151
+
### 3) Sponsor Computes the Sponsor Hash
152
+
- The sponsor computes:
153
+
-`hash_sponsor = keccak256(0x78 || rlp(payload_fields... with fee_payer_signature = 0x80))`
154
+
- The sponsor uses the same payload as the executor (no mutation other than the domain byte).
155
+
156
+
### 4) Sponsor Signs and Fills `fee_payer_signature`
157
+
- The sponsor signs `hash_sponsor`**off-chain** (e.g., within the app or via an app-side signing service) and obtains `fee_payer_signature`.
158
+
- The transaction payload is updated:
159
+
-`fee_payer_signature = Some(sponsor_signature)`
160
+
- The sponsor can verify that `recover_fee_payer(hash_sponsor, signature)` returns their address.
161
+
-**Broadcast readiness:** once `fee_payer_signature` is present, the tx is fully sponsored and can be broadcast.
162
+
163
+
### 5) Submission and Validation
164
+
- The fully formed typed tx is:
165
+
-`0x76 || rlp([payload_fields..., v, r, s])` with `fee_payer_signature` included in the payload
166
+
- Validation path:
167
+
- Executor signature verified on domain `0x76`
168
+
- Sponsor signature verified on domain `0x78`
169
+
- Sponsor address recovered from signature and used for fee checks / balance
170
+
171
+
### 6) Execution and Receipt
172
+
- Execution occurs with `tx.origin` = executor.
173
+
- Gas is charged to the recovered sponsor address.
174
+
128
175
## Implementation Strategy
129
176
130
177
We will utilize Reth's `NodeTypes` configuration to wire these primitives without modifying core crates.
@@ -156,7 +203,7 @@ pub enum EvTxEnvelope {
156
203
157
204
***Handler:** Extend `ConfigureEvm` or implement a custom `EvmHandler`.
158
205
***Fee Deduction:** Override the standard fee deduction logic.
159
-
* If `tx.type == 0x76` and `fee_payer` is present, debit the `fee_payer` account in the REVM database.
206
+
* If `tx.type == 0x76` and `fee_payer_signature` is present, debit the **recovered sponsor** account in the REVM database.
160
207
* Otherwise, fallback to standard deduction (debit `caller`).
161
208
***Batch Execution:** Execute `calls` sequentially under an outer checkpoint; revert all state if any call fails.
162
209
***Context:** Map `EvNodeTransaction` to `TxEnv`. Ensure `TxEnv.caller` is always the executor.
0 commit comments