@agenticprimitives/contracts 1.0.0-alpha.16 → 1.0.0-alpha.18
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/deployments-base-sepolia.json +35 -33
- package/dist/abi/AgentAccount.json +20 -19
- package/dist/abi/AgentAccountFactory.json +18 -0
- package/dist/abi/CustodyPolicy.json +6 -6
- package/dist/deployments/base-sepolia.d.ts +4 -1
- package/dist/deployments/base-sepolia.js +36 -33
- package/dist/deployments/registries-base-sepolia.d.ts +1 -0
- package/dist/deployments/registries-base-sepolia.js +2 -1
- package/package.json +1 -1
- package/src/AgentAccount.sol +32 -9
- package/src/AgentAccountFactory.sol +43 -3
- package/src/custody/CustodyPolicy.sol +15 -5
- package/src/enforcers/QuorumEnforcer.sol +4 -1
- package/src/libraries/SignatureSlotRecovery.sol +16 -4
- package/src/naming/AgentNamePredicates.sol +6 -0
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
{
|
|
2
|
-
"agentAccountFactory": "
|
|
3
|
-
"agentAccountImplementation": "
|
|
4
|
-
"agentNameRegistry": "
|
|
5
|
-
"agentNameResolver": "
|
|
6
|
-
"agentNameUniversalResolver": "
|
|
7
|
-
"agentProfileResolver": "
|
|
8
|
-
"agentRelationship": "
|
|
9
|
-
"agreementRegistry": "
|
|
10
|
-
"allowedMethodsEnforcer": "
|
|
11
|
-
"allowedTargetsEnforcer": "
|
|
12
|
-
"approvedHashRegistry": "
|
|
13
|
-
"attestationRegistry": "
|
|
14
|
-
"callDataHashEnforcer": "
|
|
2
|
+
"agentAccountFactory": "0xA9B6e53FcD8DA3658DeD09f4e37b22baA25De715",
|
|
3
|
+
"agentAccountImplementation": "0x97DAC0cC056093B7DBFb4183804EA72f8d89972F",
|
|
4
|
+
"agentNameRegistry": "0x6629Cca40B008C0984a1Ca266Ca10A344420cac3",
|
|
5
|
+
"agentNameResolver": "0xA15B0703716DC8634B74F97723618f74Af3AaA73",
|
|
6
|
+
"agentNameUniversalResolver": "0xB890060dE1B3Fd2C78e1f0859da3883743eAD452",
|
|
7
|
+
"agentProfileResolver": "0xfcd37F8dca26ead889922b22C169c21370bd352a",
|
|
8
|
+
"agentRelationship": "0x0AF2455e3f76594E81d9042aD5FE22A5A35dc57f",
|
|
9
|
+
"agreementRegistry": "0xa62c888595Cd3A645e340EA7768B53b4fC257DF5",
|
|
10
|
+
"allowedMethodsEnforcer": "0xa076b759D6785bA5E67016e399Af651fC2ABC811",
|
|
11
|
+
"allowedTargetsEnforcer": "0xb06252FaD1D41B9943c73ec696Af70F268581625",
|
|
12
|
+
"approvedHashRegistry": "0x465f8DCE65aB51A1562CC60E6bc046ca8734D537",
|
|
13
|
+
"attestationRegistry": "0xD57f2e52395b9C99fAE8Abf823578faFe038f5B7",
|
|
14
|
+
"callDataHashEnforcer": "0xA614d6E5ECebc308b4e0bABDC7c832da059bb132",
|
|
15
15
|
"chainId": 84532,
|
|
16
|
-
"custodyPolicy": "
|
|
17
|
-
"delegationManager": "
|
|
16
|
+
"custodyPolicy": "0x5DB542eeBa652372afE6B4b0Cd40D999e65846de",
|
|
17
|
+
"delegationManager": "0x9eD1dC0FD2284fcd4967beeF3317129fee7a92e5",
|
|
18
18
|
"deployer": "0x31ed17fb99e82E02085Ab4B3cbdaB05489098b44",
|
|
19
|
-
"entryPoint": "
|
|
20
|
-
"geoFeatureRegistry": "
|
|
21
|
-
"mockUsdc": "
|
|
22
|
-
"ontologyTermRegistry": "
|
|
23
|
-
"paymentEnforcer": "
|
|
24
|
-
"paymentReceiptRegistry": "
|
|
25
|
-
"permissionlessSubregistry": "
|
|
26
|
-
"permissionlessSubregistryDemoAgent": "
|
|
27
|
-
"quorumEnforcer": "
|
|
28
|
-
"relationshipTypeRegistry": "
|
|
29
|
-
"shapeRegistry": "
|
|
30
|
-
"skillDefinitionRegistry": "
|
|
31
|
-
"smartAgentPaymaster": "
|
|
32
|
-
"timestampEnforcer": "
|
|
33
|
-
"universalSignatureValidator": "
|
|
34
|
-
"valueEnforcer": "
|
|
35
|
-
"agentRegistryBase": "
|
|
36
|
-
"
|
|
19
|
+
"entryPoint": "0x96E37dD695840AF7781E669bdca9d79E4d7d8040",
|
|
20
|
+
"geoFeatureRegistry": "0x7D4F6F5cca1cDb1c72b25c50aB80Fb9629BA800B",
|
|
21
|
+
"mockUsdc": "0x6cfF706bA1461a9ef9F5aaf8f1581301805FbF92",
|
|
22
|
+
"ontologyTermRegistry": "0xC03a64e1492021fEc27f31F066f09Abe28F73e00",
|
|
23
|
+
"paymentEnforcer": "0x4DAc5F8891112D0C34d207FcE5ED78f13cD2b7d8",
|
|
24
|
+
"paymentReceiptRegistry": "0xF659091DDB30D3A608d6f96fAEDB41e966B72433",
|
|
25
|
+
"permissionlessSubregistry": "0x598C7bbAf25f5246BE3D5A75FdEDC180D67D8026",
|
|
26
|
+
"permissionlessSubregistryDemoAgent": "0x571f9F2e12939F2fEDFC431aD6d7323d7483e02B",
|
|
27
|
+
"quorumEnforcer": "0xA4b148EfF1Ff1c116849F6e9D9c0059bC644873F",
|
|
28
|
+
"relationshipTypeRegistry": "0x8991a3ECf1DD41064Aa48DaF15a24B3d6a2811C5",
|
|
29
|
+
"shapeRegistry": "0xdE375012B37820C23272e2A2c9de2A8F6328aFA3",
|
|
30
|
+
"skillDefinitionRegistry": "0x167c8a31d5Fc36558A4eAD0CA96AcA7936a8e5e7",
|
|
31
|
+
"smartAgentPaymaster": "0x3444160e79C463B8F1e10f86Eae4047E22256aD0",
|
|
32
|
+
"timestampEnforcer": "0xBb8fF9c82417189c6EfeBbB369e9dd9d651aa0f3",
|
|
33
|
+
"universalSignatureValidator": "0x3bc65655d4b6fb57731A256fcd47Db2F8Fe36907",
|
|
34
|
+
"valueEnforcer": "0x3D2abD6c7C1319f2bbA96B3b76A7e0d92C620A39",
|
|
35
|
+
"agentRegistryBase": "0xB18534CA9c679968132ca2a43E454f5fA341030D",
|
|
36
|
+
"agenticGovernance": "0x27c1F21ffA275e61Fe152Edd4f2676fD6a816dDa",
|
|
37
|
+
"timelockController": "0xeB66E0B92287E53BB5A80bD2a01002150249DC94",
|
|
38
|
+
"governanceGuardian": "0x31ed17fb99e82E02085Ab4B3cbdaB05489098b44"
|
|
37
39
|
}
|
|
@@ -454,6 +454,25 @@
|
|
|
454
454
|
],
|
|
455
455
|
"stateMutability": "view"
|
|
456
456
|
},
|
|
457
|
+
{
|
|
458
|
+
"type": "function",
|
|
459
|
+
"name": "getPasskeyRpIdHash",
|
|
460
|
+
"inputs": [
|
|
461
|
+
{
|
|
462
|
+
"name": "credentialIdDigest",
|
|
463
|
+
"type": "bytes32",
|
|
464
|
+
"internalType": "bytes32"
|
|
465
|
+
}
|
|
466
|
+
],
|
|
467
|
+
"outputs": [
|
|
468
|
+
{
|
|
469
|
+
"name": "",
|
|
470
|
+
"type": "bytes32",
|
|
471
|
+
"internalType": "bytes32"
|
|
472
|
+
}
|
|
473
|
+
],
|
|
474
|
+
"stateMutability": "view"
|
|
475
|
+
},
|
|
457
476
|
{
|
|
458
477
|
"type": "function",
|
|
459
478
|
"name": "hasAcceptedSessionDelegation",
|
|
@@ -697,7 +716,7 @@
|
|
|
697
716
|
"internalType": "address"
|
|
698
717
|
}
|
|
699
718
|
],
|
|
700
|
-
"stateMutability": "
|
|
719
|
+
"stateMutability": "view"
|
|
701
720
|
},
|
|
702
721
|
{
|
|
703
722
|
"type": "function",
|
|
@@ -1150,24 +1169,6 @@
|
|
|
1150
1169
|
"type": "bytes32",
|
|
1151
1170
|
"indexed": true,
|
|
1152
1171
|
"internalType": "bytes32"
|
|
1153
|
-
},
|
|
1154
|
-
{
|
|
1155
|
-
"name": "x",
|
|
1156
|
-
"type": "uint256",
|
|
1157
|
-
"indexed": false,
|
|
1158
|
-
"internalType": "uint256"
|
|
1159
|
-
},
|
|
1160
|
-
{
|
|
1161
|
-
"name": "y",
|
|
1162
|
-
"type": "uint256",
|
|
1163
|
-
"indexed": false,
|
|
1164
|
-
"internalType": "uint256"
|
|
1165
|
-
},
|
|
1166
|
-
{
|
|
1167
|
-
"name": "rpIdHash",
|
|
1168
|
-
"type": "bytes32",
|
|
1169
|
-
"indexed": false,
|
|
1170
|
-
"internalType": "bytes32"
|
|
1171
1172
|
}
|
|
1172
1173
|
],
|
|
1173
1174
|
"anonymous": false
|
|
@@ -53,6 +53,19 @@
|
|
|
53
53
|
],
|
|
54
54
|
"stateMutability": "view"
|
|
55
55
|
},
|
|
56
|
+
{
|
|
57
|
+
"type": "function",
|
|
58
|
+
"name": "SELF_PASSKEY_TRUSTEE",
|
|
59
|
+
"inputs": [],
|
|
60
|
+
"outputs": [
|
|
61
|
+
{
|
|
62
|
+
"name": "",
|
|
63
|
+
"type": "address",
|
|
64
|
+
"internalType": "address"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"stateMutability": "view"
|
|
68
|
+
},
|
|
56
69
|
{
|
|
57
70
|
"type": "function",
|
|
58
71
|
"name": "accountImplementation",
|
|
@@ -443,6 +456,11 @@
|
|
|
443
456
|
"name": "NotGovernance",
|
|
444
457
|
"inputs": []
|
|
445
458
|
},
|
|
459
|
+
{
|
|
460
|
+
"type": "error",
|
|
461
|
+
"name": "SelfPasskeyTrusteeWithoutPasskey",
|
|
462
|
+
"inputs": []
|
|
463
|
+
},
|
|
446
464
|
{
|
|
447
465
|
"type": "error",
|
|
448
466
|
"name": "SystemPaused",
|
|
@@ -580,10 +580,10 @@
|
|
|
580
580
|
"internalType": "address"
|
|
581
581
|
},
|
|
582
582
|
{
|
|
583
|
-
"name": "
|
|
584
|
-
"type": "
|
|
583
|
+
"name": "guardianCommitment",
|
|
584
|
+
"type": "bytes32",
|
|
585
585
|
"indexed": true,
|
|
586
|
-
"internalType": "
|
|
586
|
+
"internalType": "bytes32"
|
|
587
587
|
}
|
|
588
588
|
],
|
|
589
589
|
"anonymous": false
|
|
@@ -599,10 +599,10 @@
|
|
|
599
599
|
"internalType": "address"
|
|
600
600
|
},
|
|
601
601
|
{
|
|
602
|
-
"name": "
|
|
603
|
-
"type": "
|
|
602
|
+
"name": "guardianCommitment",
|
|
603
|
+
"type": "bytes32",
|
|
604
604
|
"indexed": true,
|
|
605
|
-
"internalType": "
|
|
605
|
+
"internalType": "bytes32"
|
|
606
606
|
}
|
|
607
607
|
],
|
|
608
608
|
"anonymous": false
|
|
@@ -35,8 +35,11 @@ export interface Deployments {
|
|
|
35
35
|
readonly "universalSignatureValidator": Address;
|
|
36
36
|
readonly "valueEnforcer": Address;
|
|
37
37
|
readonly "agentRegistryBase": Address;
|
|
38
|
-
readonly "
|
|
38
|
+
readonly "agenticGovernance": Address;
|
|
39
|
+
readonly "timelockController": Address;
|
|
40
|
+
readonly "governanceGuardian": Address;
|
|
39
41
|
readonly "chainId": number;
|
|
42
|
+
readonly "deploymentEpoch": string;
|
|
40
43
|
}
|
|
41
44
|
export declare const CONTRACTS: Deployments;
|
|
42
45
|
export default CONTRACTS;
|
|
@@ -1,40 +1,43 @@
|
|
|
1
1
|
// Generated by scripts/build-deployments.mjs — do not edit by hand.
|
|
2
2
|
// Source: deployments-base-sepolia.json
|
|
3
3
|
export const CONTRACTS = {
|
|
4
|
-
"agentAccountFactory": "
|
|
5
|
-
"agentAccountImplementation": "
|
|
6
|
-
"agentNameRegistry": "
|
|
7
|
-
"agentNameResolver": "
|
|
8
|
-
"agentNameUniversalResolver": "
|
|
9
|
-
"agentProfileResolver": "
|
|
10
|
-
"agentRelationship": "
|
|
11
|
-
"agreementRegistry": "
|
|
12
|
-
"allowedMethodsEnforcer": "
|
|
13
|
-
"allowedTargetsEnforcer": "
|
|
14
|
-
"approvedHashRegistry": "
|
|
15
|
-
"attestationRegistry": "
|
|
16
|
-
"callDataHashEnforcer": "
|
|
4
|
+
"agentAccountFactory": "0xA9B6e53FcD8DA3658DeD09f4e37b22baA25De715",
|
|
5
|
+
"agentAccountImplementation": "0x97DAC0cC056093B7DBFb4183804EA72f8d89972F",
|
|
6
|
+
"agentNameRegistry": "0x6629Cca40B008C0984a1Ca266Ca10A344420cac3",
|
|
7
|
+
"agentNameResolver": "0xA15B0703716DC8634B74F97723618f74Af3AaA73",
|
|
8
|
+
"agentNameUniversalResolver": "0xB890060dE1B3Fd2C78e1f0859da3883743eAD452",
|
|
9
|
+
"agentProfileResolver": "0xfcd37F8dca26ead889922b22C169c21370bd352a",
|
|
10
|
+
"agentRelationship": "0x0AF2455e3f76594E81d9042aD5FE22A5A35dc57f",
|
|
11
|
+
"agreementRegistry": "0xa62c888595Cd3A645e340EA7768B53b4fC257DF5",
|
|
12
|
+
"allowedMethodsEnforcer": "0xa076b759D6785bA5E67016e399Af651fC2ABC811",
|
|
13
|
+
"allowedTargetsEnforcer": "0xb06252FaD1D41B9943c73ec696Af70F268581625",
|
|
14
|
+
"approvedHashRegistry": "0x465f8DCE65aB51A1562CC60E6bc046ca8734D537",
|
|
15
|
+
"attestationRegistry": "0xD57f2e52395b9C99fAE8Abf823578faFe038f5B7",
|
|
16
|
+
"callDataHashEnforcer": "0xA614d6E5ECebc308b4e0bABDC7c832da059bb132",
|
|
17
17
|
"chainId": 84532,
|
|
18
|
-
"custodyPolicy": "
|
|
19
|
-
"delegationManager": "
|
|
18
|
+
"custodyPolicy": "0x5DB542eeBa652372afE6B4b0Cd40D999e65846de",
|
|
19
|
+
"delegationManager": "0x9eD1dC0FD2284fcd4967beeF3317129fee7a92e5",
|
|
20
20
|
"deployer": "0x31ed17fb99e82E02085Ab4B3cbdaB05489098b44",
|
|
21
|
-
"entryPoint": "
|
|
22
|
-
"geoFeatureRegistry": "
|
|
23
|
-
"mockUsdc": "
|
|
24
|
-
"ontologyTermRegistry": "
|
|
25
|
-
"paymentEnforcer": "
|
|
26
|
-
"paymentReceiptRegistry": "
|
|
27
|
-
"permissionlessSubregistry": "
|
|
28
|
-
"permissionlessSubregistryDemoAgent": "
|
|
29
|
-
"quorumEnforcer": "
|
|
30
|
-
"relationshipTypeRegistry": "
|
|
31
|
-
"shapeRegistry": "
|
|
32
|
-
"skillDefinitionRegistry": "
|
|
33
|
-
"smartAgentPaymaster": "
|
|
34
|
-
"timestampEnforcer": "
|
|
35
|
-
"universalSignatureValidator": "
|
|
36
|
-
"valueEnforcer": "
|
|
37
|
-
"agentRegistryBase": "
|
|
38
|
-
"
|
|
21
|
+
"entryPoint": "0x96E37dD695840AF7781E669bdca9d79E4d7d8040",
|
|
22
|
+
"geoFeatureRegistry": "0x7D4F6F5cca1cDb1c72b25c50aB80Fb9629BA800B",
|
|
23
|
+
"mockUsdc": "0x6cfF706bA1461a9ef9F5aaf8f1581301805FbF92",
|
|
24
|
+
"ontologyTermRegistry": "0xC03a64e1492021fEc27f31F066f09Abe28F73e00",
|
|
25
|
+
"paymentEnforcer": "0x4DAc5F8891112D0C34d207FcE5ED78f13cD2b7d8",
|
|
26
|
+
"paymentReceiptRegistry": "0xF659091DDB30D3A608d6f96fAEDB41e966B72433",
|
|
27
|
+
"permissionlessSubregistry": "0x598C7bbAf25f5246BE3D5A75FdEDC180D67D8026",
|
|
28
|
+
"permissionlessSubregistryDemoAgent": "0x571f9F2e12939F2fEDFC431aD6d7323d7483e02B",
|
|
29
|
+
"quorumEnforcer": "0xA4b148EfF1Ff1c116849F6e9D9c0059bC644873F",
|
|
30
|
+
"relationshipTypeRegistry": "0x8991a3ECf1DD41064Aa48DaF15a24B3d6a2811C5",
|
|
31
|
+
"shapeRegistry": "0xdE375012B37820C23272e2A2c9de2A8F6328aFA3",
|
|
32
|
+
"skillDefinitionRegistry": "0x167c8a31d5Fc36558A4eAD0CA96AcA7936a8e5e7",
|
|
33
|
+
"smartAgentPaymaster": "0x3444160e79C463B8F1e10f86Eae4047E22256aD0",
|
|
34
|
+
"timestampEnforcer": "0xBb8fF9c82417189c6EfeBbB369e9dd9d651aa0f3",
|
|
35
|
+
"universalSignatureValidator": "0x3bc65655d4b6fb57731A256fcd47Db2F8Fe36907",
|
|
36
|
+
"valueEnforcer": "0x3D2abD6c7C1319f2bbA96B3b76A7e0d92C620A39",
|
|
37
|
+
"agentRegistryBase": "0xB18534CA9c679968132ca2a43E454f5fA341030D",
|
|
38
|
+
"agenticGovernance": "0x27c1F21ffA275e61Fe152Edd4f2676fD6a816dDa",
|
|
39
|
+
"timelockController": "0xeB66E0B92287E53BB5A80bD2a01002150249DC94",
|
|
40
|
+
"governanceGuardian": "0x31ed17fb99e82E02085Ab4B3cbdaB05489098b44",
|
|
41
|
+
"deploymentEpoch": "ep_015f71625117a4d1"
|
|
39
42
|
};
|
|
40
43
|
export default CONTRACTS;
|
|
@@ -4,6 +4,7 @@ import type { Address } from 'viem';
|
|
|
4
4
|
export interface Deployments {
|
|
5
5
|
readonly "agreementRegistry": Address;
|
|
6
6
|
readonly "attestationRegistry": Address;
|
|
7
|
+
readonly "deploymentEpoch": string;
|
|
7
8
|
}
|
|
8
9
|
export declare const CONTRACTS: Deployments;
|
|
9
10
|
export default CONTRACTS;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Source: deployments-registries-base-sepolia.json
|
|
3
3
|
export const CONTRACTS = {
|
|
4
4
|
"agreementRegistry": "0x9f2A085f0bd2d8Afb69490C0C98D88592093906A",
|
|
5
|
-
"attestationRegistry": "0x4a156CAaE69E894E3C5e6F3064fE028F138b6847"
|
|
5
|
+
"attestationRegistry": "0x4a156CAaE69E894E3C5e6F3064fE028F138b6847",
|
|
6
|
+
"deploymentEpoch": "ep_45ca31c3315a5978"
|
|
6
7
|
};
|
|
7
8
|
export default CONTRACTS;
|
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.18",
|
|
4
4
|
"description": "Solidity contracts + ABIs + flattened sources + per-network deployment addresses for the agenticprimitives stack.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/src/AgentAccount.sol
CHANGED
|
@@ -441,7 +441,7 @@ contract AgentAccount is
|
|
|
441
441
|
$.piaToCredentialId[pia] = credIdDigest;
|
|
442
442
|
$.rpIdHashOf[credIdDigest] = rpIdHash;
|
|
443
443
|
$.count = 1;
|
|
444
|
-
emit PasskeyAdded(credIdDigest
|
|
444
|
+
emit PasskeyAdded(credIdDigest);
|
|
445
445
|
emit CustodianAdded(pia);
|
|
446
446
|
}
|
|
447
447
|
|
|
@@ -1515,15 +1515,23 @@ contract AgentAccount is
|
|
|
1515
1515
|
}
|
|
1516
1516
|
|
|
1517
1517
|
/// @notice Deterministically derive the Passkey-Identity-Address for
|
|
1518
|
-
/// a P-256 public key.
|
|
1519
|
-
///
|
|
1520
|
-
///
|
|
1521
|
-
|
|
1518
|
+
/// a P-256 public key ON THIS ACCOUNT. Spec 302 W2: the PIA is
|
|
1519
|
+
/// account-scoped — `keccak256(abi.encode(x, y, address(this)))` —
|
|
1520
|
+
/// so the same physical passkey yields a DIFFERENT custodian
|
|
1521
|
+
/// address on every account it custodies. The pre-302 global
|
|
1522
|
+
/// derivation (`keccak256(abi.encode(x, y))`) made the PIA a
|
|
1523
|
+
/// public cross-account join key: one `CustodianAdded(pia)` log
|
|
1524
|
+
/// scan clustered a person's SA with every org/treasury SA their
|
|
1525
|
+
/// root passkey controls. Off-chain mirror: account-custody
|
|
1526
|
+
/// `passkeyIdentity(x, y, account)`; the v=2 signature slot
|
|
1527
|
+
/// verifier (SignatureSlotRecovery) re-derives with the same
|
|
1528
|
+
/// account scope.
|
|
1529
|
+
function passkeyIdentity(uint256 x, uint256 y) public view returns (address) {
|
|
1522
1530
|
return _passkeyIdentity(x, y);
|
|
1523
1531
|
}
|
|
1524
1532
|
|
|
1525
|
-
function _passkeyIdentity(uint256 x, uint256 y) internal
|
|
1526
|
-
return address(uint160(uint256(keccak256(abi.encode(x, y)))));
|
|
1533
|
+
function _passkeyIdentity(uint256 x, uint256 y) internal view returns (address) {
|
|
1534
|
+
return address(uint160(uint256(keccak256(abi.encode(x, y, address(this))))));
|
|
1527
1535
|
}
|
|
1528
1536
|
|
|
1529
1537
|
/// @inheritdoc IAgentAccount
|
|
@@ -1622,7 +1630,14 @@ contract AgentAccount is
|
|
|
1622
1630
|
assembly { $.slot := slot }
|
|
1623
1631
|
}
|
|
1624
1632
|
|
|
1625
|
-
|
|
1633
|
+
/// @dev Spec 302 W1 — the event carries ONLY the credential digest. The raw
|
|
1634
|
+
/// P256 coordinates and rpIdHash were removed: identical (x, y) across
|
|
1635
|
+
/// accounts let any log indexer cluster every SA one physical passkey
|
|
1636
|
+
/// custodies (publicly defeating ADR-0025's person↔org privacy), and
|
|
1637
|
+
/// sha256(rpId) is a guessable-preimage domain disclosure. Coordinates
|
|
1638
|
+
/// remain in storage — the ONE read path is `getPasskey(credentialIdDigest)`
|
|
1639
|
+
/// (ADR-0012/0013; INV-302-3).
|
|
1640
|
+
event PasskeyAdded(bytes32 indexed credentialIdDigest);
|
|
1626
1641
|
event PasskeyRemoved(bytes32 indexed credentialIdDigest);
|
|
1627
1642
|
|
|
1628
1643
|
/// @notice Register a new WebAuthn credential bound to a specific RP.
|
|
@@ -1658,7 +1673,7 @@ contract AgentAccount is
|
|
|
1658
1673
|
$.piaToCredentialId[pia] = credentialIdDigest;
|
|
1659
1674
|
$.rpIdHashOf[credentialIdDigest] = rpIdHash;
|
|
1660
1675
|
$.count += 1;
|
|
1661
|
-
emit PasskeyAdded(credentialIdDigest
|
|
1676
|
+
emit PasskeyAdded(credentialIdDigest);
|
|
1662
1677
|
emit CustodianAdded(pia);
|
|
1663
1678
|
}
|
|
1664
1679
|
|
|
@@ -1693,6 +1708,14 @@ contract AgentAccount is
|
|
|
1693
1708
|
return (k.x, k.y);
|
|
1694
1709
|
}
|
|
1695
1710
|
|
|
1711
|
+
/// @notice Read the RP-ID hash a credential was registered against.
|
|
1712
|
+
/// @dev Spec 302 W1 (INV-302-3): the slimmed `PasskeyAdded` event no longer
|
|
1713
|
+
/// carries `rpIdHash`; this getter is the ONE read path for it
|
|
1714
|
+
/// (ADR-0012/0013 — `readContract`, no log walking).
|
|
1715
|
+
function getPasskeyRpIdHash(bytes32 credentialIdDigest) external view returns (bytes32) {
|
|
1716
|
+
return _passkeyStorage().rpIdHashOf[credentialIdDigest];
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1696
1719
|
/// @notice Total count of registered passkeys.
|
|
1697
1720
|
function passkeyCount() external view returns (uint256) {
|
|
1698
1721
|
return _passkeyStorage().count;
|
|
@@ -101,6 +101,25 @@ contract AgentAccountFactory is GovernanceManaged {
|
|
|
101
101
|
/// threshold at `_buildValidatorInitData:252`.
|
|
102
102
|
uint256 public constant MAX_INITIAL_CUSTODIANS = 32;
|
|
103
103
|
|
|
104
|
+
/// @notice Spec 302 W2 — trustee-slot sentinel meaning "the initial
|
|
105
|
+
/// passkey's Passkey-Identity-Address on the account being
|
|
106
|
+
/// deployed". The PIA is now account-scoped, so it CANNOT be
|
|
107
|
+
/// computed before the CREATE2 address exists — but the salt
|
|
108
|
+
/// commits to `params.trustees` (CA-F1). Clients that want the
|
|
109
|
+
/// initial passkey to be its own recovery trustee (mode>0
|
|
110
|
+
/// self-recovery bootstrap) pass this sentinel; the factory
|
|
111
|
+
/// resolves it to the real per-account PIA AFTER the deploy,
|
|
112
|
+
/// when it builds the CustodyPolicy install blob. The address
|
|
113
|
+
/// therefore commits to the INTENT ("self-passkey is a
|
|
114
|
+
/// trustee"), which is deterministic, instead of the derived
|
|
115
|
+
/// value, which is circular.
|
|
116
|
+
address public constant SELF_PASSKEY_TRUSTEE =
|
|
117
|
+
address(uint160(uint256(keccak256("ap.trustee.self-initial-passkey"))));
|
|
118
|
+
|
|
119
|
+
/// @notice Spec 302 W2 — `SELF_PASSKEY_TRUSTEE` passed without an
|
|
120
|
+
/// initial passkey to resolve it to.
|
|
121
|
+
error SelfPasskeyTrusteeWithoutPasskey();
|
|
122
|
+
|
|
104
123
|
constructor(
|
|
105
124
|
IEntryPoint entryPoint_,
|
|
106
125
|
address delegationManager_,
|
|
@@ -176,7 +195,7 @@ contract AgentAccountFactory is GovernanceManaged {
|
|
|
176
195
|
account = AgentAccount(payable(address(proxy)));
|
|
177
196
|
|
|
178
197
|
if (params.mode > 0) {
|
|
179
|
-
bytes memory validatorInit = _buildValidatorInitData(params, timelockOverrides);
|
|
198
|
+
bytes memory validatorInit = _buildValidatorInitData(params, timelockOverrides, address(account));
|
|
180
199
|
account.installModule(2 /* MODULE_TYPE_EXECUTOR */, custodyPolicy, validatorInit);
|
|
181
200
|
}
|
|
182
201
|
|
|
@@ -281,6 +300,15 @@ contract AgentAccountFactory is GovernanceManaged {
|
|
|
281
300
|
revert TooManyInitialCustodians(params.custodians.length, MAX_INITIAL_CUSTODIANS);
|
|
282
301
|
}
|
|
283
302
|
|
|
303
|
+
// Spec 302 W2 — the self-passkey trustee sentinel is meaningless
|
|
304
|
+
// without an initial passkey to resolve it to (fail-closed at
|
|
305
|
+
// predict time too, so counterfactual and deploy agree).
|
|
306
|
+
bool hasSentinel;
|
|
307
|
+
for (uint256 i; i < params.trustees.length; i++) {
|
|
308
|
+
if (params.trustees[i] == SELF_PASSKEY_TRUSTEE) { hasSentinel = true; break; }
|
|
309
|
+
}
|
|
310
|
+
if (hasSentinel && !hasPasskey) revert SelfPasskeyTrusteeWithoutPasskey();
|
|
311
|
+
|
|
284
312
|
if (params.mode == 0) return;
|
|
285
313
|
|
|
286
314
|
uint256 nTrustees = params.trustees.length;
|
|
@@ -305,7 +333,8 @@ contract AgentAccountFactory is GovernanceManaged {
|
|
|
305
333
|
/// external custodians + (1 if initial passkey, else 0).
|
|
306
334
|
function _buildValidatorInitData(
|
|
307
335
|
AgentAccountInitParams calldata params,
|
|
308
|
-
uint32[7] calldata timelockOverrides
|
|
336
|
+
uint32[7] calldata timelockOverrides,
|
|
337
|
+
address account
|
|
309
338
|
) internal view returns (bytes memory) {
|
|
310
339
|
uint256 nSigners = params.custodians.length;
|
|
311
340
|
if (params.initialPasskeyX != 0 && params.initialPasskeyY != 0) nSigners++;
|
|
@@ -344,10 +373,21 @@ contract AgentAccountFactory is GovernanceManaged {
|
|
|
344
373
|
|
|
345
374
|
uint8 recThr = uint8(params.trustees.length / 2 + 1);
|
|
346
375
|
|
|
376
|
+
// Spec 302 W2 — resolve the self-passkey trustee sentinel to the
|
|
377
|
+
// account-scoped PIA. Runs AFTER the deploy (the account address —
|
|
378
|
+
// and thus the per-account PIA — exists), while the CREATE2 salt
|
|
379
|
+
// committed to the sentinel form (deterministic pre-deploy).
|
|
380
|
+
address[] memory trustees = new address[](params.trustees.length);
|
|
381
|
+
for (uint256 i; i < trustees.length; i++) {
|
|
382
|
+
trustees[i] = params.trustees[i] == SELF_PASSKEY_TRUSTEE
|
|
383
|
+
? AgentAccount(payable(account)).passkeyIdentity(params.initialPasskeyX, params.initialPasskeyY)
|
|
384
|
+
: params.trustees[i];
|
|
385
|
+
}
|
|
386
|
+
|
|
347
387
|
return abi.encode(
|
|
348
388
|
params.mode,
|
|
349
389
|
recThr,
|
|
350
|
-
|
|
390
|
+
trustees,
|
|
351
391
|
thresholds,
|
|
352
392
|
timelocks,
|
|
353
393
|
uint256(0.01 ether),
|
|
@@ -273,8 +273,17 @@ contract CustodyPolicy {
|
|
|
273
273
|
event CustodyChangeScheduled(address indexed account, uint256 indexed changeId, CustodyAction indexed action, uint64 eta, address proposer);
|
|
274
274
|
event CustodyChangeApplied(address indexed account, uint256 indexed changeId);
|
|
275
275
|
event ScheduledChangeCancelled(address indexed account, uint256 indexed changeId);
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
/// @dev Spec 302 W3 — guardian/trustee events carry an opaque MEMBERSHIP
|
|
277
|
+
/// COMMITMENT, not the raw guardian address: `GuardianAdded(account,
|
|
278
|
+
/// guardian)` published each person's social-recovery graph (who
|
|
279
|
+
/// guards whom) permanently. The commitment
|
|
280
|
+
/// `keccak256(abi.encode(guardian, account))` is unsalted +
|
|
281
|
+
/// on-chain-reproducible (ADR-0040 posture): anyone holding a
|
|
282
|
+
/// CANDIDATE guardian address can confirm membership, but nobody can
|
|
283
|
+
/// enumerate the graph from logs. The ONE read path for a live check
|
|
284
|
+
/// is `isTrustee(account, signer)` (ADR-0012/0013).
|
|
285
|
+
event GuardianAdded(address indexed account, bytes32 indexed guardianCommitment);
|
|
286
|
+
event GuardianRemoved(address indexed account, bytes32 indexed guardianCommitment);
|
|
278
287
|
event ThresholdChanged(address indexed account, uint8 indexed tier, uint8 oldValue, uint8 newValue);
|
|
279
288
|
event ModeChanged(address indexed account, uint8 oldMode, uint8 newMode);
|
|
280
289
|
event T3CeilingChanged(address indexed account, uint256 oldCeiling, uint256 newCeiling);
|
|
@@ -753,7 +762,8 @@ contract CustodyPolicy {
|
|
|
753
762
|
address prev;
|
|
754
763
|
for (uint256 i; i < vargs.reqThreshold; i++) {
|
|
755
764
|
address signer = SignatureSlotRecovery.recoverFromSlot(
|
|
756
|
-
|
|
765
|
+
// Spec 302 W2 — v=2 passkey slots derive the per-ACCOUNT PIA.
|
|
766
|
+
vargs.payloadHash, sigsMem, i, approvedHashReg, account
|
|
757
767
|
);
|
|
758
768
|
if (signer <= prev) revert AdminDuplicateOrUnsortedSigner(signer);
|
|
759
769
|
prev = signer;
|
|
@@ -871,7 +881,7 @@ contract CustodyPolicy {
|
|
|
871
881
|
if (c.trustees[g]) revert TrusteeAlreadyExists(g);
|
|
872
882
|
c.trustees[g] = true;
|
|
873
883
|
c.trusteeCount += 1;
|
|
874
|
-
emit GuardianAdded(account, g);
|
|
884
|
+
emit GuardianAdded(account, keccak256(abi.encode(g, account)));
|
|
875
885
|
}
|
|
876
886
|
|
|
877
887
|
function _applyRemoveGuardian(address account, Config storage c, address g) internal {
|
|
@@ -881,7 +891,7 @@ contract CustodyPolicy {
|
|
|
881
891
|
}
|
|
882
892
|
c.trustees[g] = false;
|
|
883
893
|
c.trusteeCount -= 1;
|
|
884
|
-
emit GuardianRemoved(account, g);
|
|
894
|
+
emit GuardianRemoved(account, keccak256(abi.encode(g, account)));
|
|
885
895
|
}
|
|
886
896
|
|
|
887
897
|
function _applyChangeMode(address account, Config storage c, uint8 newMode) internal {
|
|
@@ -179,7 +179,10 @@ contract QuorumEnforcer is ICaveatEnforcer {
|
|
|
179
179
|
expectedPayloadHash,
|
|
180
180
|
signatures,
|
|
181
181
|
i,
|
|
182
|
-
approvedHashRegistry
|
|
182
|
+
approvedHashRegistry,
|
|
183
|
+
// Spec 302 W2 — quorum passkey signers are custodians OF THE
|
|
184
|
+
// DELEGATOR account; their v=2 PIA is scoped to it.
|
|
185
|
+
delegator
|
|
183
186
|
);
|
|
184
187
|
|
|
185
188
|
// Sorted-ascending check (also rejects duplicates).
|
|
@@ -28,8 +28,10 @@ import {WebAuthnLib} from "./WebAuthnLib.sol";
|
|
|
28
28
|
* v == 2 → WebAuthn passkey sig (agenticprimitives
|
|
29
29
|
* extension; NOT in Safe). r holds the
|
|
30
30
|
* Passkey-Identity-Address (PIA, derived
|
|
31
|
-
* from the P-256 pubkey
|
|
32
|
-
*
|
|
31
|
+
* from the P-256 pubkey + the account it is
|
|
32
|
+
* scoped to via
|
|
33
|
+
* `address(uint160(uint256(keccak256(abi.encode(x, y, passkeyScope)))))`
|
|
34
|
+
* — per-account since spec 302 W2).
|
|
33
35
|
* s holds the byte offset into `signatures`
|
|
34
36
|
* to a length-prefixed tail containing
|
|
35
37
|
* `abi.encode(uint256 x, uint256 y, bytes32 rpIdHash, WebAuthnLib.Assertion assertion)`.
|
|
@@ -77,12 +79,21 @@ library SignatureSlotRecovery {
|
|
|
77
79
|
* caller does not want to allow v=1 sigs
|
|
78
80
|
* (e.g. quorum-of-owners admin paths
|
|
79
81
|
* that don't accept pre-approved hashes).
|
|
82
|
+
* @param passkeyScope Spec 302 W2 — the AgentAccount the v=2
|
|
83
|
+
* slot's PIA is scoped to (the account
|
|
84
|
+
* whose custody the passkey signer claims:
|
|
85
|
+
* CustodyPolicy passes `account`, the
|
|
86
|
+
* QuorumEnforcer passes the `delegator`).
|
|
87
|
+
* The per-account derivation
|
|
88
|
+
* `keccak256(abi.encode(x, y, scope))`
|
|
89
|
+
* kills the cross-account PIA join key.
|
|
80
90
|
*/
|
|
81
91
|
function recoverFromSlot(
|
|
82
92
|
bytes32 payloadHash,
|
|
83
93
|
bytes memory signatures,
|
|
84
94
|
uint256 index,
|
|
85
|
-
address approvedHashRegistry
|
|
95
|
+
address approvedHashRegistry,
|
|
96
|
+
address passkeyScope
|
|
86
97
|
) internal view returns (address signer) {
|
|
87
98
|
bytes32 r;
|
|
88
99
|
bytes32 s;
|
|
@@ -171,7 +182,8 @@ library SignatureSlotRecovery {
|
|
|
171
182
|
// WebAuthnLib.Assertion assertion).
|
|
172
183
|
(uint256 pubX, uint256 pubY, bytes32 rpIdHash, WebAuthnLib.Assertion memory assertion) =
|
|
173
184
|
abi.decode(dyn, (uint256, uint256, bytes32, WebAuthnLib.Assertion));
|
|
174
|
-
|
|
185
|
+
// Spec 302 W2 — per-account PIA (mirrors AgentAccount._passkeyIdentity).
|
|
186
|
+
address derived = address(uint160(uint256(keccak256(abi.encode(pubX, pubY, passkeyScope)))));
|
|
175
187
|
if (derived != signer) revert PasskeyPubKeyMismatch(signer, derived);
|
|
176
188
|
// WA-2: require UV at the slot level. This path verifies custody-COUNCIL
|
|
177
189
|
// passkey signatures (CustodyPolicy quorum: trustees/custodians authorizing
|
|
@@ -92,4 +92,10 @@ library AgentNamePredicates {
|
|
|
92
92
|
bytes32 internal constant CONNECTION_KIND_YOUVERSION = keccak256("youversion");
|
|
93
93
|
bytes32 internal constant CONNECTION_KIND_PASSKEY = keccak256("passkey");
|
|
94
94
|
bytes32 internal constant CONNECTION_KIND_MULTI = keccak256("multi");
|
|
95
|
+
// Social/KMS-class kinds (specs 319/320) — per-subject C_sub custodians, code-flow sign-in.
|
|
96
|
+
// The attribute write path validates only the PREDICATE (OntologyTermRegistry.isActive), NOT the
|
|
97
|
+
// enum value, so these are publishable on the live deployment with no redeploy; the ShapeRegistry
|
|
98
|
+
// ConnectionKindEnum seed adds them for forward shape-validation correctness (Deploy.s.sol).
|
|
99
|
+
bytes32 internal constant CONNECTION_KIND_EMAIL = keccak256("email");
|
|
100
|
+
bytes32 internal constant CONNECTION_KIND_PHONE = keccak256("phone");
|
|
95
101
|
}
|