Skip to content

Commit dad9c5a

Browse files
authored
Merge pull request #138 from PracticalParticle/dev
Dev
2 parents 6b57c0d + 711c46c commit dad9c5a

12 files changed

Lines changed: 1124 additions & 391 deletions

File tree

AGENTS.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
## AGENTS.md – Bloxchain Protocol
2+
3+
This file is a **briefing document for AI agents** working on this repo. It complements `README.md` and the docs under `sdk/typescript/docs`.
4+
5+
Focus areas:
6+
- Core Solidity contracts under `contracts/core`
7+
- TypeScript SDK under `sdk/typescript`
8+
9+
---
10+
11+
## 1. Tech Stack & Targets
12+
13+
- **Language / Runtime**
14+
- Solidity `0.8.34` (upgradeable, OZ upgradeable patterns)
15+
- TypeScript (Viem‑based SDK)
16+
- **Core Domains**
17+
- `contracts/core` – source of truth for all protocol behavior
18+
- `sdk/typescript` – thin, type‑safe wrappers and helpers for the core contracts
19+
- **Do not treat** `contracts/` and `sdk/typescript/` as independent systems: the SDK is an integration layer over the Solidity core.
20+
21+
When in doubt, **derive behavior from Solidity first**, then align the SDK and docs.
22+
23+
---
24+
25+
## 2. Project Structure (for Agents)
26+
27+
Key paths you should care about:
28+
29+
- `contracts/core/`
30+
- `lib/EngineBlox.sol` – central state machine library (`SecureOperationState`, tx lifecycle, RBAC, function schemas, meta‑tx, whitelists).
31+
- `base/BaseStateMachine.sol` – upgrade‑safe wrapper that owns `_secureState` and exposes shared queries and helpers.
32+
- `security/SecureOwnable.sol` – owner / broadcaster / recovery roles, timelock configuration.
33+
- `access/RuntimeRBAC.sol` – dynamic, non‑protected roles and function permissions, batch config.
34+
- `execution/GuardController.sol` – guarded execution, time‑lock workflows, target whitelists.
35+
- `pattern/Account.sol` – abstract pattern that **combines all three components**; basis for account‑style contracts (e.g. `AccountBlox`).
36+
- `lib/utils/SharedValidation.sol` – common validation helpers and custom errors.
37+
- `*/lib/definitions/*.sol` – definition libraries with function schemas, operation types, and default permissions.
38+
39+
- `sdk/typescript/`
40+
- `contracts/core/*.tsx` – class wrappers for core contracts (`SecureOwnable`, `RuntimeRBAC`, `GuardController`, `BaseStateMachine`).
41+
- `lib/EngineBlox.tsx` – TS mirror of `EngineBlox` pure helpers and constants.
42+
- `utils/metaTx/metaTransaction.tsx` – EIP‑712 + meta‑tx helpers that must match the Solidity domain / struct hashes.
43+
- `utils/*` – error handling, validation, interface IDs, ERC‑20 helpers.
44+
- `docs/` – SDK and architecture docs (up‑to‑date; treat as user‑facing source of truth).
45+
46+
---
47+
48+
## 3. Commands for Agents
49+
50+
When you need to **build, test, or regenerate docs**, prefer these:
51+
52+
```bash
53+
# Compile & size‑check contracts (Truffle / Foundry flows may coexist)
54+
npm run compile:foundry
55+
npm run compile:truffle:size
56+
57+
# Run protocol & sanity tests
58+
npm run test:foundry
59+
npm run test:sanity-sdk:core
60+
61+
# Regenerate Solidity‑based docs (NatSpec)
62+
npm run docgen
63+
```
64+
65+
Always keep changes compatible with existing tests; if you modify core behavior, update the relevant sanity scripts under `scripts/sanity-sdk`.
66+
67+
---
68+
69+
## 4. Documentation & Alignment Rules
70+
71+
For **any change to core behavior**:
72+
73+
1. **Solidity first**
74+
- Update the relevant file under `contracts/core`.
75+
- Maintain or improve NatSpec; it is the canonical machine‑readable spec.
76+
2. **SDK second**
77+
- Update the corresponding wrapper under `sdk/typescript/contracts/core`.
78+
- Ensure types in `sdk/typescript/types` and interfaces in `sdk/typescript/interfaces` stay consistent.
79+
3. **Docs third**
80+
- Update or add markdown under `sdk/typescript/docs`, especially:
81+
- `api-reference.md`
82+
- Component guides: `secure-ownable.md`, `runtime-rbac.md`, `guard-controller.md`
83+
- Architecture docs: `bloxchain-architecture.md`, `state-machine-engine.md`, `core-contract-graph.md`, `account-pattern.md`, `getting-started.md`
84+
85+
Agents should **never** introduce new public methods or change signatures without:
86+
- Updating NatSpec
87+
- Updating TS types/wrappers
88+
- Updating affected docs
89+
90+
---
91+
92+
## 5. Code Style & Safety Constraints
93+
94+
High‑level rules for agents:
95+
96+
- **Security first**
97+
- Preserve and extend reentrancy protections (`nonReentrant`, CEI).
98+
- Never weaken input validation or access control (`SharedValidation`, role checks, whitelist checks).
99+
- Do not bypass state‑machine entrypoints with “shortcut” external functions.
100+
- **Upgradeability**
101+
- Core components use OZ upgradeable patterns – **no constructors** on upgradeable contracts.
102+
- Keep storage layout stable; use gaps as already defined.
103+
- **Custom errors over strings**
104+
- Prefer existing custom errors in `SharedValidation` and related libraries.
105+
106+
TypeScript:
107+
- Use existing helpers (e.g. `EngineBlox`, meta‑tx utils, validation helpers) before adding new ad‑hoc logic.
108+
- Keep Viem types (`PublicClient`, `WalletClient`, `Address`, `Hex`) accurate and explicit.
109+
110+
---
111+
112+
## 6. Boundaries & Things Agents Must Not Do
113+
114+
Agents **must not**:
115+
116+
- Commit secrets or modify:
117+
- `.env`
118+
- Deployment keys or secret configs
119+
- Hard‑code private keys, RPC URLs, or production contract addresses in source; use envs or `deployed-addresses.json`.
120+
- Change CI / security enforcement to “work around” tests or linters (e.g. disabling checks, lowering coverage, skipping Slither/Semgrep).
121+
- Remove or weaken timelock, RBAC, or whitelist checks to “simplify” flows.
122+
123+
If an operation requires touching live deployments or production infra, stop and request explicit instructions.
124+
125+
---
126+
127+
## 7. Guidance for Different Agent Types
128+
129+
- **AI audit agents**
130+
- Start from:
131+
- `contracts/core/lib/EngineBlox.sol`
132+
- `contracts/core/base/BaseStateMachine.sol`
133+
- `contracts/core/security/SecureOwnable.sol`
134+
- `contracts/core/access/RuntimeRBAC.sol`
135+
- `contracts/core/execution/GuardController.sol`
136+
- Cross‑reference:
137+
- `sdk/typescript/docs/core-contract-graph.md`
138+
- `sdk/typescript/docs/bloxchain-architecture.md`
139+
- `sdk/typescript/docs/state-machine-engine.md`
140+
- Focus on invariants: role separation, timelock enforcement, meta‑tx replay protection, whitelist enforcement, upgrade safety.
141+
142+
- **AI builder agents**
143+
- Prefer building on **Account‑based contracts** (`contracts/core/pattern/Account.sol` and its implementations).
144+
- Use SDK entrypoints:
145+
- `SecureOwnable`, `RuntimeRBAC`, `GuardController`, `BaseStateMachine` wrappers
146+
- `lib/EngineBlox.tsx` and `utils/metaTx/metaTransaction.tsx`
147+
- Follow examples from:
148+
- `scripts/sanity-sdk/*`
149+
- `sdk/typescript/docs/examples-basic.md`
150+
- `sdk/typescript/docs/getting-started.md`
151+
152+
- **AI operational agents**
153+
- When wiring flows (role config, guard config, meta‑tx ops), follow the same ordering and constraints as the definition libraries:
154+
- `contracts/core/access/lib/definitions/RuntimeRBACDefinitions.sol`
155+
- `contracts/core/execution/lib/definitions/GuardControllerDefinitions.sol`
156+
- Use `deployed-addresses.json` as the canonical source for contract addresses per network.
157+
158+
---
159+
160+
## 8. How to Ask the Repo for Help
161+
162+
When you need more context:
163+
164+
- Read:
165+
- `README.md`
166+
- `sdk/typescript/docs/index.md`
167+
- `sdk/typescript/docs/getting-started.md`
168+
- `sdk/typescript/docs/account-pattern.md`
169+
- Look at:
170+
- Existing tests under `scripts/sanity-sdk`
171+
- NatSpec in the relevant Solidity files
172+
173+
Prefer **deriving intent from tests and NatSpec** over guessing new behaviors. If required behavior is unclear or ambiguous, surface a question to a human rather than inventing protocol‑level semantics.
174+

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,22 +111,22 @@ Addresses are written to **`deployed-addresses.json`**.
111111

112112
| Contract | Address |
113113
|----------|---------|
114-
| EngineBlox | [`0x51c870ce35fecf1917fa633e06c708563deedd2a`](https://sepolia.etherscan.io/address/0x51c870ce35fecf1917fa633e06c708563deedd2a) |
115-
| SecureOwnableDefinitions | [`0x7353a3977bdae344c34cf2a3ab14063bd6408d52`](https://sepolia.etherscan.io/address/0x7353a3977bdae344c34cf2a3ab14063bd6408d52) |
116-
| RuntimeRBACDefinitions | [`0x49b67fe22865b69b7e95cbd1886531ff3a3a3b24`](https://sepolia.etherscan.io/address/0x49b67fe22865b69b7e95cbd1886531ff3a3a3b24) |
117-
| GuardControllerDefinitions | [`0x3fe69cc06dc2484a5fac2af21b9158e9c4f16cd7`](https://sepolia.etherscan.io/address/0x3fe69cc06dc2484a5fac2af21b9158e9c4f16cd7) |
114+
| EngineBlox | [`0xb090b28379f1de23ed81d4a151c7ae693d23ba61`](https://sepolia.etherscan.io/address/0xb090b28379f1de23ed81d4a151c7ae693d23ba61) |
115+
| SecureOwnableDefinitions | [`0xca0bb5092f7abdac176a750f5eb7e747662bfc45`](https://sepolia.etherscan.io/address/0xca0bb5092f7abdac176a750f5eb7e747662bfc45) |
116+
| RuntimeRBACDefinitions | [`0x6a2d53655c38ba4bba11afaf7700a1edce54bfc4`](https://sepolia.etherscan.io/address/0x6a2d53655c38ba4bba11afaf7700a1edce54bfc4) |
117+
| GuardControllerDefinitions | [`0x0fdfede18ae02da6116154f2beff0c6c5379ffd1`](https://sepolia.etherscan.io/address/0x0fdfede18ae02da6116154f2beff0c6c5379ffd1) |
118118

119119
#### Account
120120

121121
| Contract | Address |
122122
|----------|---------|
123-
| AccountBlox | [`0xa44c8f4f70b9615278544b6cc89a2fb5ef609522`](https://sepolia.etherscan.io/address/0xa44c8f4f70b9615278544b6cc89a2fb5ef609522) |
123+
| AccountBlox | [`0x05afa7bfd78d60e4affec9a3194b12aea3b28479`](https://sepolia.etherscan.io/address/0x05afa7bfd78d60e4affec9a3194b12aea3b28479) |
124124

125125
#### Examples
126126

127127
| Contract | Address |
128128
|----------|---------|
129-
| CopyBlox | [`0x1731bd93e9275983aec8813562af2fbba1d5fa68`](https://sepolia.etherscan.io/address/0x1731bd93e9275983aec8813562af2fbba1d5fa68) |
129+
| CopyBlox | [`0xa5f9dbde2b3ac26f6cf78e0e4d93d7bfe47e80da`](https://sepolia.etherscan.io/address/0xa5f9dbde2b3ac26f6cf78e0e4d93d7bfe47e80da) |
130130

131131
## 📖 Usage Examples
132132

migrations/2_deploy_guardian_contracts.cjs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ module.exports = async function(deployer, network, accounts) {
8585
await deployer.deploy(AccountBlox);
8686
accountBlox = await AccountBlox.deployed();
8787
console.log("✅ AccountBlox deployed at:", accountBlox.address);
88+
8889
// Get web3 from deployed contract instance (available for error handling)
8990
const web3 = accountBlox.constructor.web3 || global.web3;
9091

@@ -96,9 +97,6 @@ module.exports = async function(deployer, network, accounts) {
9697
console.log(` ⚠️ Warning: Nonce sync failed after max retries, proceeding anyway`);
9798
}
9899

99-
// Save network info to artifact (fixes issue when network_id is "*")
100-
await saveArtifactNetwork(AccountBlox, accountBlox.address, web3, network);
101-
102100
// Initialize AccountBlox
103101
console.log("🔧 Initializing AccountBlox...");
104102
try {
@@ -111,27 +109,60 @@ module.exports = async function(deployer, network, accounts) {
111109
);
112110
console.log("✅ AccountBlox initialized successfully");
113111
console.log(" Transaction hash:", tx.tx);
112+
113+
// Save network info to artifact only after successful initialization
114+
await saveArtifactNetwork(AccountBlox, accountBlox.address, web3, network);
114115
} catch (error) {
115116
console.log("❌ AccountBlox initialization failed:");
116117
console.log(" Error message:", error.message);
117118
console.log(" Error reason:", error.reason);
118119
console.log(" Error data:", error.data);
119120
console.log(" Full error:", JSON.stringify(error, null, 2));
121+
122+
// If the provider threw a connection error after broadcasting the tx,
123+
// it's possible that the contract was actually initialized on-chain.
124+
// Check the owner() state to detect this and avoid double-initializing.
125+
let initializedOnChain = false;
126+
try {
127+
const currentOwner = await accountBlox.owner();
128+
if (currentOwner && currentOwner !== "0x0000000000000000000000000000000000000000") {
129+
initializedOnChain = true;
130+
console.log("⚠️ initialize() reported an error, but owner() is set on-chain:", currentOwner);
131+
console.log(" Treating AccountBlox as initialized based on contract state.");
132+
} else {
133+
console.log(" owner() check indicates AccountBlox is not initialized (owner is zero address).");
134+
}
135+
} catch (ownerCheckError) {
136+
console.log(" Additional owner() check failed:", ownerCheckError.message);
137+
}
120138

121-
// Try to decode the error if it's a revert
122-
if (error.data) {
139+
if (initializedOnChain) {
140+
// In this case, persist network info so sanity tests and tooling
141+
// can still discover the deployed/initialized contract.
123142
try {
124-
const decodedError = await web3.eth.call({
125-
to: accountBlox.address,
126-
data: error.data
127-
});
128-
console.log(" Decoded error data:", decodedError);
129-
} catch (decodeError) {
130-
console.log(" Could not decode error data:", decodeError.message);
143+
await saveArtifactNetwork(AccountBlox, accountBlox.address, web3, network);
144+
console.log("✅ Saved AccountBlox network info after owner() state check.");
145+
} catch (saveError) {
146+
console.log("⚠️ Failed to save AccountBlox network info after owner() check:", saveError.message);
131147
}
148+
} else {
149+
// Try to decode the error if it's a revert
150+
if (error.data) {
151+
try {
152+
const decodedError = await web3.eth.call({
153+
to: accountBlox.address,
154+
data: error.data
155+
});
156+
console.log(" Decoded error data:", decodedError);
157+
} catch (decodeError) {
158+
console.log(" Could not decode error data:", decodeError.message);
159+
}
160+
}
161+
162+
console.log("⚠️ Contract deployed but not initialized. This must be resolved before using this deployment.");
163+
// Fail the migration so callers know initialization did not succeed
164+
throw new Error("AccountBlox initialization failed – migration aborted.");
132165
}
133-
134-
console.log("⚠️ Contract deployed but not initialized. This may be expected for upgradeable contracts.");
135166
}
136167
} else {
137168
console.log("\n📦 Step 2: Skipping AccountBlox deployment (disabled)");

scripts/deployment/deploy-foundation-libraries.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,15 @@ async function main() {
191191
],
192192
account: deployerAccount,
193193
});
194-
await waitForTransactionReceipt(publicClient, { hash: initHash });
194+
const initReceipt = await waitForTransactionReceipt(publicClient, { hash: initHash });
195+
if (initReceipt.status !== "success" && initReceipt.status !== 1n) {
196+
console.error(
197+
`⚠️ AccountBlox initialization transaction did not succeed (status: ${String(
198+
initReceipt.status
199+
)}). Please inspect tx: ${initHash}`
200+
);
201+
throw new Error("AccountBlox initialization failed");
202+
}
195203
console.log(` ✅ AccountBlox initialized (tx: ${initHash})`);
196204

197205
console.log("\n🎉 Foundation libraries deployment complete.");

0 commit comments

Comments
 (0)