@agenticprimitives/contracts 1.0.0-alpha.26 → 1.0.0-alpha.27
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/abi/AgentAccount.json +82 -0
- package/dist/abi/CustodyPolicy.json +24 -0
- package/dist/abi/EstateProjectionRegistry.json +293 -0
- package/dist/abi/IApprovedHashRegistryWrite.json +35 -0
- package/dist/abi/PayloadClassesEnforcer.json +117 -0
- package/dist/abi/TreasurySpendPolicy.json +369 -0
- package/dist/abi/index.d.ts +4 -0
- package/dist/abi/index.js +4 -0
- package/package.json +1 -1
- package/src/AgentAccount.sol +70 -1
- package/src/IAgentAccount.sol +23 -0
- package/src/custody/CustodyPolicy.sol +52 -2
- package/src/custody/TreasurySpendPolicy.sol +166 -0
- package/src/enforcers/PayloadClassesEnforcer.sol +30 -0
- package/src/registry/EstateProjectionRegistry.sol +109 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "function",
|
|
4
|
+
"name": "budget",
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "account",
|
|
8
|
+
"type": "address",
|
|
9
|
+
"internalType": "address"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"outputs": [
|
|
13
|
+
{
|
|
14
|
+
"name": "asset",
|
|
15
|
+
"type": "address",
|
|
16
|
+
"internalType": "address"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "ceiling",
|
|
20
|
+
"type": "uint256",
|
|
21
|
+
"internalType": "uint256"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "windowSeconds",
|
|
25
|
+
"type": "uint64",
|
|
26
|
+
"internalType": "uint64"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "windowStart",
|
|
30
|
+
"type": "uint64",
|
|
31
|
+
"internalType": "uint64"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "windowIndex",
|
|
35
|
+
"type": "uint64",
|
|
36
|
+
"internalType": "uint64"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "spent",
|
|
40
|
+
"type": "uint256",
|
|
41
|
+
"internalType": "uint256"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "installed",
|
|
45
|
+
"type": "bool",
|
|
46
|
+
"internalType": "bool"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"stateMutability": "view"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "function",
|
|
53
|
+
"name": "decodeBatch",
|
|
54
|
+
"inputs": [
|
|
55
|
+
{
|
|
56
|
+
"name": "msgData",
|
|
57
|
+
"type": "bytes",
|
|
58
|
+
"internalType": "bytes"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"outputs": [
|
|
62
|
+
{
|
|
63
|
+
"name": "",
|
|
64
|
+
"type": "tuple[]",
|
|
65
|
+
"internalType": "struct TreasurySpendPolicy.Call[]",
|
|
66
|
+
"components": [
|
|
67
|
+
{
|
|
68
|
+
"name": "target",
|
|
69
|
+
"type": "address",
|
|
70
|
+
"internalType": "address"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "value",
|
|
74
|
+
"type": "uint256",
|
|
75
|
+
"internalType": "uint256"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "data",
|
|
79
|
+
"type": "bytes",
|
|
80
|
+
"internalType": "bytes"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"stateMutability": "pure"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "function",
|
|
89
|
+
"name": "decodeSingle",
|
|
90
|
+
"inputs": [
|
|
91
|
+
{
|
|
92
|
+
"name": "msgData",
|
|
93
|
+
"type": "bytes",
|
|
94
|
+
"internalType": "bytes"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"outputs": [
|
|
98
|
+
{
|
|
99
|
+
"name": "",
|
|
100
|
+
"type": "address",
|
|
101
|
+
"internalType": "address"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "",
|
|
105
|
+
"type": "uint256",
|
|
106
|
+
"internalType": "uint256"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "",
|
|
110
|
+
"type": "bytes",
|
|
111
|
+
"internalType": "bytes"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"stateMutability": "pure"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "function",
|
|
118
|
+
"name": "isModuleType",
|
|
119
|
+
"inputs": [
|
|
120
|
+
{
|
|
121
|
+
"name": "moduleTypeId",
|
|
122
|
+
"type": "uint256",
|
|
123
|
+
"internalType": "uint256"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"outputs": [
|
|
127
|
+
{
|
|
128
|
+
"name": "",
|
|
129
|
+
"type": "bool",
|
|
130
|
+
"internalType": "bool"
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"stateMutability": "pure"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": "function",
|
|
137
|
+
"name": "moduleId",
|
|
138
|
+
"inputs": [],
|
|
139
|
+
"outputs": [
|
|
140
|
+
{
|
|
141
|
+
"name": "",
|
|
142
|
+
"type": "string",
|
|
143
|
+
"internalType": "string"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"stateMutability": "pure"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"type": "function",
|
|
150
|
+
"name": "onInstall",
|
|
151
|
+
"inputs": [
|
|
152
|
+
{
|
|
153
|
+
"name": "initData",
|
|
154
|
+
"type": "bytes",
|
|
155
|
+
"internalType": "bytes"
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"outputs": [],
|
|
159
|
+
"stateMutability": "nonpayable"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"type": "function",
|
|
163
|
+
"name": "onUninstall",
|
|
164
|
+
"inputs": [
|
|
165
|
+
{
|
|
166
|
+
"name": "",
|
|
167
|
+
"type": "bytes",
|
|
168
|
+
"internalType": "bytes"
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
"outputs": [],
|
|
172
|
+
"stateMutability": "nonpayable"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"type": "function",
|
|
176
|
+
"name": "postCheck",
|
|
177
|
+
"inputs": [
|
|
178
|
+
{
|
|
179
|
+
"name": "",
|
|
180
|
+
"type": "bytes",
|
|
181
|
+
"internalType": "bytes"
|
|
182
|
+
}
|
|
183
|
+
],
|
|
184
|
+
"outputs": [],
|
|
185
|
+
"stateMutability": "nonpayable"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"type": "function",
|
|
189
|
+
"name": "preCheck",
|
|
190
|
+
"inputs": [
|
|
191
|
+
{
|
|
192
|
+
"name": "",
|
|
193
|
+
"type": "address",
|
|
194
|
+
"internalType": "address"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"name": "",
|
|
198
|
+
"type": "uint256",
|
|
199
|
+
"internalType": "uint256"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "msgData",
|
|
203
|
+
"type": "bytes",
|
|
204
|
+
"internalType": "bytes"
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"outputs": [
|
|
208
|
+
{
|
|
209
|
+
"name": "",
|
|
210
|
+
"type": "bytes",
|
|
211
|
+
"internalType": "bytes"
|
|
212
|
+
}
|
|
213
|
+
],
|
|
214
|
+
"stateMutability": "nonpayable"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "function",
|
|
218
|
+
"name": "remaining",
|
|
219
|
+
"inputs": [
|
|
220
|
+
{
|
|
221
|
+
"name": "account",
|
|
222
|
+
"type": "address",
|
|
223
|
+
"internalType": "address"
|
|
224
|
+
}
|
|
225
|
+
],
|
|
226
|
+
"outputs": [
|
|
227
|
+
{
|
|
228
|
+
"name": "left",
|
|
229
|
+
"type": "uint256",
|
|
230
|
+
"internalType": "uint256"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"name": "ceiling",
|
|
234
|
+
"type": "uint256",
|
|
235
|
+
"internalType": "uint256"
|
|
236
|
+
}
|
|
237
|
+
],
|
|
238
|
+
"stateMutability": "view"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"type": "event",
|
|
242
|
+
"name": "BudgetInstalled",
|
|
243
|
+
"inputs": [
|
|
244
|
+
{
|
|
245
|
+
"name": "account",
|
|
246
|
+
"type": "address",
|
|
247
|
+
"indexed": true,
|
|
248
|
+
"internalType": "address"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"name": "asset",
|
|
252
|
+
"type": "address",
|
|
253
|
+
"indexed": true,
|
|
254
|
+
"internalType": "address"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"name": "ceiling",
|
|
258
|
+
"type": "uint256",
|
|
259
|
+
"indexed": false,
|
|
260
|
+
"internalType": "uint256"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"name": "windowSeconds",
|
|
264
|
+
"type": "uint64",
|
|
265
|
+
"indexed": false,
|
|
266
|
+
"internalType": "uint64"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"name": "windowStart",
|
|
270
|
+
"type": "uint64",
|
|
271
|
+
"indexed": false,
|
|
272
|
+
"internalType": "uint64"
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
"anonymous": false
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"type": "event",
|
|
279
|
+
"name": "BudgetUninstalled",
|
|
280
|
+
"inputs": [
|
|
281
|
+
{
|
|
282
|
+
"name": "account",
|
|
283
|
+
"type": "address",
|
|
284
|
+
"indexed": true,
|
|
285
|
+
"internalType": "address"
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
"anonymous": false
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"type": "event",
|
|
292
|
+
"name": "Spent",
|
|
293
|
+
"inputs": [
|
|
294
|
+
{
|
|
295
|
+
"name": "account",
|
|
296
|
+
"type": "address",
|
|
297
|
+
"indexed": true,
|
|
298
|
+
"internalType": "address"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"name": "windowIndex",
|
|
302
|
+
"type": "uint64",
|
|
303
|
+
"indexed": true,
|
|
304
|
+
"internalType": "uint64"
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"name": "amount",
|
|
308
|
+
"type": "uint256",
|
|
309
|
+
"indexed": false,
|
|
310
|
+
"internalType": "uint256"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"name": "spentInWindow",
|
|
314
|
+
"type": "uint256",
|
|
315
|
+
"indexed": false,
|
|
316
|
+
"internalType": "uint256"
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
"anonymous": false
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"type": "error",
|
|
323
|
+
"name": "AlreadyInstalledOn",
|
|
324
|
+
"inputs": [
|
|
325
|
+
{
|
|
326
|
+
"name": "account",
|
|
327
|
+
"type": "address",
|
|
328
|
+
"internalType": "address"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"type": "error",
|
|
334
|
+
"name": "BadBudget",
|
|
335
|
+
"inputs": []
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"type": "error",
|
|
339
|
+
"name": "BudgetExceeded",
|
|
340
|
+
"inputs": [
|
|
341
|
+
{
|
|
342
|
+
"name": "ceiling",
|
|
343
|
+
"type": "uint256",
|
|
344
|
+
"internalType": "uint256"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"name": "spentInWindow",
|
|
348
|
+
"type": "uint256",
|
|
349
|
+
"internalType": "uint256"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"name": "amount",
|
|
353
|
+
"type": "uint256",
|
|
354
|
+
"internalType": "uint256"
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"type": "error",
|
|
360
|
+
"name": "NotInstalledOn",
|
|
361
|
+
"inputs": [
|
|
362
|
+
{
|
|
363
|
+
"name": "account",
|
|
364
|
+
"type": "address",
|
|
365
|
+
"internalType": "address"
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
}
|
|
369
|
+
]
|
package/dist/abi/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare const CaveatEnforcerBase: Abi;
|
|
|
24
24
|
export declare const CustodyPolicy: Abi;
|
|
25
25
|
export declare const DelegationManager: Abi;
|
|
26
26
|
export declare const DigestBindingEnforcer: Abi;
|
|
27
|
+
export declare const EstateProjectionRegistry: Abi;
|
|
27
28
|
export declare const GeoFeatureRegistry: Abi;
|
|
28
29
|
export declare const GovernanceManaged: Abi;
|
|
29
30
|
export declare const IAgentAccount: Abi;
|
|
@@ -32,6 +33,7 @@ export declare const IAgentAccountFactoryView: Abi;
|
|
|
32
33
|
export declare const IAgentAccountPauseView: Abi;
|
|
33
34
|
export declare const IAgenticPrimitivesAgentAccount: Abi;
|
|
34
35
|
export declare const IApprovedHashRegistryView: Abi;
|
|
36
|
+
export declare const IApprovedHashRegistryWrite: Abi;
|
|
35
37
|
export declare const IAttributeReader: Abi;
|
|
36
38
|
export declare const ICaveatEnforcer: Abi;
|
|
37
39
|
export declare const ICustodyPolicyAccountModuleView: Abi;
|
|
@@ -50,6 +52,7 @@ export declare const MultiSendCallOnly: Abi;
|
|
|
50
52
|
export declare const MultiSendCallOnlyHarness: Abi;
|
|
51
53
|
export declare const OntologyTermRegistry: Abi;
|
|
52
54
|
export declare const P256Verifier: Abi;
|
|
55
|
+
export declare const PayloadClassesEnforcer: Abi;
|
|
53
56
|
export declare const PaymentEnforcer: Abi;
|
|
54
57
|
export declare const PaymentEscrow: Abi;
|
|
55
58
|
export declare const PaymentReceiptRegistry: Abi;
|
|
@@ -63,6 +66,7 @@ export declare const SkillDefinitionRegistry: Abi;
|
|
|
63
66
|
export declare const SmartAgentModuleTypes: Abi;
|
|
64
67
|
export declare const SmartAgentPaymaster: Abi;
|
|
65
68
|
export declare const TimestampEnforcer: Abi;
|
|
69
|
+
export declare const TreasurySpendPolicy: Abi;
|
|
66
70
|
export declare const UniversalSignatureValidator: Abi;
|
|
67
71
|
export declare const ValueEnforcer: Abi;
|
|
68
72
|
export declare const WebAuthnLib: Abi;
|
package/dist/abi/index.js
CHANGED
|
@@ -24,6 +24,7 @@ export { default as CaveatEnforcerBase } from './CaveatEnforcerBase.json' with {
|
|
|
24
24
|
export { default as CustodyPolicy } from './CustodyPolicy.json' with { type: 'json' };
|
|
25
25
|
export { default as DelegationManager } from './DelegationManager.json' with { type: 'json' };
|
|
26
26
|
export { default as DigestBindingEnforcer } from './DigestBindingEnforcer.json' with { type: 'json' };
|
|
27
|
+
export { default as EstateProjectionRegistry } from './EstateProjectionRegistry.json' with { type: 'json' };
|
|
27
28
|
export { default as GeoFeatureRegistry } from './GeoFeatureRegistry.json' with { type: 'json' };
|
|
28
29
|
export { default as GovernanceManaged } from './GovernanceManaged.json' with { type: 'json' };
|
|
29
30
|
export { default as IAgentAccount } from './IAgentAccount.json' with { type: 'json' };
|
|
@@ -32,6 +33,7 @@ export { default as IAgentAccountFactoryView } from './IAgentAccountFactoryView.
|
|
|
32
33
|
export { default as IAgentAccountPauseView } from './IAgentAccountPauseView.json' with { type: 'json' };
|
|
33
34
|
export { default as IAgenticPrimitivesAgentAccount } from './IAgenticPrimitivesAgentAccount.json' with { type: 'json' };
|
|
34
35
|
export { default as IApprovedHashRegistryView } from './IApprovedHashRegistryView.json' with { type: 'json' };
|
|
36
|
+
export { default as IApprovedHashRegistryWrite } from './IApprovedHashRegistryWrite.json' with { type: 'json' };
|
|
35
37
|
export { default as IAttributeReader } from './IAttributeReader.json' with { type: 'json' };
|
|
36
38
|
export { default as ICaveatEnforcer } from './ICaveatEnforcer.json' with { type: 'json' };
|
|
37
39
|
export { default as ICustodyPolicyAccountModuleView } from './ICustodyPolicyAccountModuleView.json' with { type: 'json' };
|
|
@@ -50,6 +52,7 @@ export { default as MultiSendCallOnly } from './MultiSendCallOnly.json' with { t
|
|
|
50
52
|
export { default as MultiSendCallOnlyHarness } from './MultiSendCallOnlyHarness.json' with { type: 'json' };
|
|
51
53
|
export { default as OntologyTermRegistry } from './OntologyTermRegistry.json' with { type: 'json' };
|
|
52
54
|
export { default as P256Verifier } from './P256Verifier.json' with { type: 'json' };
|
|
55
|
+
export { default as PayloadClassesEnforcer } from './PayloadClassesEnforcer.json' with { type: 'json' };
|
|
53
56
|
export { default as PaymentEnforcer } from './PaymentEnforcer.json' with { type: 'json' };
|
|
54
57
|
export { default as PaymentEscrow } from './PaymentEscrow.json' with { type: 'json' };
|
|
55
58
|
export { default as PaymentReceiptRegistry } from './PaymentReceiptRegistry.json' with { type: 'json' };
|
|
@@ -63,6 +66,7 @@ export { default as SkillDefinitionRegistry } from './SkillDefinitionRegistry.js
|
|
|
63
66
|
export { default as SmartAgentModuleTypes } from './SmartAgentModuleTypes.json' with { type: 'json' };
|
|
64
67
|
export { default as SmartAgentPaymaster } from './SmartAgentPaymaster.json' with { type: 'json' };
|
|
65
68
|
export { default as TimestampEnforcer } from './TimestampEnforcer.json' with { type: 'json' };
|
|
69
|
+
export { default as TreasurySpendPolicy } from './TreasurySpendPolicy.json' with { type: 'json' };
|
|
66
70
|
export { default as UniversalSignatureValidator } from './UniversalSignatureValidator.json' with { type: 'json' };
|
|
67
71
|
export { default as ValueEnforcer } from './ValueEnforcer.json' with { type: 'json' };
|
|
68
72
|
export { default as WebAuthnLib } from './WebAuthnLib.json' with { type: 'json' };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agenticprimitives/contracts",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Solidity contracts + ABIs + flattened sources + per-network deployment addresses for the agenticprimitives stack.",
|
|
6
6
|
"homepage": "https://agenticprimitives.dev",
|
package/src/AgentAccount.sol
CHANGED
|
@@ -56,6 +56,16 @@ interface IApprovedHashRegistryView {
|
|
|
56
56
|
function isApproved(address signer, bytes32 hash) external view returns (bool);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/// @dev Spec 410 §1 (THESIS-1a) — the ONLY write path from this account to its registry. The account
|
|
60
|
+
/// computes the epoch-bound key itself (`approveDigest`); `execute` / `executeBatch` /
|
|
61
|
+
/// `executeFromModule` refuse the registry as a target unconditionally, so no caller — custodian,
|
|
62
|
+
/// module or delegate — can approve a key under an epoch the account is not in.
|
|
63
|
+
interface IApprovedHashRegistryWrite {
|
|
64
|
+
function approveHash(bytes32 hash) external;
|
|
65
|
+
function revokeHash(bytes32 hash) external;
|
|
66
|
+
function revokeAll() external;
|
|
67
|
+
}
|
|
68
|
+
|
|
59
69
|
/**
|
|
60
70
|
* @title AgentAccount
|
|
61
71
|
* @notice ERC-4337 + UUPS-upgradeable smart account — agent identity anchor.
|
|
@@ -268,6 +278,9 @@ contract AgentAccount is
|
|
|
268
278
|
/// @notice A delegation-originated execution stack tried to self-call an
|
|
269
279
|
/// account-governance selector. Delegations may never reach governance.
|
|
270
280
|
error DelegatedGovernanceForbidden();
|
|
281
|
+
/// @dev Spec 410 §1 (THESIS-1a): the approved-hash registry is reachable only through
|
|
282
|
+
/// `approveDigest` / `revokeDigest` / `revokeAllApprovedDigests`, never as an execute target.
|
|
283
|
+
error ApprovedHashRegistryOnlyViaAccount();
|
|
271
284
|
|
|
272
285
|
/// @notice Emitted when `setDelegationManager` rotates the DM via a
|
|
273
286
|
/// self-call (the only authorized path post-Wave-2A).
|
|
@@ -1057,6 +1070,7 @@ contract AgentAccount is
|
|
|
1057
1070
|
revert NotInstalledExecutor(msg.sender);
|
|
1058
1071
|
}
|
|
1059
1072
|
emit ModuleExecuted(msg.sender, target, value);
|
|
1073
|
+
_rejectDirectRegistryCall(target);
|
|
1060
1074
|
// CA-1 + Wave-1/ACCT-C1 (spec 300): a module action from the CANONICAL CustodyPolicy is a
|
|
1061
1075
|
// custody-governed context (gated upstream by its own T5 quorum + timelock). `_custodyGovCtx`
|
|
1062
1076
|
// authorizes every governance mutator this call dispatches (the ONLY way past
|
|
@@ -1146,6 +1160,7 @@ contract AgentAccount is
|
|
|
1146
1160
|
// executeBatch(...)) nest) and forbid it from self-calling governance.
|
|
1147
1161
|
bool setDelCtx = (msg.sender == _delegationManager && !_delegationExecCtx);
|
|
1148
1162
|
if (setDelCtx) _delegationExecCtx = true;
|
|
1163
|
+
_rejectDirectRegistryCall(target);
|
|
1149
1164
|
_rejectDelegatedGovernance(target, data);
|
|
1150
1165
|
|
|
1151
1166
|
ModulesStorage storage $ = _modulesStorage();
|
|
@@ -1232,6 +1247,7 @@ contract AgentAccount is
|
|
|
1232
1247
|
}
|
|
1233
1248
|
|
|
1234
1249
|
for (uint256 i = 0; i < calls.length; i++) {
|
|
1250
|
+
_rejectDirectRegistryCall(calls[i].target);
|
|
1235
1251
|
_rejectDelegatedGovernance(calls[i].target, calls[i].data);
|
|
1236
1252
|
(bool ok, bytes memory ret) = calls[i].target.call{ value: calls[i].value }(calls[i].data);
|
|
1237
1253
|
if (!ok) {
|
|
@@ -1328,6 +1344,16 @@ contract AgentAccount is
|
|
|
1328
1344
|
if (_isAccountTrustedTarget(target)) revert DelegatedGovernanceForbidden();
|
|
1329
1345
|
}
|
|
1330
1346
|
|
|
1347
|
+
/// @dev Spec 410 §1 (THESIS-1a). `ApprovedHashRegistry.approveHash` stores whatever 32 bytes the account
|
|
1348
|
+
/// sends, and the custody epoch is public — so a custodian who could reach the registry through
|
|
1349
|
+
/// `execute` could approve `keccak256(abi.encode(h, epoch + 1))`: inert now, live the moment a
|
|
1350
|
+
/// recovery bumps the epoch to expel that very custodian. Closing it: the registry is never an
|
|
1351
|
+
/// execute target; the account derives the key on chain in `approveDigest`, under the epoch it is
|
|
1352
|
+
/// in, and nowhere else. Unconditional — not only under the delegation context (R917-C-1/C-2).
|
|
1353
|
+
function _rejectDirectRegistryCall(address target) internal view {
|
|
1354
|
+
if (target == _approvedHashRegistry && target != address(0)) revert ApprovedHashRegistryOnlyViaAccount();
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1331
1357
|
/// @dev The contracts that take THIS ACCOUNT as principal when it is `msg.sender` — reachable only from
|
|
1332
1358
|
/// the account's own governance paths (`uninstallModule`, a custodian-signed userOp), never from a
|
|
1333
1359
|
/// delegation. The custody policy is read from the factory (the canonical one; a legacy direct
|
|
@@ -1357,7 +1383,10 @@ contract AgentAccount is
|
|
|
1357
1383
|
s == IAgentAccount.removeCustodian.selector ||
|
|
1358
1384
|
s == this.addPasskey.selector ||
|
|
1359
1385
|
s == this.removePasskey.selector ||
|
|
1360
|
-
s == this.acceptSessionDelegation.selector
|
|
1386
|
+
s == this.acceptSessionDelegation.selector ||
|
|
1387
|
+
s == this.approveDigest.selector ||
|
|
1388
|
+
s == this.revokeDigest.selector ||
|
|
1389
|
+
s == this.revokeAllApprovedDigests.selector;
|
|
1361
1390
|
}
|
|
1362
1391
|
|
|
1363
1392
|
// ─── ERC-1271 ───────────────────────────────────────────────────
|
|
@@ -1697,6 +1726,11 @@ contract AgentAccount is
|
|
|
1697
1726
|
event PasskeyRemoved(bytes32 indexed credentialIdDigest);
|
|
1698
1727
|
/// @dev R917-C-2 — a credential was retired; every approved hash keyed to the previous epoch is void.
|
|
1699
1728
|
event CustodyEpochBumped(uint64 epoch);
|
|
1729
|
+
/// @dev Spec 410 §1 — `digest` approved under `epoch` through the account's own key derivation.
|
|
1730
|
+
event DigestApproved(bytes32 indexed digest, uint64 epoch);
|
|
1731
|
+
event DigestRevoked(bytes32 indexed digest, uint64 epoch);
|
|
1732
|
+
/// @dev Spec 410 §1 — every approval this account ever made is void (registry-side epoch bump).
|
|
1733
|
+
event AllDigestsRevoked();
|
|
1700
1734
|
|
|
1701
1735
|
/// @notice Register a new WebAuthn credential bound to a specific RP.
|
|
1702
1736
|
/// `onlySelf` — callable via a UserOp signed by any existing signer
|
|
@@ -1802,6 +1836,41 @@ contract AgentAccount is
|
|
|
1802
1836
|
emit CustodyEpochBumped(next);
|
|
1803
1837
|
}
|
|
1804
1838
|
|
|
1839
|
+
// ─── Approved digests (spec 410 §1, THESIS-1a) ───────────────────
|
|
1840
|
+
|
|
1841
|
+
/// @notice Approve `digest` for this account's `0x03` sentinel under the epoch the account is IN. The
|
|
1842
|
+
/// only path to the registry (`execute` refuses it as a target), so the key is never computed
|
|
1843
|
+
/// by a caller and never for an epoch other than the current one. `onlySelf`, not
|
|
1844
|
+
/// custody-gated: spec 253's one-prompt org-create batches it into the deploy userOp under the
|
|
1845
|
+
/// creating custodian, and the epoch (R917-C-2) plus `revokeAllApprovedDigests` on every
|
|
1846
|
+
/// recovery path (spec 410 §1.2) close the persistence risk instead. A delegation stack cannot
|
|
1847
|
+
/// reach it (`_isGovernanceSelector`).
|
|
1848
|
+
function approveDigest(bytes32 digest) external onlySelf {
|
|
1849
|
+
if (_approvedHashRegistry == address(0)) revert ApprovedHashRegistryOnlyViaAccount();
|
|
1850
|
+
IApprovedHashRegistryWrite(_approvedHashRegistry).approveHash(approvedHashKey(digest));
|
|
1851
|
+
emit DigestApproved(digest, _custodyEpoch);
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
/// @notice Revoke one approval made under the current epoch.
|
|
1855
|
+
function revokeDigest(bytes32 digest) external onlySelf {
|
|
1856
|
+
if (_approvedHashRegistry == address(0)) revert ApprovedHashRegistryOnlyViaAccount();
|
|
1857
|
+
IApprovedHashRegistryWrite(_approvedHashRegistry).revokeHash(approvedHashKey(digest));
|
|
1858
|
+
emit DigestRevoked(digest, _custodyEpoch);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
/// @notice Void EVERY approval this account ever made, under any epoch — including one planted for a
|
|
1862
|
+
/// future epoch before this contract generation refused direct registry calls. `CustodyPolicy`
|
|
1863
|
+
/// calls it as the last step of every recovery path; a custody-governed account reaches it
|
|
1864
|
+
/// only through the module (`_requireCustodyGoverned`), a mode-0 person through her own userOp.
|
|
1865
|
+
/// Recovery re-approves nothing: the person re-issues from a reviewed list (spec 410 §1.2).
|
|
1866
|
+
function revokeAllApprovedDigests() external onlySelf {
|
|
1867
|
+
_requireCustodyGoverned();
|
|
1868
|
+
// No registry wired: nothing was ever approvable (the sentinel fails closed, l. ~1388), so there is
|
|
1869
|
+
// nothing to void — a no-op, never a revert, so a recovery on such an account still completes.
|
|
1870
|
+
if (_approvedHashRegistry != address(0)) IApprovedHashRegistryWrite(_approvedHashRegistry).revokeAll();
|
|
1871
|
+
emit AllDigestsRevoked();
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1805
1874
|
// ─── Custody policy + scheduled changes ───────────────────────────
|
|
1806
1875
|
//
|
|
1807
1876
|
// The schedule / apply / cancel custody-change surface, CustodyAction
|
package/src/IAgentAccount.sol
CHANGED
|
@@ -90,6 +90,29 @@ struct AgentAccountRecoveryArgs {
|
|
|
90
90
|
bytes32[] removePasskeyCredentialIdDigests;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @notice Payload for `CustodyAction.RotateCredential` (T4) — spec 410 §1.2. A PLANNED rotation: the
|
|
95
|
+
* old credential is still controlled, the person (or an org's quorum) registers the new one,
|
|
96
|
+
* retires the old one, and re-approves every standing approved-digest wire under the new epoch
|
|
97
|
+
* — in ONE applied change, so no wire is dead between the retirement and the re-approval.
|
|
98
|
+
*
|
|
99
|
+
* Exactly one credential is added (`addOwner` XOR `addPasskey.x != 0`) and exactly one retired
|
|
100
|
+
* (`removeOwner` XOR `removePasskeyCredentialIdDigest != 0`). `reapprove` lists the delegation
|
|
101
|
+
* digests to approve after the retirement; the module calls `AgentAccount.approveDigest` for
|
|
102
|
+
* each, so the key is derived on chain under the post-rotation epoch.
|
|
103
|
+
*
|
|
104
|
+
* This is the ONLY custody action that carries a re-approval list. `AgentAccountRecoveryArgs`
|
|
105
|
+
* has no such field by construction: a recovery is the moment a planted grant would otherwise
|
|
106
|
+
* ride through, so recovery re-approves nothing and ends with `revokeAllApprovedDigests`.
|
|
107
|
+
*/
|
|
108
|
+
struct AgentAccountRotateCredentialArgs {
|
|
109
|
+
address addOwner;
|
|
110
|
+
AgentAccountRecoveryPasskeyAdd addPasskey;
|
|
111
|
+
address removeOwner;
|
|
112
|
+
bytes32 removePasskeyCredentialIdDigest;
|
|
113
|
+
bytes32[] reapprove;
|
|
114
|
+
}
|
|
115
|
+
|
|
93
116
|
/**
|
|
94
117
|
* @title IAgentAccount
|
|
95
118
|
* @notice Interface for an agent-native ERC-4337 smart account.
|