PR #25 (squash-merged via Gitea API)
Some checks failed
CI / Frontend Lint (push) Has been cancelled
CI / Frontend Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Frontend E2E Tests (push) Has been cancelled
CI / Orchestrator Build (push) Has been cancelled
CI / Orchestrator Unit Tests (push) Has been cancelled
CI / Orchestrator E2E (Testcontainers) (push) Has been cancelled
CI / Contracts Compile (push) Has been cancelled
CI / Contracts Test (push) Has been cancelled
Security Scan / Dependency Vulnerability Scan (push) Has been cancelled
Security Scan / OWASP ZAP Scan (push) Has been cancelled

This commit was merged in pull request #25.
This commit is contained in:
2026-04-22 21:11:52 +00:00
parent 21d49595d0
commit a9fbb39889
5 changed files with 353 additions and 2 deletions

View File

@@ -25,7 +25,12 @@ import { logger } from "../logging/logger";
import type { Plan } from "../types/plan";
const NOTARY_REGISTRY_ABI = [
"function registerPlan(bytes32 planId, tuple(uint8 stepType, address target, uint256 amount, bytes data)[] steps, address creator) external",
// Step tuple order must match IComboHandler.Step exactly:
// (StepType stepType, bytes data, address target, uint256 value)
// Any divergence changes the canonical signature and therefore the
// function selector — the call would silently miss and the contract
// would revert with no revert data.
"function registerPlan(bytes32 planId, tuple(uint8 stepType, bytes data, address target, uint256 value)[] steps, address creator) external",
"function finalizePlan(bytes32 planId, bool success) external",
"function getPlan(bytes32 planId) view returns (tuple(bytes32 planHash, address creator, uint256 registeredAt, uint256 finalizedAt, bool success, bytes32 receiptHash))",
"event PlanRegistered(bytes32 indexed planId, address indexed creator, bytes32 planHash)",
@@ -108,7 +113,13 @@ function getContract(cfg: NotaryConfig): {
if (cached && cached.cfg.contractAddress === cfg.contractAddress) {
return { contract: cached.contract, wallet: cached.wallet };
}
const provider = new ethers.JsonRpcProvider(cfg.rpcUrl);
// cacheTimeout=-1 disables the 250ms response cache — otherwise
// back-to-back anchor+finalize calls read a stale getTransactionCount
// and collide on nonce, particularly on fast (ganache/hardhat) chains.
const provider = new ethers.JsonRpcProvider(cfg.rpcUrl, cfg.chainId, {
staticNetwork: true,
cacheTimeout: -1,
});
const wallet = new ethers.Wallet(cfg.privateKey!, provider);
const contract = new ethers.Contract(
cfg.contractAddress!,