@agenticprimitives/account-custody 0.1.0-alpha.2

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.
@@ -0,0 +1,209 @@
1
+ // CustodyAction — mirrors enum in packages/contracts/src/custody/CustodyPolicy.sol
2
+ // (spec 213 § 2.2). The on-the-wire encoding is uint8; this enum maps the
3
+ // values into the same custody-vocabulary names the Solidity surface uses.
4
+ //
5
+ // Wave H2 hardening: every builder validates arguments at the package
6
+ // boundary so wire-format bugs surface at call time instead of as
7
+ // opaque on-chain reverts.
8
+ import { encodeAbiParameters } from 'viem';
9
+ export var CustodyAction;
10
+ (function (CustodyAction) {
11
+ CustodyAction[CustodyAction["AddCustodian"] = 0] = "AddCustodian";
12
+ CustodyAction[CustodyAction["RemoveCustodian"] = 1] = "RemoveCustodian";
13
+ CustodyAction[CustodyAction["AddPasskeyCredential"] = 2] = "AddPasskeyCredential";
14
+ CustodyAction[CustodyAction["RemovePasskeyCredential"] = 3] = "RemovePasskeyCredential";
15
+ CustodyAction[CustodyAction["AddTrustee"] = 4] = "AddTrustee";
16
+ CustodyAction[CustodyAction["RemoveTrustee"] = 5] = "RemoveTrustee";
17
+ CustodyAction[CustodyAction["ChangeCustodyMode"] = 6] = "ChangeCustodyMode";
18
+ CustodyAction[CustodyAction["ApplySystemUpdate"] = 7] = "ApplySystemUpdate";
19
+ CustodyAction[CustodyAction["RotateDelegationManager"] = 8] = "RotateDelegationManager";
20
+ CustodyAction[CustodyAction["RotatePaymaster"] = 9] = "RotatePaymaster";
21
+ CustodyAction[CustodyAction["RotateSessionIssuer"] = 10] = "RotateSessionIssuer";
22
+ CustodyAction[CustodyAction["RotateAllCustodians"] = 11] = "RotateAllCustodians";
23
+ CustodyAction[CustodyAction["ChangeValueCeiling"] = 12] = "ChangeValueCeiling";
24
+ CustodyAction[CustodyAction["SetRecoveryApprovals"] = 13] = "SetRecoveryApprovals";
25
+ CustodyAction[CustodyAction["RecoverAccount"] = 14] = "RecoverAccount";
26
+ CustodyAction[CustodyAction["ChangeApprovalsRequired"] = 15] = "ChangeApprovalsRequired";
27
+ })(CustodyAction || (CustodyAction = {}));
28
+ // ─── Range / shape validators ────────────────────────────────────────────
29
+ const ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
30
+ const BYTES32_RE = /^0x[0-9a-fA-F]{64}$/;
31
+ const U256_MAX = (1n << 256n) - 1n;
32
+ const U8_MAX = 255;
33
+ function assertAddress(label, v) {
34
+ if (typeof v !== 'string' || !ADDRESS_RE.test(v)) {
35
+ throw new RangeError(`[custody] ${label}: not a 20-byte hex address (${v})`);
36
+ }
37
+ }
38
+ function assertBytes32(label, v) {
39
+ if (typeof v !== 'string' || !BYTES32_RE.test(v)) {
40
+ throw new RangeError(`[custody] ${label}: not a 32-byte hex (${v})`);
41
+ }
42
+ }
43
+ function assertUint8(label, v, min = 0, max = U8_MAX) {
44
+ if (!Number.isInteger(v) || v < min || v > max) {
45
+ throw new RangeError(`[custody] ${label}: not a uint8 in [${min}, ${max}] (got ${v})`);
46
+ }
47
+ }
48
+ function assertUint256(label, v, min = 0n, max = U256_MAX) {
49
+ if (typeof v !== 'bigint' || v < min || v > max) {
50
+ throw new RangeError(`[custody] ${label}: not a uint256 in [${min}, ${max}] (got ${v})`);
51
+ }
52
+ }
53
+ // ─── Per-action arg builders ─────────────────────────────────────────────
54
+ //
55
+ // Each builder produces the `args` bytes the on-chain scheduler expects.
56
+ // Keeping these here means the UI never reaches for `encodeAbiParameters`
57
+ // directly with magic type strings.
58
+ export function buildAddCustodianArgs(custodian) {
59
+ assertAddress('AddCustodian.custodian', custodian);
60
+ return encodeAbiParameters([{ type: 'address' }], [custodian]);
61
+ }
62
+ export function buildRemoveCustodianArgs(custodian) {
63
+ assertAddress('RemoveCustodian.custodian', custodian);
64
+ return encodeAbiParameters([{ type: 'address' }], [custodian]);
65
+ }
66
+ export function buildAddTrusteeArgs(trustee) {
67
+ assertAddress('AddTrustee.trustee', trustee);
68
+ return encodeAbiParameters([{ type: 'address' }], [trustee]);
69
+ }
70
+ export function buildRemoveTrusteeArgs(trustee) {
71
+ assertAddress('RemoveTrustee.trustee', trustee);
72
+ return encodeAbiParameters([{ type: 'address' }], [trustee]);
73
+ }
74
+ export function buildChangeCustodyModeArgs(newMode) {
75
+ assertUint8('ChangeCustodyMode.newMode', newMode, 0, 3);
76
+ return encodeAbiParameters([{ type: 'uint8' }], [newMode]);
77
+ }
78
+ export function buildChangeValueCeilingArgs(newCeilingWei) {
79
+ assertUint256('ChangeValueCeiling.newCeilingWei', newCeilingWei);
80
+ return encodeAbiParameters([{ type: 'uint256' }], [newCeilingWei]);
81
+ }
82
+ /**
83
+ * Encode args for `SetRecoveryApprovals(newThreshold)`.
84
+ *
85
+ * The on-chain CustodyPolicy rejects `newThreshold == 0` (Wave 2C C-9)
86
+ * to prevent T4-quorum-induced silent recovery disable. The builder
87
+ * does NOT enforce that ceiling because the upper bound is the
88
+ * runtime trustee count; on-chain validation catches an over-threshold.
89
+ */
90
+ export function buildSetRecoveryApprovalsArgs(approvals) {
91
+ assertUint8('SetRecoveryApprovals.approvals', approvals);
92
+ return encodeAbiParameters([{ type: 'uint8' }], [approvals]);
93
+ }
94
+ export function buildApplySystemUpdateArgs(newImpl) {
95
+ assertAddress('ApplySystemUpdate.newImpl', newImpl);
96
+ return encodeAbiParameters([{ type: 'address' }], [newImpl]);
97
+ }
98
+ /**
99
+ * Encode args for `ChangeApprovalsRequired(tier, newCount)`.
100
+ *
101
+ * `tier` is a RiskTier in [1, 5] — T6 (recovery) lives in a separate
102
+ * slot and is set via `buildSetRecoveryApprovalsArgs`. `newCount` must
103
+ * satisfy `1 <= newCount <= account.custodianCount()` at apply time.
104
+ */
105
+ export function buildChangeApprovalsRequiredArgs(tier, newCount) {
106
+ assertUint8('ChangeApprovalsRequired.tier', tier, 1, 5);
107
+ assertUint8('ChangeApprovalsRequired.newCount', newCount, 1);
108
+ return encodeAbiParameters([{ type: 'uint8' }, { type: 'uint8' }], [tier, newCount]);
109
+ }
110
+ /**
111
+ * Encode args for `AddPasskeyCredential(credentialIdDigest, x, y)`.
112
+ * Side effect on AgentAccount: also registers the PIA derived from
113
+ * `(x, y)` as a first-class custodian.
114
+ *
115
+ * Wave 2C C-6 hardening: on-chain initializer rejects credentialIdDigest
116
+ * == 0; this builder echoes that check at the wire-format boundary so
117
+ * the demo never spends gas on a guaranteed-revert tx.
118
+ */
119
+ export function buildAddPasskeyCredentialArgs(credentialIdDigest, x, y) {
120
+ assertBytes32('AddPasskeyCredential.credentialIdDigest', credentialIdDigest);
121
+ if (credentialIdDigest === ('0x' + '00'.repeat(32))) {
122
+ throw new RangeError('[custody] AddPasskeyCredential.credentialIdDigest: must be non-zero (audit C-6)');
123
+ }
124
+ assertUint256('AddPasskeyCredential.x', x, 1n);
125
+ assertUint256('AddPasskeyCredential.y', y, 1n);
126
+ return encodeAbiParameters([{ type: 'bytes32' }, { type: 'uint256' }, { type: 'uint256' }], [credentialIdDigest, x, y]);
127
+ }
128
+ /** Encode args for `RemovePasskeyCredential(credentialIdDigest)`. */
129
+ export function buildRemovePasskeyCredentialArgs(credentialIdDigest) {
130
+ assertBytes32('RemovePasskeyCredential.credentialIdDigest', credentialIdDigest);
131
+ return encodeAbiParameters([{ type: 'bytes32' }], [credentialIdDigest]);
132
+ }
133
+ /**
134
+ * Encode args for `RotateAllCustodians(addCustodians, removeCustodians)`
135
+ * (Wave 2C C-10). Adds the new set + removes the old in one atomic action;
136
+ * factory enforces that at-least-one custodian remains.
137
+ */
138
+ export function buildRotateAllCustodiansArgs(addCustodians, removeCustodians) {
139
+ for (const c of addCustodians)
140
+ assertAddress('RotateAllCustodians.add', c);
141
+ for (const c of removeCustodians)
142
+ assertAddress('RotateAllCustodians.remove', c);
143
+ return encodeAbiParameters([{ type: 'address[]' }, { type: 'address[]' }], [addCustodians, removeCustodians]);
144
+ }
145
+ /**
146
+ * Encode args for `RecoverAccount(args)` — atomic add/remove of owners
147
+ * and passkeys in one T6 action so the signer set doesn't pass through
148
+ * a half-rotated intermediate state.
149
+ *
150
+ * Solidity struct (from packages/contracts/src/IAgentAccount.sol):
151
+ * struct AgentAccountRecoveryArgs {
152
+ * address[] addOwners;
153
+ * address[] removeOwners;
154
+ * AgentAccountRecoveryPasskeyAdd[] addPasskeys;
155
+ * bytes32[] removePasskeyCredentialIdDigests;
156
+ * }
157
+ */
158
+ export function buildRecoverAccountArgs(args) {
159
+ const addOwners = args.addOwners ?? [];
160
+ const removeOwners = args.removeOwners ?? [];
161
+ const addPasskeys = args.addPasskeys ?? [];
162
+ const removePasskeyCredentialIdDigests = args.removePasskeyCredentialIdDigests ?? [];
163
+ for (const a of addOwners)
164
+ assertAddress('RecoverAccount.addOwners', a);
165
+ for (const a of removeOwners)
166
+ assertAddress('RecoverAccount.removeOwners', a);
167
+ for (const p of addPasskeys) {
168
+ assertBytes32('RecoverAccount.addPasskeys.credentialIdDigest', p.credentialIdDigest);
169
+ if (p.credentialIdDigest === ('0x' + '00'.repeat(32))) {
170
+ throw new RangeError('[custody] RecoverAccount.addPasskeys: credentialIdDigest must be non-zero (audit C-6)');
171
+ }
172
+ assertUint256('RecoverAccount.addPasskeys.x', p.x, 1n);
173
+ assertUint256('RecoverAccount.addPasskeys.y', p.y, 1n);
174
+ }
175
+ for (const d of removePasskeyCredentialIdDigests) {
176
+ assertBytes32('RecoverAccount.removePasskeyCredentialIdDigests', d);
177
+ }
178
+ if (addOwners.length === 0 &&
179
+ removeOwners.length === 0 &&
180
+ addPasskeys.length === 0 &&
181
+ removePasskeyCredentialIdDigests.length === 0) {
182
+ throw new RangeError('[custody] RecoverAccount: at least one add/remove field must be non-empty');
183
+ }
184
+ return encodeAbiParameters([
185
+ {
186
+ type: 'tuple',
187
+ components: [
188
+ { name: 'addOwners', type: 'address[]' },
189
+ { name: 'removeOwners', type: 'address[]' },
190
+ {
191
+ name: 'addPasskeys',
192
+ type: 'tuple[]',
193
+ components: [
194
+ { name: 'credentialIdDigest', type: 'bytes32' },
195
+ { name: 'x', type: 'uint256' },
196
+ { name: 'y', type: 'uint256' },
197
+ ],
198
+ },
199
+ { name: 'removePasskeyCredentialIdDigests', type: 'bytes32[]' },
200
+ ],
201
+ },
202
+ ], [{
203
+ addOwners: addOwners,
204
+ removeOwners: removeOwners,
205
+ addPasskeys: addPasskeys,
206
+ removePasskeyCredentialIdDigests: removePasskeyCredentialIdDigests,
207
+ }]);
208
+ }
209
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { Address, Hex } from 'viem';
2
+ export declare const CUSTODY_DOMAIN_NAME = "agenticprimitives.CustodyPolicy";
3
+ export declare const CUSTODY_DOMAIN_VERSION = "1";
4
+ export declare function custodyDomain(args: {
5
+ chainId: number;
6
+ verifyingContract: Address;
7
+ }): {
8
+ readonly name: "agenticprimitives.CustodyPolicy";
9
+ readonly version: "1";
10
+ readonly chainId: number;
11
+ readonly verifyingContract: `0x${string}`;
12
+ };
13
+ export declare const ScheduleCustodyChangeRequest: {
14
+ readonly ScheduleCustodyChangeRequest: readonly [{
15
+ readonly name: "account";
16
+ readonly type: "address";
17
+ }, {
18
+ readonly name: "action";
19
+ readonly type: "uint8";
20
+ }, {
21
+ readonly name: "argsHash";
22
+ readonly type: "bytes32";
23
+ }, {
24
+ readonly name: "changeId";
25
+ readonly type: "uint256";
26
+ }];
27
+ };
28
+ export declare const ApplyCustodyChangeRequest: {
29
+ readonly ApplyCustodyChangeRequest: readonly [{
30
+ readonly name: "account";
31
+ readonly type: "address";
32
+ }, {
33
+ readonly name: "action";
34
+ readonly type: "uint8";
35
+ }, {
36
+ readonly name: "argsHash";
37
+ readonly type: "bytes32";
38
+ }, {
39
+ readonly name: "changeId";
40
+ readonly type: "uint256";
41
+ }, {
42
+ readonly name: "eta";
43
+ readonly type: "uint64";
44
+ }];
45
+ };
46
+ export declare const CancelScheduledChangeRequest: {
47
+ readonly CancelScheduledChangeRequest: readonly [{
48
+ readonly name: "account";
49
+ readonly type: "address";
50
+ }, {
51
+ readonly name: "action";
52
+ readonly type: "uint8";
53
+ }, {
54
+ readonly name: "argsHash";
55
+ readonly type: "bytes32";
56
+ }, {
57
+ readonly name: "changeId";
58
+ readonly type: "uint256";
59
+ }, {
60
+ readonly name: "eta";
61
+ readonly type: "uint64";
62
+ }];
63
+ };
64
+ export interface ScheduleCustodyChangeMessage {
65
+ account: Address;
66
+ action: number;
67
+ argsHash: Hex;
68
+ changeId: bigint;
69
+ }
70
+ export interface ApplyCustodyChangeMessage extends ScheduleCustodyChangeMessage {
71
+ eta: bigint;
72
+ }
73
+ export type CancelScheduledChangeMessage = ApplyCustodyChangeMessage;
74
+ //# sourceMappingURL=eip712.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eip712.d.ts","sourceRoot":"","sources":["../src/eip712.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC,eAAO,MAAM,mBAAmB,oCAAoC,CAAC;AACrE,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE;;;;;EAOlF;AAED,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;CAO/B,CAAC;AAEX,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;CAQ5B,CAAC;AAEX,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;CAQ/B,CAAC;AAEX,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAA0B,SAAQ,4BAA4B;IAC7E,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,4BAA4B,GAAG,yBAAyB,CAAC"}
package/dist/eip712.js ADDED
@@ -0,0 +1,43 @@
1
+ // EIP-712 typed-data shapes for the CustodyPolicy schedule/apply/cancel
2
+ // surface. Mirrors packages/contracts/src/custody/CustodyPolicy.sol § "EIP-712"
3
+ // (spec 207 § 15, renamed per spec 213 § 2.2).
4
+ //
5
+ // Domain `name` is "agenticprimitives.CustodyPolicy", version "1". Caller
6
+ // supplies chainId + the deployed CustodyPolicy address as `verifyingContract`.
7
+ export const CUSTODY_DOMAIN_NAME = 'agenticprimitives.CustodyPolicy';
8
+ export const CUSTODY_DOMAIN_VERSION = '1';
9
+ export function custodyDomain(args) {
10
+ return {
11
+ name: CUSTODY_DOMAIN_NAME,
12
+ version: CUSTODY_DOMAIN_VERSION,
13
+ chainId: args.chainId,
14
+ verifyingContract: args.verifyingContract,
15
+ };
16
+ }
17
+ export const ScheduleCustodyChangeRequest = {
18
+ ScheduleCustodyChangeRequest: [
19
+ { name: 'account', type: 'address' },
20
+ { name: 'action', type: 'uint8' },
21
+ { name: 'argsHash', type: 'bytes32' },
22
+ { name: 'changeId', type: 'uint256' },
23
+ ],
24
+ };
25
+ export const ApplyCustodyChangeRequest = {
26
+ ApplyCustodyChangeRequest: [
27
+ { name: 'account', type: 'address' },
28
+ { name: 'action', type: 'uint8' },
29
+ { name: 'argsHash', type: 'bytes32' },
30
+ { name: 'changeId', type: 'uint256' },
31
+ { name: 'eta', type: 'uint64' },
32
+ ],
33
+ };
34
+ export const CancelScheduledChangeRequest = {
35
+ CancelScheduledChangeRequest: [
36
+ { name: 'account', type: 'address' },
37
+ { name: 'action', type: 'uint8' },
38
+ { name: 'argsHash', type: 'bytes32' },
39
+ { name: 'changeId', type: 'uint256' },
40
+ { name: 'eta', type: 'uint64' },
41
+ ],
42
+ };
43
+ //# sourceMappingURL=eip712.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eip712.js","sourceRoot":"","sources":["../src/eip712.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,gFAAgF;AAChF,+CAA+C;AAC/C,EAAE;AACF,0EAA0E;AAC1E,gFAAgF;AAIhF,MAAM,CAAC,MAAM,mBAAmB,GAAG,iCAAiC,CAAC;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,IAAqD;IACjF,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,sBAAsB;QAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;KACjC,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,4BAA4B,EAAE;QAC5B,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;QACjC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;KACtC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,yBAAyB,EAAE;QACzB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;QACjC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;KAChC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,4BAA4B,EAAE;QAC5B,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;QACjC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;KAChC;CACO,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { custodyPolicyAbi } from './abi.js';
2
+ export { CustodyAction, buildAddCustodianArgs, buildRemoveCustodianArgs, buildAddTrusteeArgs, buildRemoveTrusteeArgs, buildChangeCustodyModeArgs, buildChangeValueCeilingArgs, buildSetRecoveryApprovalsArgs, buildApplySystemUpdateArgs, buildChangeApprovalsRequiredArgs, buildAddPasskeyCredentialArgs, buildRemovePasskeyCredentialArgs, buildRotateAllCustodiansArgs, buildRecoverAccountArgs, type RecoveryPasskeyAdd, } from './actions.js';
3
+ export { CUSTODY_DOMAIN_NAME, CUSTODY_DOMAIN_VERSION, custodyDomain, ScheduleCustodyChangeRequest, ApplyCustodyChangeRequest, CancelScheduledChangeRequest, type ScheduleCustodyChangeMessage, type ApplyCustodyChangeMessage, type CancelScheduledChangeMessage, } from './eip712.js';
4
+ export { type Custodian, type Trustee, type CustodyCouncil, type ScheduledChange, type CustodyMode, type RiskTier, CUSTODY_MODE_BY_INDEX, } from './types.js';
5
+ export { type EcdsaSlot, type ContractSigSlot, type ApprovedHashSlot, type PasskeySlot, type QuorumSlot, type WebAuthnAssertion, packQuorumSigs, encodePasskeyTailBody, passkeyIdentity, } from './quorum-slots.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,gCAAgC,EAChC,6BAA6B,EAC7B,gCAAgC,EAChC,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,EAC5B,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,GAClC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,cAAc,EACd,qBAAqB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ // @agenticprimitives/account-custody — custody-layer SDK
2
+ //
3
+ // Public surface for the CustodyPolicy ERC-7579 module. Hosts the ABI,
4
+ // CustodyAction enum + arg builders, EIP-712 typed-data shapes, and
5
+ // custody-domain types (Custodian, Trustee, CustodyCouncil, ScheduledChange).
6
+ //
7
+ // Scope discipline: this package speaks custody-domain vocabulary only.
8
+ // Delegation / Steward / Caveat concepts belong in @agenticprimitives/delegation.
9
+ // See spec 212 § 2.2 + spec 213 for the vocabulary firewall.
10
+ export { custodyPolicyAbi } from './abi.js';
11
+ export { CustodyAction, buildAddCustodianArgs, buildRemoveCustodianArgs, buildAddTrusteeArgs, buildRemoveTrusteeArgs, buildChangeCustodyModeArgs, buildChangeValueCeilingArgs, buildSetRecoveryApprovalsArgs, buildApplySystemUpdateArgs, buildChangeApprovalsRequiredArgs, buildAddPasskeyCredentialArgs, buildRemovePasskeyCredentialArgs, buildRotateAllCustodiansArgs, buildRecoverAccountArgs, } from './actions.js';
12
+ export { CUSTODY_DOMAIN_NAME, CUSTODY_DOMAIN_VERSION, custodyDomain, ScheduleCustodyChangeRequest, ApplyCustodyChangeRequest, CancelScheduledChangeRequest, } from './eip712.js';
13
+ export { CUSTODY_MODE_BY_INDEX, } from './types.js';
14
+ export { packQuorumSigs, encodePasskeyTailBody, passkeyIdentity, } from './quorum-slots.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,8EAA8E;AAC9E,EAAE;AACF,wEAAwE;AACxE,kFAAkF;AAClF,6DAA6D;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,gCAAgC,EAChC,6BAA6B,EAC7B,gCAAgC,EAChC,4BAA4B,EAC5B,uBAAuB,GAExB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,GAI7B,MAAM,aAAa,CAAC;AAErB,OAAO,EAOL,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAOL,cAAc,EACd,qBAAqB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ export interface WebAuthnAssertion {
3
+ authenticatorData: Hex;
4
+ clientDataJSON: string;
5
+ challengeIndex: bigint;
6
+ typeIndex: bigint;
7
+ r: bigint;
8
+ s: bigint;
9
+ credentialIdDigest: Hex;
10
+ }
11
+ export type EcdsaSlot = {
12
+ type: 'ecdsa';
13
+ signer: Address;
14
+ /** Raw 65-byte ECDSA sig: r (32) || s (32) || v (1). */
15
+ signature: Hex;
16
+ };
17
+ export type ContractSigSlot = {
18
+ type: 'contract-sig';
19
+ /** The address whose `isValidSignature(hash, blob)` will be called. */
20
+ signer: Address;
21
+ /** Blob handed to the signer's `isValidSignature`. */
22
+ signatureBlob: Hex;
23
+ };
24
+ export type ApprovedHashSlot = {
25
+ type: 'approved-hash';
26
+ /** Address that called `ApprovedHashRegistry.approveHash`. */
27
+ signer: Address;
28
+ };
29
+ export type PasskeySlot = {
30
+ type: 'passkey';
31
+ /** Passkey-Identity-Address: keccak256(abi.encode(x, y)) cast to address. */
32
+ pia: Address;
33
+ /** P-256 public key. Re-derived and asserted equal to `pia` inside SignatureSlotRecovery. */
34
+ x: bigint;
35
+ y: bigint;
36
+ /** Decoded WebAuthn assertion produced by the browser ceremony. */
37
+ assertion: WebAuthnAssertion;
38
+ };
39
+ export type QuorumSlot = EcdsaSlot | ContractSigSlot | ApprovedHashSlot | PasskeySlot;
40
+ /**
41
+ * Encode a v=2 passkey slot's tail body as `abi.encode(uint256 x,
42
+ * uint256 y, WebAuthnLib.Assertion assertion)` — the shape
43
+ * `SignatureSlotRecovery.recoverFromSlot` decodes for v=2 slots.
44
+ */
45
+ export declare function encodePasskeyTailBody(x: bigint, y: bigint, assertion: WebAuthnAssertion): Hex;
46
+ /**
47
+ * Pack a sorted set of slots into the bytes blob CustodyPolicy expects.
48
+ * Slot encoding follows Safe's convention; dynamic tails (v=0 + v=2)
49
+ * are appended after the slot table.
50
+ *
51
+ * Layout:
52
+ * [slot 0 (65)] … [slot N (65)] [len0 (32)] [blob0] … [lenK (32)] [blobK]
53
+ */
54
+ export declare function packQuorumSigs(slots: readonly QuorumSlot[]): Hex;
55
+ /**
56
+ * Derive a Passkey-Identity-Address from a P-256 public key. Mirrors
57
+ * `AgentAccount.passkeyIdentity` exactly so off-chain code can compute
58
+ * the same address without a chain call.
59
+ */
60
+ export declare function passkeyIdentity(x: bigint, y: bigint): Address;
61
+ //# sourceMappingURL=quorum-slots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quorum-slots.d.ts","sourceRoot":"","sources":["../src/quorum-slots.ts"],"names":[],"mappings":"AAmBA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,GAAG,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,kBAAkB,EAAE,GAAG,CAAC;CACzB;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,uEAAuE;IACvE,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,aAAa,EAAE,GAAG,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,eAAe,CAAC;IACtB,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,GAAG,EAAE,OAAO,CAAC;IACb,6FAA6F;IAC7F,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,mEAAmE;IACnE,SAAS,EAAE,iBAAiB,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,eAAe,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAiBtF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,iBAAiB,GAC3B,GAAG,CASL;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,GAAG,CAiDhE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAO7D"}
@@ -0,0 +1,110 @@
1
+ // Quorum-signature packing for the CustodyPolicy admin surface.
2
+ //
3
+ // The CustodyPolicy contract consumes Safe-compatible packed slot blobs:
4
+ // each slot is `{ r (32) || s (32) || v (1) }`, optionally followed by a
5
+ // dynamic tail for slot types that need extra bytes. Slot recovery lives
6
+ // in `libraries/SignatureSlotRecovery.sol`. Slots MUST be sorted
7
+ // ascending by signer address — the on-chain `_verifyQuorum` rejects
8
+ // out-of-order or duplicate signers.
9
+ //
10
+ // Slot types (phase 6f.4):
11
+ // v == 27 || v == 28 → EcdsaSlot (EOA ECDSA, no tail)
12
+ // v == 31..34 → EcdsaSlot (eth_sign-wrapped ECDSA, no tail)
13
+ // v == 1 → ApprovedHashSlot (pre-approved hash; r = signer)
14
+ // v == 0 → ContractSigSlot (ERC-1271; r = signer, s = tail offset)
15
+ // v == 2 → PasskeySlot (WebAuthn; r = PIA, s = tail offset)
16
+ //
17
+ // All callers should compose slots via the typed constructors below and
18
+ // then pass the array to `packQuorumSigs`.
19
+ import { concat, encodeAbiParameters, keccak256, padHex, toHex, } from 'viem';
20
+ function slotSigner(slot) {
21
+ if (slot.type === 'passkey')
22
+ return slot.pia;
23
+ return slot.signer;
24
+ }
25
+ const ASSERTION_COMPONENTS = [
26
+ { name: 'authenticatorData', type: 'bytes' },
27
+ { name: 'clientDataJSON', type: 'string' },
28
+ { name: 'challengeIndex', type: 'uint256' },
29
+ { name: 'typeIndex', type: 'uint256' },
30
+ { name: 'r', type: 'uint256' },
31
+ { name: 's', type: 'uint256' },
32
+ { name: 'credentialIdDigest', type: 'bytes32' },
33
+ ];
34
+ /**
35
+ * Encode a v=2 passkey slot's tail body as `abi.encode(uint256 x,
36
+ * uint256 y, WebAuthnLib.Assertion assertion)` — the shape
37
+ * `SignatureSlotRecovery.recoverFromSlot` decodes for v=2 slots.
38
+ */
39
+ export function encodePasskeyTailBody(x, y, assertion) {
40
+ return encodeAbiParameters([
41
+ { type: 'uint256' },
42
+ { type: 'uint256' },
43
+ { type: 'tuple', components: ASSERTION_COMPONENTS },
44
+ ], [x, y, assertion]);
45
+ }
46
+ /**
47
+ * Pack a sorted set of slots into the bytes blob CustodyPolicy expects.
48
+ * Slot encoding follows Safe's convention; dynamic tails (v=0 + v=2)
49
+ * are appended after the slot table.
50
+ *
51
+ * Layout:
52
+ * [slot 0 (65)] … [slot N (65)] [len0 (32)] [blob0] … [lenK (32)] [blobK]
53
+ */
54
+ export function packQuorumSigs(slots) {
55
+ if (slots.length === 0) {
56
+ throw new Error('packQuorumSigs: at least one slot required');
57
+ }
58
+ const sorted = [...slots].sort((a, b) => slotSigner(a).toLowerCase() < slotSigner(b).toLowerCase() ? -1 : 1);
59
+ for (let i = 1; i < sorted.length; i++) {
60
+ if (slotSigner(sorted[i]).toLowerCase() === slotSigner(sorted[i - 1]).toLowerCase()) {
61
+ throw new Error(`packQuorumSigs: duplicate signer ${slotSigner(sorted[i])}`);
62
+ }
63
+ }
64
+ const slotBytesTotal = 65 * sorted.length;
65
+ const slotFragments = [];
66
+ const tailFragments = [];
67
+ let runningOffset = slotBytesTotal;
68
+ for (const slot of sorted) {
69
+ if (slot.type === 'ecdsa') {
70
+ if (slot.signature.length !== 2 + 65 * 2) {
71
+ throw new Error(`packQuorumSigs: ECDSA signature must be 65 bytes`);
72
+ }
73
+ slotFragments.push(slot.signature);
74
+ }
75
+ else if (slot.type === 'approved-hash') {
76
+ const r = padHex(slot.signer, { size: 32 });
77
+ const s = padHex('0x00', { size: 32 });
78
+ slotFragments.push(concat([r, s, '0x01']));
79
+ }
80
+ else if (slot.type === 'contract-sig') {
81
+ const r = padHex(slot.signer, { size: 32 });
82
+ const s = padHex(toHex(BigInt(runningOffset)), { size: 32 });
83
+ slotFragments.push(concat([r, s, '0x00']));
84
+ const blobBytes = (slot.signatureBlob.length - 2) / 2;
85
+ tailFragments.push(concat([padHex(toHex(BigInt(blobBytes)), { size: 32 }), slot.signatureBlob]));
86
+ runningOffset += 32 + blobBytes;
87
+ }
88
+ else {
89
+ const r = padHex(slot.pia, { size: 32 });
90
+ const s = padHex(toHex(BigInt(runningOffset)), { size: 32 });
91
+ slotFragments.push(concat([r, s, '0x02']));
92
+ const blob = encodePasskeyTailBody(slot.x, slot.y, slot.assertion);
93
+ const blobBytes = (blob.length - 2) / 2;
94
+ tailFragments.push(concat([padHex(toHex(BigInt(blobBytes)), { size: 32 }), blob]));
95
+ runningOffset += 32 + blobBytes;
96
+ }
97
+ }
98
+ return concat([...slotFragments, ...tailFragments]);
99
+ }
100
+ /**
101
+ * Derive a Passkey-Identity-Address from a P-256 public key. Mirrors
102
+ * `AgentAccount.passkeyIdentity` exactly so off-chain code can compute
103
+ * the same address without a chain call.
104
+ */
105
+ export function passkeyIdentity(x, y) {
106
+ const packed = encodeAbiParameters([{ type: 'uint256' }, { type: 'uint256' }], [x, y]);
107
+ const hash = keccak256(packed);
108
+ return (`0x${hash.slice(-40)}`);
109
+ }
110
+ //# sourceMappingURL=quorum-slots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quorum-slots.js","sourceRoot":"","sources":["../src/quorum-slots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { Address } from 'viem';
2
+ /**
3
+ * A Custodian is a Smart Agent (typically a Person Smart Agent) that
4
+ * holds custody authority over another Smart Agent. Member of a
5
+ * CustodyCouncil. Authorizes scheduled custody changes via m-of-n
6
+ * approvals.
7
+ */
8
+ export interface Custodian {
9
+ address: Address;
10
+ /** Optional label for UI ("Alice", "Bob's iPhone passkey"). */
11
+ label?: string;
12
+ }
13
+ /**
14
+ * A Trustee is a Smart Agent that holds recovery authority. Distinct
15
+ * from Custodian — trustees only act when the routine custody set is
16
+ * unavailable (lost passkeys, compromised custodians). T6 recovery
17
+ * quorum.
18
+ */
19
+ export interface Trustee {
20
+ address: Address;
21
+ label?: string;
22
+ }
23
+ /**
24
+ * The set of Custodians for a given Smart Agent + the per-tier
25
+ * approvals-required count + per-tier safety-delay seconds.
26
+ */
27
+ export interface CustodyCouncil {
28
+ custodians: Custodian[];
29
+ approvalsRequiredByTier: Record<1 | 2 | 3 | 4 | 5 | 6, number>;
30
+ safetyDelayByTierSeconds: Record<1 | 2 | 3 | 4 | 5 | 6, number>;
31
+ }
32
+ /**
33
+ * A queued custody change awaiting its safety delay + approvals. The
34
+ * on-chain record is keyed by (account, changeId). The off-chain mirror
35
+ * is what the UI shows on the "pending changes" tab.
36
+ */
37
+ export interface ScheduledChange {
38
+ account: Address;
39
+ changeId: bigint;
40
+ action: number;
41
+ args: `0x${string}`;
42
+ proposedAtUnix: number;
43
+ etaUnix: number;
44
+ proposer: Address;
45
+ executed: boolean;
46
+ cancelled: boolean;
47
+ }
48
+ /** Custody policy posture for an account. */
49
+ export type CustodyMode = 'single' | 'hybrid' | 'threshold' | 'org';
50
+ export declare const CUSTODY_MODE_BY_INDEX: Record<0 | 1 | 2 | 3, CustodyMode>;
51
+ /**
52
+ * Tier ids used across the custody surface. Mirrors spec 207 § 5.
53
+ *
54
+ * T1 Read — view methods, never gated
55
+ * T2 Write — low-value mutating calls (data updates)
56
+ * T3 Value — value transfers below the high-value ceiling
57
+ * T4 Admin — most custody changes (Add/Remove Custodian, Add/Remove
58
+ * Trustee, ChangeCustodyMode)
59
+ * T5 Critical — system updates (ApplySystemUpdate, Rotate*Manager)
60
+ * T6 Recovery — RecoverAccount, gated by trustees, longer safety delay
61
+ */
62
+ export type RiskTier = 1 | 2 | 3 | 4 | 5 | 6;
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/D,wBAAwB,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;CACjE;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC;AAEpE,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,WAAW,CAKpE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,10 @@
1
+ // Custody-layer domain types. Mirrors the ontology in
2
+ // docs/ontology/ap-custody.ttl (spec 213 § 2.5). These are pure data
3
+ // shapes — no chain access.
4
+ export const CUSTODY_MODE_BY_INDEX = {
5
+ 0: 'single',
6
+ 1: 'hybrid',
7
+ 2: 'threshold',
8
+ 3: 'org',
9
+ };
10
+ //# sourceMappingURL=types.js.map