@keelcodes/conformance 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +187 -0
  3. package/dist/abi.d.ts +219 -0
  4. package/dist/abi.d.ts.map +1 -0
  5. package/dist/abi.js +41 -0
  6. package/dist/abi.js.map +1 -0
  7. package/dist/agents.d.ts +24 -0
  8. package/dist/agents.d.ts.map +1 -0
  9. package/dist/agents.js +161 -0
  10. package/dist/agents.js.map +1 -0
  11. package/dist/checks.d.ts +12 -0
  12. package/dist/checks.d.ts.map +1 -0
  13. package/dist/checks.js +168 -0
  14. package/dist/checks.js.map +1 -0
  15. package/dist/delegation.d.ts +40 -0
  16. package/dist/delegation.d.ts.map +1 -0
  17. package/dist/delegation.js +245 -0
  18. package/dist/delegation.js.map +1 -0
  19. package/dist/index.d.ts +30 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +25 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/permissions.d.ts +52 -0
  24. package/dist/permissions.d.ts.map +1 -0
  25. package/dist/permissions.js +189 -0
  26. package/dist/permissions.js.map +1 -0
  27. package/dist/reader.d.ts +9 -0
  28. package/dist/reader.d.ts.map +1 -0
  29. package/dist/reader.js +58 -0
  30. package/dist/reader.js.map +1 -0
  31. package/dist/redteam.d.ts +38 -0
  32. package/dist/redteam.d.ts.map +1 -0
  33. package/dist/redteam.js +190 -0
  34. package/dist/redteam.js.map +1 -0
  35. package/dist/report.d.ts +4 -0
  36. package/dist/report.d.ts.map +1 -0
  37. package/dist/report.js +29 -0
  38. package/dist/report.js.map +1 -0
  39. package/dist/runner.d.ts +8 -0
  40. package/dist/runner.d.ts.map +1 -0
  41. package/dist/runner.js +62 -0
  42. package/dist/runner.js.map +1 -0
  43. package/dist/types.d.ts +227 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +45 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +55 -0
@@ -0,0 +1,190 @@
1
+ /** The threat catalogue, mapped test-by-test to `docs/THREAT_MODEL.md` §4. */
2
+ export const REDTEAM_CASES = [
3
+ {
4
+ threat: 'T-BYPASS-01',
5
+ test: 'test_T_BYPASS_01_delegatecallCannotReachThePolicy',
6
+ title: 'delegatecall cannot route execution around the policy',
7
+ severity: 'critical',
8
+ },
9
+ {
10
+ threat: 'T-BYPASS-02',
11
+ test: 'test_T_BYPASS_02_unknownDispatchSelectorRefused',
12
+ title: 'an unknown dispatch selector is refused',
13
+ severity: 'critical',
14
+ },
15
+ {
16
+ threat: 'T-BYPASS-03',
17
+ test: 'test_T_BYPASS_03_transferFromCannotDrain',
18
+ title: 'transferFrom cannot drain a token-limited rule',
19
+ severity: 'critical',
20
+ },
21
+ {
22
+ threat: 'T-BYPASS-04',
23
+ test: 'test_T_BYPASS_04_shortCalldataCannotSpoofAmount',
24
+ title: 'short calldata cannot spoof the amount as zero',
25
+ severity: 'critical',
26
+ },
27
+ {
28
+ threat: 'T-BYPASS-05',
29
+ test: 'test_T_BYPASS_05_selectorWhitelistCannotBeWidened',
30
+ title: 'a rule selector whitelist cannot be widened from the call site',
31
+ severity: 'critical',
32
+ },
33
+ {
34
+ threat: 'T-BYPASS-06',
35
+ test: 'test_T_BYPASS_06_unauthorisedTargetRefused',
36
+ title: 'a target no rule authorises is refused',
37
+ severity: 'critical',
38
+ },
39
+ {
40
+ threat: 'T-CEILING-01',
41
+ test: 'test_T_CEILING_01_batchCannotSplitAroundDailyCap',
42
+ title: 'a batch cannot split around the native daily cap',
43
+ severity: 'high',
44
+ },
45
+ {
46
+ threat: 'T-CEILING-02',
47
+ test: 'test_T_CEILING_02_batchCannotSplitAroundTokenDailyCap',
48
+ title: 'a batch cannot split around the token daily cap',
49
+ severity: 'high',
50
+ },
51
+ {
52
+ threat: 'T-ACCRUAL-01',
53
+ test: 'test_T_ACCRUAL_01_reinstallCannotResetCounters',
54
+ title: 're-installing a session cannot reset its counters',
55
+ severity: 'high',
56
+ },
57
+ {
58
+ threat: 'T-ACCRUAL-02',
59
+ test: 'test_T_ACCRUAL_02_foreignCallerCannotTouchAccrual',
60
+ title: 'a foreign caller cannot touch another account\'s accrual',
61
+ severity: 'high',
62
+ },
63
+ {
64
+ threat: 'T-WINDOW-01',
65
+ test: 'test_T_WINDOW_01_expiredSessionRefused',
66
+ title: 'a session cannot be used outside its validity window',
67
+ severity: 'high',
68
+ },
69
+ {
70
+ threat: 'T-LIFECYCLE-01',
71
+ test: 'test_T_LIFECYCLE_01_uninstalledSessionCannotBeUsed',
72
+ title: 'an uninstalled session cannot be used',
73
+ severity: 'critical',
74
+ },
75
+ {
76
+ threat: 'T-ENVELOPE-01',
77
+ test: 'test_T_ENVELOPE_01_drawBeyondCapRefused',
78
+ title: 'a draw past the envelope cap is refused',
79
+ severity: 'high',
80
+ },
81
+ {
82
+ threat: 'T-ENVELOPE-02',
83
+ test: 'test_T_ENVELOPE_02_attenuatedCannotRedelegate',
84
+ title: 'an attenuated envelope cannot delegate again',
85
+ severity: 'high',
86
+ },
87
+ {
88
+ threat: 'T-ENVELOPE-03',
89
+ test: 'test_T_ENVELOPE_03_allocationsCannotExceedRootCap',
90
+ title: 'child allocations cannot sum past the root cap',
91
+ severity: 'critical',
92
+ },
93
+ {
94
+ threat: 'T-ENVELOPE-04',
95
+ test: 'test_T_ENVELOPE_04_revokedOrExpiredAdvanceRefused',
96
+ title: 'a revoked or expired envelope cannot advance its cursor',
97
+ severity: 'high',
98
+ },
99
+ {
100
+ threat: 'T-ENVELOPE-05',
101
+ test: 'test_T_ENVELOPE_05_unauthorizedAdvanceAndStatusRefused',
102
+ title: 'a stranger cannot advance a cursor or drive an unauthorized status change',
103
+ severity: 'critical',
104
+ },
105
+ {
106
+ threat: 'T-ENVELOPE-06',
107
+ test: 'test_T_ENVELOPE_06_capabilityRootMismatchRefused',
108
+ title: 'a capability that does not hash to its capabilityRoot is refused',
109
+ severity: 'critical',
110
+ },
111
+ {
112
+ threat: 'T-ENVELOPE-07',
113
+ test: 'test_T_ENVELOPE_07_duplicateRegistrationRefused',
114
+ title: 're-registering the same (principal, capabilityRoot, salt) is refused',
115
+ severity: 'high',
116
+ },
117
+ {
118
+ threat: 'T-ENVELOPE-08',
119
+ test: 'test_T_ENVELOPE_08_foreignEnvelopeCannotBeBound',
120
+ title: "a session cannot be bound to a stranger's envelope",
121
+ severity: 'high',
122
+ },
123
+ {
124
+ threat: 'T-ENVELOPE-09',
125
+ test: 'test_T_ENVELOPE_09_childApproversMustBeSubset',
126
+ title: "an attenuated child cannot swap in its own approver set",
127
+ severity: 'high',
128
+ },
129
+ ];
130
+ function redTeamPort(target) {
131
+ const port = target.redTeam;
132
+ if (port === undefined) {
133
+ throw new Error('the red-team suite needs a `redTeam` port on the target');
134
+ }
135
+ return port;
136
+ }
137
+ export const REDTEAM_CHECKS = REDTEAM_CASES.map((testCase) => ({
138
+ id: `redteam.${testCase.threat.toLowerCase()}`,
139
+ title: `${testCase.threat} — ${testCase.title}`,
140
+ spec: 'THREAT_MODEL.md §4',
141
+ severity: testCase.severity,
142
+ async run(target) {
143
+ const outcome = await redTeamPort(target).outcomeOf(testCase.test);
144
+ if (outcome === undefined) {
145
+ throw new Error(`not run — Foundry case ${testCase.test} (${testCase.threat}) was not executed`);
146
+ }
147
+ if (!outcome) {
148
+ throw new Error(`Foundry-verified ✗ ${testCase.test} FAILED — ${testCase.threat} may be exploitable`);
149
+ }
150
+ return `Foundry-verified ✓ ${testCase.test} refuses ${testCase.threat}`;
151
+ },
152
+ }));
153
+ /** Red-team suite: Foundry adversarial cases reported through the conformance runner. */
154
+ export const REDTEAM_SUITE = {
155
+ name: 'Red-team',
156
+ spec: 'docs/THREAT_MODEL.md §4 (KeelPolicyHook + KeelBoundedActions adversarial cases)',
157
+ checks: REDTEAM_CHECKS,
158
+ };
159
+ /** Adapts a `testName → passed` table (e.g. from {@link parseForgeRedTeamReport}) to a {@link RedTeamPort}. */
160
+ export function toRedTeamPort(results) {
161
+ return { outcomeOf: async (testName) => results[testName] };
162
+ }
163
+ /** Strips a Foundry function signature (`test_Foo()`, `test_Foo(uint256)`) back to its name. */
164
+ function normalizeTestName(name) {
165
+ return name.replace(/\(.*\)$/, '');
166
+ }
167
+ /**
168
+ * Parses `forge test --match-path 'test/redteam/*' --json` output into a
169
+ * `testName → passed` table. Forge nests results by file → contract →
170
+ * `test_results`, so the walk is structural rather than depth-fixed; any leaf
171
+ * carrying a `status` is recorded.
172
+ */
173
+ export function parseForgeRedTeamReport(value) {
174
+ const results = {};
175
+ const visit = (node, name) => {
176
+ if (typeof node !== 'object' || node === null)
177
+ return;
178
+ const record = node;
179
+ const status = record['status'];
180
+ if (typeof status === 'string' && name !== undefined) {
181
+ results[normalizeTestName(name)] = status === 'Success';
182
+ return;
183
+ }
184
+ for (const [key, child] of Object.entries(record))
185
+ visit(child, key);
186
+ };
187
+ visit(value);
188
+ return results;
189
+ }
190
+ //# sourceMappingURL=redteam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redteam.js","sourceRoot":"","sources":["../src/redteam.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ConformanceReport } from './types.js';
2
+ /** Renders a report as human-readable lines. */
3
+ export declare function formatReport(report: ConformanceReport): string;
4
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAY,MAAM,YAAY,CAAC;AAS9D,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuB9D"}
package/dist/report.js ADDED
@@ -0,0 +1,29 @@
1
+ const SEVERITY_MARK = {
2
+ critical: '!!',
3
+ high: '! ',
4
+ medium: '· ',
5
+ low: ' ',
6
+ };
7
+ /** Renders a report as human-readable lines. */
8
+ export function formatReport(report) {
9
+ const subject = [];
10
+ if (report.account !== undefined)
11
+ subject.push(`account ${report.account}`);
12
+ if (report.module !== undefined)
13
+ subject.push(`module ${report.module}`);
14
+ if (report.moduleTypeId !== undefined && report.moduleTypeId !== 0n) {
15
+ subject.push(`type ${report.moduleTypeId}`);
16
+ }
17
+ const suffix = subject.length > 0 ? ` · ${subject.join(' · ')}` : '';
18
+ const lines = [
19
+ `${report.summary.ok ? 'PASS' : 'FAIL'} · ${report.suite} · ${report.results.length} checks${suffix}`,
20
+ ];
21
+ for (const result of report.results) {
22
+ const mark = result.status === 'pass' ? '✓' : '✗';
23
+ lines.push(` ${mark} ${SEVERITY_MARK[result.severity]} ${result.id} — ${result.message}`);
24
+ }
25
+ const { passed, failed, criticalFailures } = report.summary;
26
+ lines.push(`${passed} passed · ${failed} failed (${criticalFailures} critical) · ${report.durationMs}ms`);
27
+ return lines.join('\n');
28
+ }
29
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAA6B;IAC9C,QAAQ,EAAE,IAAI;IACd,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,GAAG,EAAE,IAAI;CACV,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,MAAM,CAAC,YAAY,KAAK,EAAE,EAAE,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,MAAM,KAAK,GAAa;QACtB,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,UAAU,MAAM,EAAE;KACtG,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAClD,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,OAAO,EAAE,CAC/E,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IAC5D,KAAK,CAAC,IAAI,CACR,GAAG,MAAM,aAAa,MAAM,YAAY,gBAAgB,gBAAgB,MAAM,CAAC,UAAU,IAAI,CAC9F,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Check, CheckResult, CheckTarget, ConformanceReport, ConformanceSummary, Suite } from './types.js';
2
+ /** Runs every check, converting thrown errors into failures. Never throws. */
3
+ export declare function runChecks(target: CheckTarget, checks: readonly Check[]): Promise<CheckResult[]>;
4
+ /** Tallies results. `ok` is false on any failure (critical or not). */
5
+ export declare function summarize(results: readonly CheckResult[]): ConformanceSummary;
6
+ /** Runs a suite against a target and returns the full report. */
7
+ export declare function runSuite(target: CheckTarget, suite: Suite): Promise<ConformanceReport>;
8
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,EACN,MAAM,YAAY,CAAC;AAqBpB,8EAA8E;AAC9E,wBAAsB,SAAS,CAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,KAAK,EAAE,GACvB,OAAO,CAAC,WAAW,EAAE,CAAC,CAMxB;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,kBAAkB,CAa7E;AAED,iEAAiE;AACjE,wBAAsB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAc5F"}
package/dist/runner.js ADDED
@@ -0,0 +1,62 @@
1
+ async function runCheck(target, check) {
2
+ const startedAt = Date.now();
3
+ const base = {
4
+ id: check.id,
5
+ title: check.title,
6
+ spec: check.spec,
7
+ severity: check.severity,
8
+ durationMs: 0,
9
+ };
10
+ try {
11
+ const message = await check.run(target);
12
+ return { ...base, status: 'pass', message, durationMs: Date.now() - startedAt };
13
+ }
14
+ catch (error) {
15
+ const message = error instanceof Error ? error.message : String(error);
16
+ return { ...base, status: 'fail', message, durationMs: Date.now() - startedAt };
17
+ }
18
+ }
19
+ /** Runs every check, converting thrown errors into failures. Never throws. */
20
+ export async function runChecks(target, checks) {
21
+ const results = [];
22
+ for (const check of checks) {
23
+ results.push(await runCheck(target, check));
24
+ }
25
+ return results;
26
+ }
27
+ /** Tallies results. `ok` is false on any failure (critical or not). */
28
+ export function summarize(results) {
29
+ let passed = 0;
30
+ let failed = 0;
31
+ let criticalFailures = 0;
32
+ for (const result of results) {
33
+ if (result.status === 'pass') {
34
+ passed += 1;
35
+ continue;
36
+ }
37
+ failed += 1;
38
+ if (result.severity === 'critical')
39
+ criticalFailures += 1;
40
+ }
41
+ return { passed, failed, criticalFailures, ok: failed === 0 };
42
+ }
43
+ /** Runs a suite against a target and returns the full report. */
44
+ export async function runSuite(target, suite) {
45
+ const startedAt = Date.now();
46
+ const results = await runChecks(target, suite.checks);
47
+ const report = {
48
+ suite: suite.name,
49
+ startedAt: new Date(startedAt).toISOString(),
50
+ durationMs: Date.now() - startedAt,
51
+ results,
52
+ summary: summarize(results),
53
+ };
54
+ if (target.account !== undefined)
55
+ report.account = target.account;
56
+ if (target.module !== undefined)
57
+ report.module = target.module;
58
+ if (target.moduleTypeId !== undefined)
59
+ report.moduleTypeId = target.moduleTypeId;
60
+ return report;
61
+ }
62
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,227 @@
1
+ /** `0x`-prefixed hex string. */
2
+ export type Hex = `0x${string}`;
3
+ /** `0x`-prefixed 20-byte address. */
4
+ export type Address = `0x${string}`;
5
+ /**
6
+ * ERC-7579 module type ids. Declared here on purpose: a conformance suite must
7
+ * depend on the *standards*, not on any particular project's adapter package, so
8
+ * it can be pointed at any ERC-7579 account or module.
9
+ */
10
+ export declare const MODULE_TYPE: {
11
+ readonly VALIDATOR: 1n;
12
+ readonly EXECUTOR: 2n;
13
+ readonly FALLBACK: 3n;
14
+ readonly HOOK: 4n;
15
+ };
16
+ export type ModuleTypeId = (typeof MODULE_TYPE)[keyof typeof MODULE_TYPE];
17
+ /**
18
+ * Default ERC-7579 execution modes a conformant account must support: callType
19
+ * `0x00` (single) and `0x01` (batch), execType `0x00` (default), default mode
20
+ * selector, empty payload.
21
+ */
22
+ export declare const EXECUTION_MODE: {
23
+ readonly SINGLE: Hex;
24
+ readonly BATCH: Hex;
25
+ };
26
+ /** How much a failure matters. `critical` failures gate the suite. */
27
+ export type Severity = 'critical' | 'high' | 'medium' | 'low';
28
+ /**
29
+ * Everything a check may query. Deliberately a small port rather than a viem
30
+ * client, so a suite can run against an in-memory fake (tests) or a live chain
31
+ * ({@link createViemReader}).
32
+ */
33
+ export interface AccountReader {
34
+ /** Whether `account` currently has bytecode (i.e. is deployed). */
35
+ hasCode(account: Address): Promise<boolean>;
36
+ /** ERC-7579 `isModuleInstalled(moduleTypeId, module, additionalContext)`. */
37
+ isModuleInstalled(args: {
38
+ account: Address;
39
+ module: Address;
40
+ moduleTypeId: bigint;
41
+ }): Promise<boolean>;
42
+ /** ERC-7579 `supportsExecutionMode(bytes32 mode)`. */
43
+ supportsExecutionMode(account: Address, mode: Hex): Promise<boolean>;
44
+ /** ERC-7579 `accountId()`. */
45
+ accountId(account: Address): Promise<string>;
46
+ /** ERC-7579 `IModule.isInitialized(smartAccount)` on the module. */
47
+ isModuleInitialized(module: Address, account: Address): Promise<boolean>;
48
+ /** ERC-7579 `IModule.isModuleType(moduleTypeId)` on the module. */
49
+ isModuleType(module: Address, moduleTypeId: bigint): Promise<boolean>;
50
+ }
51
+ /**
52
+ * The write half of ERC-7579's module-manager surface, as a deliberate second
53
+ * port. Kept separate from {@link AccountReader} so a read-only conformance run
54
+ * can never mutate an account: install/uninstall only happen when the caller
55
+ * injects this port explicitly. A live adapter would bind it to a wallet client
56
+ * (it sends transactions); tests bind it to an in-memory fake.
57
+ */
58
+ export interface ModuleAdminPort {
59
+ /** ERC-7579 `installModule(moduleTypeId, module, initData)`. */
60
+ installModule(args: {
61
+ account: Address;
62
+ module: Address;
63
+ moduleTypeId: bigint;
64
+ initData?: Hex;
65
+ }): Promise<void>;
66
+ /** ERC-7579 `uninstallModule(moduleTypeId, module, deInitData)`. */
67
+ uninstallModule(args: {
68
+ account: Address;
69
+ module: Address;
70
+ moduleTypeId: bigint;
71
+ deInitData?: Hex;
72
+ }): Promise<void>;
73
+ }
74
+ /** A caveat as defined by the ERC-7710 reference implementation. */
75
+ export interface DelegationCaveat {
76
+ enforcer: Address;
77
+ terms: Hex;
78
+ /** Ignored when hashing, so it may change after signing. */
79
+ args?: Hex;
80
+ }
81
+ /** A delegation as defined by the ERC-7710 reference implementation. */
82
+ export interface Delegation {
83
+ delegate: Address;
84
+ delegator: Address;
85
+ authority: Hex;
86
+ caveats: readonly DelegationCaveat[];
87
+ salt: bigint;
88
+ /** Ignored when hashing, so it may change after signing. */
89
+ signature?: Hex;
90
+ }
91
+ /**
92
+ * ERC-7710 delegation reads, bound to the `DelegationManager` under test.
93
+ *
94
+ * The EIP itself fixes only `redeemDelegations`; the getters below come from the
95
+ * MetaMask delegation-framework reference implementation that the EIP names.
96
+ * The reader is bound to one manager so checks need no extra arguments.
97
+ */
98
+ export interface DelegationReader {
99
+ manager: Address;
100
+ hasCode(address: Address): Promise<boolean>;
101
+ chainId(): Promise<number>;
102
+ domainHash(): Promise<Hex>;
103
+ delegationHash(delegation: Delegation): Promise<Hex>;
104
+ isDelegationDisabled(delegationHash: Hex): Promise<boolean>;
105
+ name(): Promise<string>;
106
+ version(): Promise<string>;
107
+ rootAuthority(): Promise<Hex>;
108
+ anyDelegate(): Promise<Address>;
109
+ }
110
+ /**
111
+ * ERC-7715 wallet surface — a JSON-RPC (EIP-1193) `request`, not an on-chain
112
+ * interface. The suite discovers capabilities and inspects granted permissions.
113
+ */
114
+ export interface PermissionsProvider {
115
+ request(args: {
116
+ method: string;
117
+ params?: readonly unknown[];
118
+ }): Promise<unknown>;
119
+ }
120
+ /** ERC-8004 registry reads, bound to one agent. */
121
+ export interface AgentRegistryReader {
122
+ identityRegistry: Address;
123
+ /** Optional; enables the reputation-binding check when present. */
124
+ reputationRegistry?: Address;
125
+ agentId: bigint;
126
+ hasCode(address: Address): Promise<boolean>;
127
+ ownerOf(): Promise<Address>;
128
+ tokenURI(): Promise<string>;
129
+ agentWallet(): Promise<Address>;
130
+ supportsInterface(interfaceId: Hex): Promise<boolean>;
131
+ reputationIdentityRegistry(): Promise<Address>;
132
+ }
133
+ /**
134
+ * Red-team results port. Each `Check` in the red-team suite corresponds to one
135
+ * Foundry case; the port reports whether that case passed, or `undefined` when
136
+ * it was not executed — so a report can distinguish "Foundry-verified" from
137
+ * "not run" instead of silently omitting unverified threats.
138
+ */
139
+ export interface RedTeamPort {
140
+ /** Whether the named Foundry test passed; `undefined` when it was not run. */
141
+ outcomeOf(testName: string): Promise<boolean | undefined>;
142
+ }
143
+ /**
144
+ * The subject of a conformance run. ERC-7579 needs the account fields; every
145
+ * other suite carries its own bound port, so those fields are optional and only
146
+ * the relevant suite reads them.
147
+ */
148
+ export interface CheckTarget {
149
+ reader?: AccountReader;
150
+ /** Write half of the ERC-7579 module-manager surface; enables lifecycle checks. */
151
+ moduleAdmin?: ModuleAdminPort;
152
+ /** The smart account under test (ERC-7579). */
153
+ account?: Address;
154
+ /** The module under test (ERC-7579), typically installed on `account`. */
155
+ module?: Address;
156
+ /** ERC-7579 module type of `module` on `account`. */
157
+ moduleTypeId?: bigint;
158
+ delegation?: DelegationReader;
159
+ permissions?: PermissionsProvider;
160
+ agentRegistry?: AgentRegistryReader;
161
+ redTeam?: RedTeamPort;
162
+ }
163
+ /** Narrows a target to the ERC-7579 account fields, or throws. */
164
+ export declare function accountTarget(target: CheckTarget): {
165
+ reader: AccountReader;
166
+ account: Address;
167
+ module: Address;
168
+ moduleTypeId: bigint;
169
+ };
170
+ /**
171
+ * Narrows a target to the ERC-7579 module-lifecycle fields, or throws. The
172
+ * mutation checks need both the read port and the explicit write port, so a
173
+ * plain read-only run fails them loudly instead of silently skipping.
174
+ */
175
+ export declare function moduleAdminTarget(target: CheckTarget): {
176
+ reader: AccountReader;
177
+ moduleAdmin: ModuleAdminPort;
178
+ account: Address;
179
+ module: Address;
180
+ moduleTypeId: bigint;
181
+ };
182
+ /**
183
+ * A single conformance assertion. `run` returns a short pass message, or throws
184
+ * to fail — throwing keeps checks readable and lets the runner attach context.
185
+ */
186
+ export interface Check {
187
+ id: string;
188
+ title: string;
189
+ /** Spec anchor, e.g. `ERC-7579 §3.1`. */
190
+ spec: string;
191
+ severity: Severity;
192
+ run(target: CheckTarget): Promise<string>;
193
+ }
194
+ export interface CheckResult {
195
+ id: string;
196
+ title: string;
197
+ spec: string;
198
+ severity: Severity;
199
+ status: 'pass' | 'fail';
200
+ message: string;
201
+ durationMs: number;
202
+ }
203
+ export interface ConformanceSummary {
204
+ passed: number;
205
+ failed: number;
206
+ criticalFailures: number;
207
+ /** `true` only when nothing failed and no `critical` check failed. */
208
+ ok: boolean;
209
+ }
210
+ export interface ConformanceReport {
211
+ /** Name of the suite that produced the report. */
212
+ suite: string;
213
+ account?: Address;
214
+ module?: Address;
215
+ moduleTypeId?: bigint;
216
+ startedAt: string;
217
+ durationMs: number;
218
+ results: CheckResult[];
219
+ summary: ConformanceSummary;
220
+ }
221
+ /** A named, ordered bundle of checks for one standard. */
222
+ export interface Suite {
223
+ name: string;
224
+ spec: string;
225
+ checks: readonly Check[];
226
+ }
227
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ERC-7579 module type ids. Declared here on purpose: a conformance suite must
3
+ * depend on the *standards*, not on any particular project's adapter package, so
4
+ * it can be pointed at any ERC-7579 account or module.
5
+ */
6
+ export const MODULE_TYPE = {
7
+ VALIDATOR: 1n,
8
+ EXECUTOR: 2n,
9
+ FALLBACK: 3n,
10
+ HOOK: 4n,
11
+ };
12
+ /**
13
+ * Default ERC-7579 execution modes a conformant account must support: callType
14
+ * `0x00` (single) and `0x01` (batch), execType `0x00` (default), default mode
15
+ * selector, empty payload.
16
+ */
17
+ export const EXECUTION_MODE = {
18
+ SINGLE: `0x${'00'.repeat(32)}`,
19
+ BATCH: `0x01${'00'.repeat(31)}`,
20
+ };
21
+ /** Narrows a target to the ERC-7579 account fields, or throws. */
22
+ export function accountTarget(target) {
23
+ const { reader, account, module, moduleTypeId } = target;
24
+ if (reader === undefined || account === undefined || module === undefined || moduleTypeId === undefined) {
25
+ throw new Error('the ERC-7579 suite needs reader, account, module and moduleTypeId on the target');
26
+ }
27
+ return { reader, account, module, moduleTypeId };
28
+ }
29
+ /**
30
+ * Narrows a target to the ERC-7579 module-lifecycle fields, or throws. The
31
+ * mutation checks need both the read port and the explicit write port, so a
32
+ * plain read-only run fails them loudly instead of silently skipping.
33
+ */
34
+ export function moduleAdminTarget(target) {
35
+ const { reader, moduleAdmin, account, module, moduleTypeId } = target;
36
+ if (reader === undefined ||
37
+ moduleAdmin === undefined ||
38
+ account === undefined ||
39
+ module === undefined ||
40
+ moduleTypeId === undefined) {
41
+ throw new Error('the ERC-7579 module lifecycle checks need reader, moduleAdmin, account, module and moduleTypeId on the target');
42
+ }
43
+ return { reader, moduleAdmin, account, module, moduleTypeId };
44
+ }
45
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;CACA,CAAC;AAIX;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAS;IACrC,KAAK,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAS;CAC9B,CAAC;AA8IX,kEAAkE;AAClE,MAAM,UAAU,aAAa,CAAC,MAAmB;IAM/C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IACzD,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QACxG,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IAOnD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IACtE,IACE,MAAM,KAAK,SAAS;QACpB,WAAW,KAAK,SAAS;QACzB,OAAO,KAAK,SAAS;QACrB,MAAM,KAAK,SAAS;QACpB,YAAY,KAAK,SAAS,EAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAChE,CAAC"}