Help us improve
Share bugs, ideas, or general feedback.
From midnight-verify
Verification by running E2E scripts against a local Midnight devnet. Writes SDK test scripts (raw or using testkit-js) that exercise the full transaction pipeline: deploy, call circuits, observe state. Checks devnet health before proceeding. Loaded by the sdk-tester agent. Loads the `midnight-tooling:devnet` skill for infrastructure management.
npx claudepluginhub devrelaicom/midnight-expert --plugin midnight-verifyHow this skill is triggered — by the user, by Claude, or both
Slash command
/midnight-verify:verify-by-devnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are verifying an SDK behavioral claim by running a test script against a live local devnet. Follow these steps in order.
Hub skill for the midnight-verify plugin. Classifies claims by domain, routes to the appropriate domain skill, dispatches sub-agents based on the domain skill's routing, and synthesizes final verdicts. Loaded by the /midnight-verify:verify command — the main thread acts as orchestrator.
This skill should be used when the user asks about the Midnight.js SDK, midnight-js packages, @midnight-ntwrk npm packages, setting up SDK providers, deploying or finding contracts with deployContract or findDeployedContract, calling circuits with callTx or submitCallTx, the transaction lifecycle, SDK provider types (WalletProvider, MidnightProvider, PublicDataProvider, ProofProvider, ZkConfigProvider, PrivateStateProvider), testkit-js testing, observable state subscriptions, contract maintenance and verifier keys, or connecting to the indexer or proof server.
Runs non-interactive, tiered verification protocols (static analysis, compilation, RPC simulation, on-chain, runtime) for loaded Ritual skills, with blocking checks, confidence levels, and automated fixes.
Share bugs, ideas, or general feedback.
You are verifying an SDK behavioral claim by running a test script against a live local devnet. Follow these steps in order.
Do NOT attempt E2E testing without first confirming devnet is healthy. If devnet is unreachable, report Inconclusive immediately. Do not guess at behavior.
Load the midnight-tooling:devnet skill for endpoint URLs and health check patterns. Check that all three services are reachable:
If ANY service is unreachable:
midnight-tooling:devnet skill for instructions on starting the devnet, then retry."Uses the same workspace as the type-checker: .midnight-expert/verify/sdk-workspace/.
If it doesn't exist, follow the same initialization as verify-by-type-check (create workspace, install packages, create tsconfig).
Create a job directory:
JOB_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
mkdir -p .midnight-expert/verify/sdk-workspace/jobs/$JOB_ID
You have two approaches. Choose based on the claim:
Write a self-contained .mjs script that imports SDK packages directly. Best for:
Pros: No extra dependencies. Transparent — mirrors what a DApp developer would write. Easy to debug.
Cons: More boilerplate (provider setup, wallet init, waiting for sync).
Example structure for a raw SDK script:
import { deployContract } from '@midnight-ntwrk/midnight-js-contracts';
import { setNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
import { httpClientProofProvider } from '@midnight-ntwrk/midnight-js-http-client-proof-provider';
import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-public-data-provider';
import { NodeZkConfigProvider } from '@midnight-ntwrk/midnight-js-node-zk-config-provider';
import { levelPrivateStateProvider } from '@midnight-ntwrk/midnight-js-level-private-state-provider';
// 1. Configure network
setNetworkId('devnet');
// 2. Set up providers (load the `midnight-tooling:devnet` skill for URLs)
const providers = {
privateStateProvider: levelPrivateStateProvider({ ... }),
publicDataProvider: indexerPublicDataProvider({ ... }),
zkConfigProvider: new NodeZkConfigProvider({ ... }),
proofProvider: httpClientProofProvider({ ... }),
walletProvider: ..., // from wallet SDK
midnightProvider: ..., // from wallet SDK
};
// 3. Execute the claim
// ... deploy, call, observe ...
// 4. Output structured result
console.log(JSON.stringify({ result: ... }));
Use @midnight-ntwrk/testkit-js for TestEnvironment and wallet management. Best for:
Pros: Handles provider wiring, wallet management, health checks automatically. Less boilerplate for complex scenarios.
Cons: Additional abstraction layer. Don't use when the claim is about SDK primitives that testkit wraps.
Example structure for a testkit-js script:
// Testkit handles environment setup, wallet init, provider wiring
import { createTestEnvironment } from '@midnight-ntwrk/testkit-js';
const env = await createTestEnvironment('undeployed');
// ... use env to deploy contracts, call circuits, observe state
| Scenario | Use |
|---|---|
| "Does function X return Y?" | Raw SDK script |
| "Does deploy work?" | Raw SDK script |
| "Full lifecycle (deploy -> call -> observe -> reconnect)" | testkit-js |
| "Multi-user interaction" | testkit-js |
| "State observation / subscriptions" | testkit-js |
| "Claim is ABOUT testkit behavior" | Raw SDK script |
| "Claim is about provider wiring" | Raw SDK script |
Most E2E tests need a compiled Compact contract. Options:
compact compile --skip-zk — load the midnight-tooling:compact-cli skill for compilation detailsimport CompactStandardLibrary;
export ledger round: Counter;
export circuit increment(): [] {
round.increment(1);
}
Compile it and place the output in the job directory.
Write the chosen script to the job directory:
cat > .midnight-expert/verify/sdk-workspace/jobs/$JOB_ID/test-claim.mjs << 'SCRIPT_EOF'
<script content>
SCRIPT_EOF
Run it:
cd .midnight-expert/verify/sdk-workspace/jobs/$JOB_ID
node test-claim.mjs
Capture stdout and stderr. The script should output structured JSON for programmatic interpretation.
If the script throws: Capture the error. Determine if it's a claim issue (the SDK genuinely doesn't behave as claimed) or a test issue (your script has a bug). If it's a test issue, fix and retry once.
Report format:
### Devnet Execution Report
**Claim:** [verbatim]
**Approach:** [Raw SDK script / testkit-js]
**Test script:**
\`\`\`javascript
[full source]
\`\`\`
**Output:**
\`\`\`
[stdout/stderr]
\`\`\`
**Interpretation:** [Confirmed / Refuted / Inconclusive] — [explanation]
rm -rf .midnight-expert/verify/sdk-workspace/jobs/$JOB_ID
This mode is used ONLY as a fallback for wallet SDK claims when source investigation returned Inconclusive. You will only reach this section if the orchestrator explicitly dispatches you with domain: 'wallet-sdk'.
The wallet SDK requires Docker containers instead of a standalone devnet:
docker ps | grep midnight-node or query the substrate RPC endpointhttp://localhost:6300/api/v3/graphql)http://localhost:6301/health)If ANY container is unreachable:
Reuse the wallet-sdk-workspace at .midnight-expert/verify/wallet-sdk-workspace/. It already has all wallet SDK packages installed.
Write test scripts using the wallet SDK packages directly. The packages/docs-snippets/ in the wallet repo provide reference patterns for common operations (initialization, transfers, swaps, balancing). Use these as hints for script structure but verify behavior through execution.
The rest of the devnet verification flow (choose approach, write script, run, interpret, report, clean up) follows the same pattern as the standard SDK devnet mode.