Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/spec/deployed-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,22 @@ Two distinct EVM accounts deploy AgentKeys contracts. They are **different keys*
| Contract | Address | Bytecode |
|---|---|---|
| `AgentKeysScope` | `0xd44b375daefc65768f417d0f0125b68d5ba7df3b` | 4572 bytes |
| `SidecarRegistry` | `0x1Ac62f1C2D828476a5D784e850a700dC1f17e0bE` | 4572 bytes |
| `SidecarRegistry` | `0x1Ac62f1C2D828476a5D784e850a700dC1f17e0bE` | 7200 bytes |
| `K3EpochCounter` | `0x6c9e675c699a06acefbc156afdee6bfbfe32ccb3` | 591 bytes |
| `CredentialAudit` | `0x63c4545ac01c77cc74044f25b8edea3880224577` | 3043 bytes |
| `P256Verifier` | `0xda5b772f9d6c09abe80414eea908612df9b54749` | (pre-deployed verifier) |
| `K11Verifier` | `0x5a441431f08e0f5f5ed10659620cb4e0e814e627` | (pre-deployed verifier) |
| `CredentialAudit` | `0x63c4545ac01c77cc74044f25b8edea3880224577` | 2584 bytes |
| `P256Verifier` | `0xda5b772f9d6c09abe80414eea908612df9b54749` | 3428 bytes (pre-deployed verifier) |
| `K11Verifier` | `0x5a441431f08e0f5f5ed10659620cb4e0e814e627` | 2033 bytes (pre-deployed verifier) |

### ERC-4337 master infra (#164, deployed 2026-06-02 — prod deployer)

Foundation plumbing for the P-256 smart-account master ([plan](../plan/chain/erc4337-master-account.md)). **NOT yet the live master-auth:** the registry/scope cutover to account-authorization (#164 E3/E7) is a later coordinated redeploy; these are inert until masters are registered as accounts.

| Contract | Address | Notes |
|---|---|---|
| `EntryPoint` (ERC-4337 v0.7) | `0x6672E1b315332167aBA12E0B1d3532a7e9B1ADE9` | canonical eth-infinitism v0.7 bytecode; landed a UserOp end-to-end in the spike |
| `P256AccountFactory` | `0x1ccCe65b22De81aDA4F378FeAf7503d93f5d27a3` | CREATE2 factory; `constructor(entryPoint, k11Verifier)`; wired to the live `K11Verifier`; mainnet CREATE2 determinism smoke-verified |
| `EntryPoint` (ERC-4337 v0.7) | `0x6672E1b315332167aBA12E0B1d3532a7e9B1ADE9` | 11810 bytes; canonical eth-infinitism v0.7 bytecode; landed a UserOp end-to-end in the spike |
| `P256AccountFactory` | `0x1ccCe65b22De81aDA4F378FeAf7503d93f5d27a3` | 4591 bytes; CREATE2 factory; `constructor(entryPoint, k11Verifier)`; wired to the live `K11Verifier`; mainnet CREATE2 determinism smoke-verified |

> **`VerifyingPaymaster` is intentionally NOT deployed.** The spike and current flow submit UserOps via direct `EntryPoint.handleOps` from a pre-funded account — no paymaster needed. [`crates/agentkeys-chain/src/VerifyingPaymaster.sol`](../../crates/agentkeys-chain/src/VerifyingPaymaster.sol) is kept in source for the optional gas-sponsorship path; deploy it only when sponsored UserOps are required, then add its address here and in `operator-workstation.env`.

### Test / CI deploy (Heima mainnet — test deployer)

Expand Down
3 changes: 3 additions & 0 deletions scripts/operator-workstation.env
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ HEIMA_DEPLOYER_ADDR_HEIMA=0xdE644936D5B7d5d42032fd08bbA42Fbbfd6663Bc
HEIMA_DEPLOYER_ADDR_HEIMA_PASEO=0xdE644936D5B7d5d42032fd08bbA42Fbbfd6663Bc
P256_VERIFIER_ADDRESS_HEIMA=0xda5b772f9d6c09abe80414eea908612df9b54749
K11_VERIFIER_ADDRESS_HEIMA=0x5a441431f08e0f5f5ed10659620cb4e0e814e627
# ERC-4337 master infra (#164, prod deployer) — see docs/spec/deployed-contracts.md
ENTRYPOINT_ADDRESS_HEIMA=0x6672E1b315332167aBA12E0B1d3532a7e9B1ADE9
P256_ACCOUNT_FACTORY_ADDRESS_HEIMA=0x1ccCe65b22De81aDA4F378FeAf7503d93f5d27a3

# EC2 + EIP wiring lives in scripts/broker.env (the broker-machine env file)
# — those values identify the broker host, not operator-account identifiers.
Expand Down
49 changes: 44 additions & 5 deletions scripts/verify-heima-contracts.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# scripts/verify-heima-contracts.sh — read-only health-check for the
# four v2 stage-1 contracts deployed to Heima.
# v2 stage-1 contracts (+ the ERC-4337 master infra, when configured)
# deployed to Heima.
#
# What it checks (all read-only RPC, never spends gas):
# 1. eth_getCode for each contract — confirms bytecode is present
Expand All @@ -9,6 +10,8 @@
# 3. AgentKeysScope.registry() points at the deployed SidecarRegistry
# (catches the constructor wiring drift)
# 4. K3EpochCounter.currentEpoch() ≥ 1, signerGovernance != address(0)
# 5. (when configured) ERC-4337 EntryPoint + P256AccountFactory bytecode +
# the factory's entryPoint()/k11Verifier() constructor wiring
#
# Usage:
# bash scripts/verify-heima-contracts.sh
Expand Down Expand Up @@ -49,6 +52,10 @@ SCOPE=$(eval echo \$SCOPE_CONTRACT_ADDRESS_${PROFILE_NAME_UC})
REGISTRY=$(eval echo \$SIDECAR_REGISTRY_ADDRESS_${PROFILE_NAME_UC})
EPOCH=$(eval echo \$K3_EPOCH_COUNTER_ADDRESS_${PROFILE_NAME_UC})
AUDIT=$(eval echo \$CREDENTIAL_AUDIT_ADDRESS_${PROFILE_NAME_UC})
# ERC-4337 master infra (#164) — only set on chains where it's deployed
ENTRYPOINT=$(eval echo \${ENTRYPOINT_ADDRESS_${PROFILE_NAME_UC}:-})
FACTORY=$(eval echo \${P256_ACCOUNT_FACTORY_ADDRESS_${PROFILE_NAME_UC}:-})
K11=$(eval echo \${K11_VERIFIER_ADDRESS_${PROFILE_NAME_UC}:-})

FAILED=0
echo " chain: $AGENTKEYS_CHAIN" >&2
Expand All @@ -60,7 +67,7 @@ echo " CredentialAudit: $AUDIT" >&2
echo >&2

# 1. Bytecode presence
log "1/4 bytecode presence (eth_getCode)"
log "1/5 bytecode presence (eth_getCode)"
for pair in "AgentKeysScope:$SCOPE" "SidecarRegistry:$REGISTRY" "K3EpochCounter:$EPOCH" "CredentialAudit:$AUDIT"; do
name="${pair%%:*}"; addr="${pair##*:}"
code=$(curl -sS -H 'Content-Type: application/json' \
Expand All @@ -74,7 +81,7 @@ for pair in "AgentKeysScope:$SCOPE" "SidecarRegistry:$REGISTRY" "K3EpochCounter:
done

# 2. View functions respond with expected values
log "2/4 view functions return expected constants"
log "2/5 view functions return expected constants"
v=$(cast call "$REGISTRY" "ROLE_CAP_MINT()(uint8)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
[ "$v" = "1" ] && ok "SidecarRegistry.ROLE_CAP_MINT = 1" || fail "SidecarRegistry.ROLE_CAP_MINT: expected 1, got '$v'"
v=$(cast call "$REGISTRY" "ROLE_RECOVERY()(uint8)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
Expand All @@ -85,7 +92,7 @@ v=$(cast call "$AUDIT" "OP_STORE()(uint8)" --rpc-url "$RPC_HTTP" 2>&1 || echo ER
[ "$v" = "0" ] && ok "CredentialAudit.OP_STORE = 0" || fail "CredentialAudit.OP_STORE: expected 0, got '$v'"

# 3. AgentKeysScope.registry() points at the deployed SidecarRegistry
log "3/4 AgentKeysScope.registry() is wired to the deployed SidecarRegistry"
log "3/5 AgentKeysScope.registry() is wired to the deployed SidecarRegistry"
linked=$(cast call "$SCOPE" "registry()(address)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
# Normalize case for comparison
linked_lc=$(printf '%s' "$linked" | tr '[:upper:]' '[:lower:]')
Expand All @@ -97,7 +104,7 @@ else
fi

# 4. K3EpochCounter initialized
log "4/4 K3EpochCounter initialized"
log "4/5 K3EpochCounter initialized"
epoch_val=$(cast call "$EPOCH" "currentEpoch()(uint256)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
gov=$(cast call "$EPOCH" "signerGovernance()(address)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
[ "$epoch_val" -ge 1 ] 2>/dev/null && ok "K3EpochCounter.currentEpoch = $epoch_val" || fail "K3EpochCounter.currentEpoch unset: '$epoch_val'"
Expand All @@ -107,6 +114,38 @@ case "$gov" in
*) ok "K3EpochCounter.signerGovernance = $gov" ;;
esac

# 5. ERC-4337 master infra (only on chains where it's deployed)
log "5/5 ERC-4337 master infra (EntryPoint + P256AccountFactory)"
if [ -z "$ENTRYPOINT" ] || [ -z "$FACTORY" ]; then
ok "skip: no ERC-4337 infra configured for $AGENTKEYS_CHAIN"
else
for pair in "EntryPoint:$ENTRYPOINT" "P256AccountFactory:$FACTORY"; do
name="${pair%%:*}"; addr="${pair##*:}"
code=$(curl -sS -H 'Content-Type: application/json' \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getCode\",\"params\":[\"$addr\",\"latest\"],\"id\":1}" \
"$RPC_HTTP" | jq -r .result)
if [ -z "$code" ] || [ "$code" = "0x" ]; then
fail "$name @ $addr: NO bytecode"
else
ok "$name @ $addr: $((${#code} / 2 - 1)) bytes"
fi
done
fac_ep=$(cast call "$FACTORY" "entryPoint()(address)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
if [ "$(printf '%s' "$fac_ep" | tr '[:upper:]' '[:lower:]')" = "$(printf '%s' "$ENTRYPOINT" | tr '[:upper:]' '[:lower:]')" ]; then
ok "P256AccountFactory.entryPoint() = $fac_ep (matches deployed EntryPoint)"
else
fail "P256AccountFactory.entryPoint() = $fac_ep but ENTRYPOINT_ADDRESS_${PROFILE_NAME_UC} = $ENTRYPOINT"
fi
if [ -n "$K11" ]; then
fac_k11=$(cast call "$FACTORY" "k11Verifier()(address)" --rpc-url "$RPC_HTTP" 2>&1 || echo ERR)
if [ "$(printf '%s' "$fac_k11" | tr '[:upper:]' '[:lower:]')" = "$(printf '%s' "$K11" | tr '[:upper:]' '[:lower:]')" ]; then
ok "P256AccountFactory.k11Verifier() = $fac_k11 (matches deployed K11Verifier)"
else
fail "P256AccountFactory.k11Verifier() = $fac_k11 but K11_VERIFIER_ADDRESS_${PROFILE_NAME_UC} = $K11"
fi
fi
fi

echo >&2
if [ "$FAILED" = "0" ]; then
printf "${C_OK}═══ all checks passed ═══${C_RESET}\n" >&2
Expand Down
Loading