Skip to content

feat: shared regtest env with .env auto-discovery#1

Merged
Kukks merged 50 commits intomasterfrom
feat/shared-regtest-env-discovery
Mar 30, 2026
Merged

feat: shared regtest env with .env auto-discovery#1
Kukks merged 50 commits intomasterfrom
feat/shared-regtest-env-discovery

Conversation

@Kukks
Copy link
Copy Markdown
Contributor

@Kukks Kukks commented Mar 26, 2026

Summary

  • Add lib/env.sh with shared load_env() function used by all scripts
  • Add .env auto-discovery chain (.env.defaults base + first override from --env / ../.env.regtest / .env)
  • Add ARKD_IMAGE / ARKD_WALLET_IMAGE override variables with compose overlay
  • Make all start-env.sh sections idempotent (skip setup if services already running)
  • Add service summary output on startup
  • Add missing submodule detection with helpful error message
  • Update README with submodule usage and CI integration docs

Context

This enables arkade-regtest to be used as a git submodule across ts-sdk, boltz-swap, and dotnet-sdk. See docs/superpowers/specs/2026-03-26-shared-regtest-across-sdks-design.md.

Test plan

  • ./start-env.sh works from repo root (no override)
  • ./start-env.sh --env /path/to/.env works with explicit override
  • Place .env.regtest in parent dir, run from submodule — override detected
  • Set ARKD_IMAGE=ghcr.io/arkade-os/arkd:v0.9.0 in override — custom arkd starts
  • Run ./start-env.sh twice — second run skips already-running services
  • ./clean-env.sh && ./start-env.sh — clean restart works

Kukks added 5 commits March 26, 2026 00:35
Defines the approach for making arkade-regtest the single source of
truth for regtest infrastructure across ts-sdk, boltz-swap, and
dotnet-sdk via git submodules with .env overrides.
- Clarify .env discovery as "base + overlay" not "first found wins"
- Specify ARKD_IMAGE override mechanism (stop nigiri arkd, start custom)
- Remove NIGIRI_USE_SYSTEM (redundant with existing NIGIRI_BRANCH)
- Detail idempotent start detection logic
- Fix cache key to include .env.regtest
- Fix port summary to match actual service names
- Note new vars need export in start-env.sh
11 tasks: arkade-regtest changes (1-7), SDK integrations (8-10),
README update (11). Addresses review feedback: merged idempotent
start with ARKD_IMAGE override, fixed cleanup detection, clarified
merge ordering for SDK tasks.
- Add lib/env.sh with shared load_env() function used by all scripts
- Add .env auto-discovery chain: .env.defaults base + first override
  from --env flag > ../.env.regtest > .env
- Add ARKD_IMAGE / ARKD_WALLET_IMAGE config vars with compose overlay
  (docker-compose.arkd-override.yml) for custom arkd versions
- Make all start-env.sh sections idempotent (skip if already running)
- Add service summary output on startup
- Add missing submodule detection with helpful error message
- Update stop-env.sh and clean-env.sh for arkd-override cleanup
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

🔍 Arkana PR Review — ArkLabsHQ/arkade-regtest#1

Solid foundation for shared regtest infrastructure. The .env auto-discovery chain, idempotent start, and ARKD_IMAGE override mechanism are well-designed. A few items worth addressing:


Security

1. Shell injection via source "$override" (lib/env.sh)
The ../.env.regtest auto-discovery sources arbitrary files from the parent directory. In the submodule use case, this is the consuming repo (controlled by the dev), so risk is low. But worth documenting explicitly that .env.regtest files are sourced as shell, not parsed as key-value — meaning arbitrary commands in an override file will execute. A comment in lib/env.sh would suffice.

Correctness

2. Fragile custom-arkd detection (grep -v 'nigiri')
In clean-env.sh:30 and stop-env.sh:32, custom arkd is detected by checking if the container image name does NOT contain "nigiri":

docker inspect ark --format '{{.Config.Image}}' 2>/dev/null | grep -v 'nigiri'

This breaks if a custom image name happens to contain "nigiri" (unlikely but technically possible). A more robust approach: compare against a known default image, or store a marker file when the override is activated.

3. setup_arkd_fees runs unconditionally
In start-env.sh, the fulmine and LND setup got idempotent guards, but setup_arkd_fees at line ~332 runs every time. If setup_arkd_fees is not idempotent (e.g., it appends config or hits a non-idempotent API), this could cause drift on repeated start-env.sh runs. Worth checking if it needs a guard.

4. Fulmine status check path

fulmine_status=$(curl -s http://localhost:${FULMINE_API_PORT}/api/v1/wallet/status ...)

Confirm the Fulmine API path is correct — if Fulmine uses a different status endpoint, this check silently fails and re-runs setup every time (which may be fine, but not truly idempotent).

Minor

5. Docker compose variable interpolation in cleanup scripts
Good catch exporting ARKD_IMAGE/ARKD_WALLET_IMAGE in both clean-env.sh and stop-env.sh — docker-compose needs these for interpolation even during teardown.

6. Plan docs reference Windows paths
The plan (docs/superpowers/plans/...) references C:\Git\ts-sdk etc. These are internal working notes, so cosmetic only, but if the docs are intended for broader consumption, normalizing to Unix paths would be cleaner.

Cross-Repo Impact

This PR is the prerequisite for the SDK integration PRs (ts-sdk, boltz-swap, dotnet-sdk). The design spec is thorough — the .env.regtest pattern with per-SDK version pins is a clean solution for the version-drift problem across SDKs.

Architecture is sound. The separation of concerns (arkade-regtest owns infra, SDKs own test setup) is the right call. The idempotent start + summary output significantly improves DX.


Reviewed by Arkana 🔍

Add fulmine-delegator container for delegation tests (ports 7010-7012).
Includes wallet setup, funding, and settlement in start-env.sh.
Needed by dotnet-sdk E2E delegation tests.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

🔍 Arkana Review — arkade-regtest#1

Solid foundation for shared regtest infra. The .env layering, idempotent start, and arkd image override are well designed.

Highlights

  • .env auto-discovery chain (--env > ../.env.regtest > .env) is clean and predictable for submodule consumers
  • Idempotent start — checking running containers before acting avoids the "blow everything up on re-run" problem all the SDK compose files had
  • Delegator service added to the overlay stack — good, ts-sdk and dotnet-sdk tests need this
  • Submodule missing detection with helpful error message is a nice touch

Observations

1. Arkd override detection in stop/clean is fragile

docker inspect ark --format '{{.Config.Image}}' 2>/dev/null | grep -v 'nigiri'

This assumes nigiri-managed arkd images contain "nigiri" in the image name. If nigiri ever uses ghcr.io/arkade-os/arkd:latest (which it might on the bump-arkd branch), the grep would incorrectly match. Safer approach: compare against $ARKD_IMAGE directly:

if [ -n "${ARKD_IMAGE:-}" ] && docker ps --format '{{.Names}}' | grep -q '^ark$'; then

Since ARKD_IMAGE is only non-empty when an override was requested, this is both simpler and more reliable.

2. DELEGATOR_GRPC_PORT/API_PORT/HTTP_PORT not exported in start-env.sh
The delegator ports are defined in .env.defaults and used in docker-compose.ark.yml via ${DELEGATOR_*_PORT} interpolation, but the export block in start-env.sh (line ~39) doesn't include them. Docker compose will fall back to the host environment or empty string. Should add:

export DELEGATOR_GRPC_PORT DELEGATOR_API_PORT DELEGATOR_HTTP_PORT

3. Spec/plan docs (1290 lines) — useful context but these are implementation artifacts. Consider moving them to a wiki or removing after all SDK PRs land.

Cross-Repo Impact

This is the dependency for:

All three SDK PRs point their .gitmodules to branch feat/shared-regtest-env-discovery. After this PR merges, those submodule refs need updating to master.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

Followup review (commit 1d9db91): Retry bump 15→30 for delegator readiness — reasonable given arkd cold-start times. LGTM.

One minor note: the delegator wait loop sleeps 2s per attempt, so 30 attempts = 60s max. The arkd wallet init loop above uses 30 attempts × 3s = 90s. Might be worth aligning the delegator to 3s intervals too, since it depends on arkd being fully ready (not just the fulmine binary starting). Currently it could time out if arkd takes >60s to serve.

Add ARKD_SCHEDULER_TYPE, ARKD_ALLOW_CSV_BLOCK_TYPE, ARKD_VTXO_TREE_EXPIRY,
ARKD_UNILATERAL_EXIT_DELAY, ARKD_BOARDING_EXIT_DELAY, ARKD_LIVE_STORE_TYPE
to the arkd-override compose. Each SDK can now tune arkd behavior via .env.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

🔍 Arkana Review — Updated Commits

Scope: .env auto-discovery chain, ARKD_IMAGE override, arkd-override compose, delegator service, idempotent start, README.

Architecture

Clean layered design. The lib/env.sh extraction avoids duplication across start/stop/clean scripts. The override priority chain (--env > ../.env.regtest > .env) is intuitive for submodule consumers.

Key Observations

  1. arkd-override compose (docker-compose.arkd-override.yml): Well-structured — stops nigiri's built-in arkd and replaces with pinned images. The environment variable passthrough with defaults (${ARKD_SCHEDULER_TYPE:-block}) is good defensive practice.

  2. Delegator service addition to docker-compose.ark.yml: This was missing from the original — needed for dotnet-sdk tests that use delegation. Good catch adding it here so all SDKs get it.

  3. Idempotent start: The script skipping already-running services is important for dev UX. Repeated ./start-env.sh calls won't blow up existing state.

  4. clean-env.sh custom arkd detection: The docker inspect check for non-nigiri images is a nice touch to handle both paths correctly.

Cross-Repo Impact

This PR is the foundation for:

  • arkade-os/ts-sdk#386 (pins arkd v0.9.0)
  • arkade-os/boltz-swap#106 (pins arkd v0.8.11)
  • arkade-os/dotnet-sdk#56 (uses nigiri's built-in arkd, pins fulmine)

All three are open and reference this PR. The .gitmodules in all consumers point to branch feat/shared-regtest-env-discovery — ensure this merges before or simultaneously with the consumer PRs, or they'll fail to resolve the submodule.

Docs

The docs/superpowers/ directory contains the implementation plan and design spec (1,290 lines). These are useful for traceability but consider whether they should live in the repo long-term or be extracted to a wiki/docs repo.

Nit

  • README.md still references https://github.com/arkade-os/arkade-regtest.git as the submodule URL but the repo is under ArkLabsHQ. The .gitmodules in consumer repos correctly use ArkLabsHQ — just ensure consistency.

Looks solid. The coordinated rollout across all four repos is well-planned.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

Followup review (commit 45cae46)

Adds missing export for delegator ports (DELEGATOR_GRPC_PORT, DELEGATOR_API_PORT, DELEGATOR_HTTP_PORT) and arkd config vars (ARKD_SCHEDULER_TYPE, ARKD_ALLOW_CSV_BLOCK_TYPE, etc.) needed for docker-compose interpolation.

Without these exports, the delegator and arkd-override compose files would get empty strings for these variables. Good catch — LGTM.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

Iterative review (new commits since last review)

Two changes:

  1. start-env.sh — always recreate arkd when ARKD_IMAGE is set: Removes the idempotent "skip if already running with correct image" check. This is the right call — the old check compared image name only, so env var changes (e.g. ARKD_VTXO_TREE_EXPIRY) would not be picked up by a running container. Always recreating ensures the override compose file re-reads current env vars.

  2. New configurable arkd vars in compose overlay: ARKD_SCHEDULER_TYPE, ARKD_ALLOW_CSV_BLOCK_TYPE, ARKD_VTXO_TREE_EXPIRY, ARKD_UNILATERAL_EXIT_DELAY, ARKD_BOARDING_EXIT_DELAY, ARKD_LIVE_STORE_TYPE — all with sensible defaults matching arkd current defaults.

Clean and correct. The export fix ensures docker-compose can interpolate these vars. The forced recreate is a reasonable tradeoff (few extra seconds) for correctness.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

Iterative review (commit 45a3b0f)

Adds ARKD_WALLET_SIGNER_KEY passthrough to the arkd-override compose. This is needed because old per-SDK compose files set this key explicitly — without it, arkd-wallet would use its default key generation, potentially breaking test determinism for tests expecting a specific server pubkey.

The default in .env.defaults (afcd3fa1...) matches the old SDK compose files. SDKs can override via .env.regtest if needed.

Good fix — LGTM ✅

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

Iterative reviewe368a88 (fix: add missing env vars to override compose)

Good catch. Both additions are necessary:

  • ARKD_WALLET_NETWORK=regtest — without this, the wallet defaults to mainnet and fails to connect to the regtest nbxplorer
  • ARKD_UNLOCKER_TYPE=env — required to pair with ARKD_UNLOCKER_PASSWORD; without it arkd tries interactive unlock and hangs

These are critical for any SDK using ARKD_IMAGE overrides. All three consumer PRs (ts-sdk#386, boltz-swap#106, dotnet-sdk#56) bump to this ref — good coordination.

LGTM ✅

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

🔍 Review: Shared regtest env with .env auto-discovery

Overall: Solid infrastructure work. The .env layering, idempotent start, and arkd override mechanism are well-designed for the submodule consumption pattern. A few observations on the implementation.

✅ What works well

  • lib/env.sh extraction — single source of truth for the env loading chain, used consistently across start/stop/clean scripts.
  • .env discovery priority (--env > ../.env.regtest > .env) — the parent-dir .env.regtest convention is exactly right for submodule usage.
  • Idempotent start — checking running containers before setup avoids the common "run twice, break everything" problem. Good use of docker ps + container name checks.
  • Submodule detection — the .env.defaults existence check with helpful error message is a nice DX touch.
  • Compose overlay for custom arkd — clean separation. The override compose joins the nigiri network and maps the same ports, so all downstream services connect transparently.

Observations & Suggestions

  1. Hardcoded signer key in .env.defaults (ARKD_WALLET_SIGNER_KEY=afcd3fa...):
    This is a regtest-only key, so not a real security concern, but worth a comment in .env.defaults explicitly noting it's a well-known regtest key. Prevents someone from mistakenly thinking it's a leaked key.

  2. docker inspect nigiri detection in clean/stop — the pattern docker inspect ark --format '{{.Config.Image}}' | grep -v 'nigiri' is fragile if nigiri ever changes their image naming. Consider checking against the exact $ARKD_IMAGE value instead (which is loaded via load_env). Since you already export ARKD_IMAGE, the check could be [ -n "${ARKD_IMAGE:-}" ] — if the env says custom image was configured, clean it up.

  3. Delegator service addition — nice that this comes with the same idempotent wallet setup pattern. The FULMINE_DELEGATOR_ENABLED=true env var enables the delegator mode in the same fulmine image — clean reuse.

  4. start-env.sh custom arkd section always recreates (line "Always recreate with override compose to ensure custom env vars are applied"):
    This means start-env.sh is idempotent for everything except custom arkd, which gets torn down and recreated every run. This is intentional per the comment, but it means running start-env.sh twice with ARKD_IMAGE set will reset arkd state (wallet, VTXOs, etc.). Worth documenting this behavior difference — or checking if the image + env vars match before deciding to recreate.

  5. setup_delegator_wallet funding amount$NIGIRI faucet "$delegator_address" 0.01 is 0.01 BTC (1M sats). Then it settles, which triggers a round. The 15-second sleep + 3 blocks afterward may be tight if the round hasn't completed. Consider polling api/v1/wallet/balance for confirmed off-chain balance instead of a fixed sleep.

  6. README CI example — the actions/cache key hashes both regtest/.env.defaults and .env.regtest, which correctly invalidates when either config changes. Good.

  7. Spec + plan docs included — the docs/superpowers/ spec and plan are thorough. The plan covers all three SDK integrations with specific file-level changes. Good reference for the follow-up PRs.

Cross-repo impact

This PR enables the submodule pattern for:

Those PRs are blocked on this one merging to master (or tracking the feature branch as noted in the plan).

No security concerns. All credentials are regtest-only. The compose files don't expose anything beyond localhost.

Looks good for merge after addressing the custom-arkd idempotency question. 👍

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 26, 2026

🔍 Arkana PR Review

PR: feat: shared regtest env with .env auto-discovery

Overview

This PR adds the foundational infrastructure to make arkade-regtest consumable as a git submodule across all Arkade SDKs. Key additions:

  1. lib/env.sh — shared load_env() function with auto-discovery chain (--env > ../.env.regtest > .env)
  2. ARKD_IMAGE / ARKD_WALLET_IMAGE override variables with a dedicated compose overlay
  3. fulmine-delegator service added to docker-compose.ark.yml
  4. Delegator ports exposed on configurable ports (7010-7012)
  5. Idempotent start/stop/clean with arkd-override container detection
  6. Updated README with submodule usage and CI integration docs

Positive Findings

  • Clean layered env loading design — .env.defaults always loads, then exactly one override layers on top
  • docker-compose.arkd-override.yml correctly joins the nigiri external network and maps the same ports, so all services connect seamlessly
  • Good defensive coding — ARKD_WALLET_SIGNER_KEY=${ARKD_WALLET_SIGNER_KEY:-} allows optional signer key injection
  • The fulmine-delegator addition fills a gap needed by ts-sdk delegation tests
  • Cleanup scripts detect custom arkd by inspecting container image rather than file existence — robust

Items to Verify

  1. Submodule branch tracking: .gitmodules in the SDK PRs reference branch = feat/shared-regtest-env-discovery — these should be updated to master once this PR is merged

  2. ARKD_UNLOCKER_TYPE for override arkd: The override compose sets ARKD_UNLOCKER_TYPE=env and ARKD_UNLOCKER_PASSWORD, but the defaults compose (nigiri's built-in arkd) may use a different unlocker type. Verify that wallet init (nigiri ark init) works correctly with both paths

  3. ARKD_ROUND_INTERVAL missing: The override compose doesn't set ARKD_ROUND_INTERVAL. The old ts-sdk and dotnet-sdk docker-compose files set ARKD_ROUND_INTERVAL=10. If this defaults to something longer, integration tests may time out waiting for rounds

  4. Port conflict potential: If nigiri's arkd containers aren't fully stopped before override containers start on the same ports (7070, 6060), there could be transient port conflicts. The docker stop ark ark-wallet followed by docker rm should handle this, but worth testing with slow container shutdown

  5. Large plan document included: docs/superpowers/plans/2026-03-26-shared-regtest-across-sdks.md (1011 lines) is useful as implementation documentation but might be better suited for a wiki or separate tracking rather than living in the repo permanently. Consider moving to a project wiki after the work is complete.

Security

  • No credentials exposed — ARKD_WALLET_SIGNER_KEY is a well-known regtest-only key
  • Docker network configuration is correct (external nigiri network)
  • No production implications — this is purely test infrastructure

Cross-Repo Impact

This is the foundation PR — ts-sdk#386, boltz-swap#106, and dotnet-sdk#56 all depend on this being merged (they currently track the feature branch via .gitmodules).

Overall: well-structured infrastructure improvement. The .env auto-discovery chain is clean and the override mechanism is sound.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana Review — 36c2689 (timeout for note/redeem-notes)

Good fix. arkd note blocking indefinitely on gocron (v0.9.1) is a real CI killer — 60s timeout is appropriate.

One observation: Both the custom-arkd and built-in-arkd paths now have identical note/redeem logic (lines 476-483 and 504-511). Consider extracting to a helper function (fund_and_redeem_notes) to reduce the duplication in this already-long script. Not blocking, but would simplify future changes to this flow.

The two-stage approach (timeout on arkd note, then separate timeout on redeem-notes) correctly isolates which step fails, making diagnostics clear from the warning messages.

LGTM for this commit. ✅

…ttle

The fulmine settle endpoint was blocking indefinitely because:
1. No blocks were mined after faucet funding, so the boarding UTXO
   was never confirmed on-chain
2. The curl call had no timeout, causing the wallet Playwright CI
   to hang for 27+ minutes until the workflow was cancelled

Changes:
- Mine 3 blocks before fulmine settle (matching delegator pattern)
- Add timeout 120 + --max-time 110 to settle calls (fulmine + delegator)
- Make settle non-fatal if it times out
- Add --connect-timeout to all service readiness check curls
- Add --max-time to service status check curls and Boltz pairs check
- Mine blocks + sleep after fulmine settle for commitment tx confirmation
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana Review — ArkLabsHQ/arkade-regtest#1

Scope: Shared regtest environment with .env auto-discovery, ARKD_IMAGE override, idempotent start, delegator wallet support.

Architecture

Clean factoring: lib/env.sh shared loader, docker-compose.arkd-override.yml for custom arkd versions, auto-discovery chain (--env > ../.env.regtest > .env). The idempotent start pattern (check if services running → skip) is solid for both CI caching and dev workflow.

Observations

  1. docker-compose.arkd-override.ymlARKD_UNLOCKER_TYPE is set to env but the variable is not exported from start-env.sh. It works because the compose file hardcodes ARKD_UNLOCKER_TYPE=env, but if future SDKs need to override the unlocker type, this should be configurable.

  2. Wallet init flow duplication — The custom-arkd path (admin API init) vs nigiri-arkd path (CLI init) share the faucet+note logic. Lines ~430-445 and ~460-475 are near-identical. A fund_arkd_wallet() helper would reduce this.

  3. setup_delegator_wallet() — Good addition. The timeout 120 on settle is sensible for CI environments where rounds may take time.

  4. Fulmine settle — Added timeout 120 curl -s --max-time 110 with WARNING instead of hard fail — correct trade-off for CI resilience.

  5. Missing export in clean-env.sh — The new delegator ports (DELEGATOR_GRPC_PORT, DELEGATOR_API_PORT, DELEGATOR_HTTP_PORT) are exported in start-env.sh but the export block in clean-env.sh does not include them. This could cause interpolation warnings when docker-compose processes docker-compose.ark.yml during cleanup if those variables are referenced there.

  6. Nigiri build caching — The README CI example correctly caches regtest/_build keyed on both config files. Good.

  7. Spec and plan docs — Well-structured. The plan at docs/superpowers/plans/ is comprehensive and matches what the SDK PRs actually implement.

Cross-Repo Impact

This is the foundational PR for ts-sdk#386, boltz-swap#106, and wallet#492. All three reference the feat/shared-regtest-env-discovery branch via .gitmodules. This PR must merge first (or the submodule branch must be rebased onto master) before the SDK PRs can work with submodules: true in CI.

Overall: solid infrastructure work. The main risk is CI timing — the idempotent checks and generous timeouts should handle most flakiness.

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review

PR: feat: shared regtest env with .env auto-discovery
Author: Kukks | +1849 / -80 across 10 files


Overview

Major infrastructure PR that transforms arkade-regtest from a standalone tool into a shared submodule-ready regtest environment. The .env auto-discovery chain, ARKD_IMAGE override mechanism, idempotent start, and new delegator service are all well-designed.

✅ What looks good

  1. lib/env.sh extraction — clean DRY pattern for env loading across all three scripts
  2. Submodule detection — helpful error message when .env.defaults is missing
  3. Idempotent start — checking for running services before setup is solid for developer iteration speed
  4. Diagnostic dumps on failure — the docker logs + docker ps output on timeout will save debugging time in CI
  5. Timeout guardstimeout 60 on arkd note and redeem-notes, --connect-timeout / --max-time on curl calls — good robustness improvements
  6. Bitcoin Core restart moved after arkd init — avoids nbxplorer disruption, smart reordering
  7. Mining blocks before settlegeneratetoaddress 3 before Fulmine/delegator settle ensures boarding UTXOs are confirmed

⚠️ Issues to consider

1. ARKD_ROUND_INTERVAL not exported (minor bug)

.env.defaults defines ARKD_ROUND_INTERVAL=10 and docker-compose.arkd-override.yml references ${ARKD_ROUND_INTERVAL:-10}, but the export block in start-env.sh exports ARKD_SESSION_DURATION but not ARKD_ROUND_INTERVAL. The compose fallback (:-10) masks this, but overrides via .env.regtest won't propagate.

# start-env.sh export block — add ARKD_ROUND_INTERVAL
export ARKD_LOG_LEVEL ARKD_SESSION_DURATION ARKD_ROUND_INTERVAL

2. Arkd override is not idempotent (spec divergence)

The spec (Section 1.3) says to check if the running ark container already has the correct image and skip if so. The implementation always tears down ark containers when ARKD_IMAGE is set, even on re-runs. This means start-env.sh run twice will restart arkd unnecessarily, losing wallet state (volumes are also removed).

If intentional (clean state guarantee), the spec should be updated. If not, consider:

if docker ps --format '{{.Names}}' | grep -q '^ark$' && \
   [ "$(docker inspect ark --format '{{.Config.Image}}')" = "$ARKD_IMAGE" ]; then
  log "Custom arkd already running with correct image, skipping..."
else
  # ... existing teardown + start logic
fi

3. Fragile nigiri image detection in cleanup scripts

clean-env.sh and stop-env.sh detect custom arkd via docker inspect ark --format '{{.Config.Image}}' | grep -v 'nigiri'. If a custom image name ever contains "nigiri" (unlikely but possible), cleanup would silently skip. A more robust check:

# Compare against known nigiri image pattern
ark_image=$(docker inspect ark --format '{{.Config.Image}}' 2>/dev/null || echo "")
if [ -n "$ark_image" ] && [ -n "${ARKD_IMAGE:-}" ] && [ "$ark_image" = "$ARKD_IMAGE" ]; then

4. ARKD_WALLET_SIGNER_KEY hardcoded in .env.defaults

The key afcd3fa10f82a05fddc9574fdb13b3991b568e89cc39a72ba4401df8abef35f0 is committed in plaintext. This is fine for regtest, but worth a comment clarifying it's regtest-only. Someone might copy this pattern for testnet/mainnet.

5. Delegator ports not exported in clean-env.sh and stop-env.sh

The new DELEGATOR_*_PORT variables are exported in start-env.sh but not in clean-env.sh or stop-env.sh. Currently those scripts don't reference delegator ports directly, but if the delegator compose needs cleanup in the future, this would be needed for consistency.

📝 Nits

  • The plan document (docs/superpowers/plans/) is 1011 lines — great for agentic workers, but consider linking to it from README rather than shipping in the repo long-term
  • setup_delegator_wallet() duplicates the settle + mine pattern from setup_fulmine_wallet() — could extract a settle_and_mine() helper, but not blocking

Security

  • ✅ No mainnet keys or credentials exposed
  • ✅ Regtest-only wallet passwords (secret, password) are appropriate
  • ✅ Ports exposed only on localhost-accessible Docker network
  • ✅ No shell injection vectors beyond standard dotenv sourcing

Cross-repo impact

This PR is the foundation for ts-sdk#386, boltz-swap#106, and wallet#492. Those PRs depend on this being merged to master. The submodule URL in the README uses arkade-os/arkade-regtest but this repo is under ArkLabsHQ — verify the submodule URL matches the actual org.


Verdict: Solid infrastructure work. The idempotency gap (#2) and missing export (#1) are the most impactful items. Everything else is minor.

…ining

After restarting Bitcoin Core for low-fee config, chopsticks loses its
RPC connection and stops mining blocks. Without block mining, the block
scheduler never triggers rounds, causing arkd note, fulmine settle, and
delegator settle to all hang indefinitely.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review — arkade-regtest#1

PR: feat: shared regtest env with .env auto-discovery
Author: @Kukks

Summary

This PR transforms arkade-regtest into a proper shared submodule for all SDK repos. Key changes:

  1. lib/env.sh with load_env() — shared env loading across all scripts with discovery chain: --env > ../.env.regtest > .env
  2. ARKD_IMAGE override — new compose overlay (docker-compose.arkd-override.yml) to swap nigiri's built-in arkd for custom images
  3. Idempotent start — skip services already running, second start-env.sh is a no-op
  4. Delegator (fulmine-delegator) — new service in the overlay stack with dedicated ports
  5. Submodule detection — helpful error when .env.defaults is missing

What Looks Good ✅

  • Clean layered env loading: The load_env() function is well-structured with clear priority. The single-source-of-truth pattern (lib/env.sh) eliminates duplication across start-env.sh, stop-env.sh, clean-env.sh.
  • Idempotent design: Checking docker ps for running containers before setup avoids the most common developer frustration (running start twice and getting errors).
  • Override compose on nigiri network: docker-compose.arkd-override.yml correctly joins the nigiri external network and remaps the same ports (7070, 7071, 6060), so all other services connect seamlessly.
  • Robust Fulmine setup: Adding mining blocks before settle and timeout 120 on settle calls prevents the hanging that was likely causing CI flakes.
  • Comprehensive docs: The spec and plan files are thorough — good for future contributors and agent workers.

Observations & Nits

  1. Hardcoded ARKD_WALLET_SIGNER_KEY in .env.defaults — This is a regtest-only key (afcd3fa...), so not a security concern. But worth a comment in the file noting it's intentionally a fixed test key, to avoid future confusion.

  2. Arkd override detection in cleanup scripts uses grep -v 'nigiri':

    docker inspect ark --format '{{.Config.Image}}' 2>/dev/null | grep -v 'nigiri'

    This heuristic could false-positive if someone names their custom image something containing "nigiri." Consider comparing against the known ARKD_IMAGE variable instead:

    if [ -n "${ARKD_IMAGE:-}" ] && docker ps -a --format '{{.Names}}' | grep -q '^ark$'; then
  3. ARKD_ROUND_INTERVAL=10 in .env.defaults — 10 seconds is aggressive for round interval. In CI this is fine, but if someone uses this locally for manual testing they'll see rapid rounds. Worth noting in a comment.

  4. ARKD_SESSION_DURATION=30 — Same consideration; 30 seconds is short. Fine for automated tests, could surprise manual testers.

  5. Missing DELEGATOR_* port exports in clean-env.sh and stop-env.sh — The new DELEGATOR_GRPC_PORT, DELEGATOR_API_PORT, DELEGATOR_HTTP_PORT are exported in start-env.sh but I don't see them in the cleanup scripts' export blocks. If docker-compose needs them for interpolation during down, this could cause warnings.

  6. ARKD_WALLET_NETWORK=regtest in the override compose — correctly hardcoded since this is only used in regtest context.

Protocol Correctness ✅

  • The arkd environment variables (ARKD_VTXO_TREE_EXPIRY=1024, ARKD_UNILATERAL_EXIT_DELAY=512, ARKD_BOARDING_EXIT_DELAY=2048) are reasonable regtest defaults.
  • ARKD_UNLOCKER_TYPE=env with password from env is correct for automated regtest usage.
  • The ARKD_VTXO_MIN_AMOUNT=1 sat minimum is appropriate for testing.

Cross-Repo Impact

This PR is the foundation for ts-sdk#386, boltz-swap#106, and wallet#492 which add arkade-regtest as a submodule. Those PRs are already open and waiting on this to land.

Verdict

Solid infrastructure work. The observations above are all nits — nothing blocking. The design is sound and the idempotent + override patterns will save significant maintenance across all SDK repos.

After Bitcoin Core restarts, both chopsticks and arkd need to be
restarted. Chopsticks reconnects to Bitcoin Core, but arkd also
needs to re-establish its chain monitoring connection to chopsticks.
Without this, the block scheduler never sees new blocks and rounds
never trigger, causing settle operations to hang indefinitely.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review — arkade-regtest#1

Overall: Solid infrastructure PR that enables arkade-regtest as a shared submodule across SDKs. The .env auto-discovery, ARKD_IMAGE override, and idempotent start are well-designed patterns. A few notes:

✅ Strengths

  • lib/env.sh shared loader — clean DRY pattern across start/stop/clean scripts. The override priority chain (--env > ../.env.regtest > .env) is intuitive for submodule consumers.
  • Idempotent start — checking running containers before acting avoids the "second run breaks everything" problem. Good use of docker ps checks and HTTP health probes.
  • Diagnostic output on failure — dumping container status + last 30 log lines when arkd fails to start is excellent for CI debugging.
  • Fulmine delegator service — adding fulmine-delegator to the compose stack extends test coverage for delegated wallet flows.
  • Submodule detection — the .env.defaults existence check with a helpful "run git submodule update --init" message prevents confusing failures.

⚠️ Minor Issues

  1. Custom arkd detection in clean-env.sh / stop-env.sh — The logic docker inspect ark --format '{{.Config.Image}}' | grep -v 'nigiri' is fragile. If a custom image name happened to contain "nigiri", the detection would break. Consider comparing against the known nigiri image name directly, or checking if ARKD_IMAGE is set in the loaded env instead of inspecting the container image.

  2. ARKD_WALLET_SIGNER_KEY in .env.defaults — This is a hardcoded private key. Fine for regtest, but worth a comment in the file explicitly stating "regtest only — never use in production" to prevent copy-paste accidents.

  3. Bitcoin Core restart ordering — The new flow restarts bitcoin, then chopsticks, then arkd — but nbxplorer also connects to bitcoin and may lose its connection. Worth verifying nbxplorer reconnects automatically or adding it to the restart chain.

  4. start-env.sh always removes arkd volumes when ARKD_IMAGE is set — Lines docker volume rm nigiri_ark_datadir nigiri_ark_wallet_datadir run unconditionally when ARKD_IMAGE is set, even on idempotent re-runs. This means the arkd override path is NOT actually idempotent — it wipes and recreates every time. If this is intentional (clean state each run), add a comment. If not, add a container image check like the Nigiri path does.

  5. Plan docs add ~1000 lines — The docs/superpowers/plans/ and docs/superpowers/specs/ files are useful but inflate the diff. Consider whether these belong in a separate docs commit or an issue/wiki instead.

🔒 Security

  • No production credentials exposed. The ARKD_WALLET_SIGNER_KEY and passwords are regtest-only values.
  • Docker network uses external: true on the nigiri network — correct for overlay composition.
  • No TLS/macaroons disabled explicitly (ARKD_NO_TLS=true, ARKD_NO_MACAROONS=true) — appropriate for local regtest.

Cross-Repo Impact

This PR is the foundation for boltz-swap#106, ts-sdk#386, and potentially dotnet-sdk integration. The .gitmodules in those repos currently point to feat/shared-regtest-env-discovery branch — they'll need updating to master after this merges.

LGTM with minor suggestions. No blocking issues.

Restructure startup sequence so Bitcoin Core restarts happen BEFORE
custom arkd starts, not after. This eliminates the mid-flight chain
disruption that caused arkd's block scheduler to stop seeing new
blocks, preventing rounds from triggering and causing settle
operations and test beforeAll hooks to hang indefinitely.

New flow: nigiri start → bitcoin restart → chopsticks restart → arkd start
Old flow: nigiri start → arkd start → bitcoin restart → (broken arkd)
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review

Overall: Solid infrastructure consolidation. This is a well-structured approach to eliminating duplicated regtest infrastructure across SDKs.

✅ What looks good

  • .env auto-discovery chain is clean and intuitive: --env > ../.env.regtest > .env — exactly right for the submodule use case.
  • lib/env.sh extraction — good DRY practice, all three scripts share the same loading logic.
  • docker-compose.arkd-override.yml — clean separation. Only activated when ARKD_IMAGE is set, no impact on default nigiri flow.
  • Idempotent start — skipping already-running services is important for dev workflows.
  • Delegator service added to the overlay stack with dedicated ports (7010-7012) — needed for ts-sdk delegation tests.
  • README with CI integration example is a nice touch.

⚠️ Observations

  1. ARKD_WALLET_SIGNER_KEY hardcoded in .env.defaults (line 28: afcd3fa10f82a05fddc9574fdb13b3991b568e89cc39a72ba4401df8abef35f0). This is a regtest-only key, which is fine, but worth a comment clarifying it's intentionally deterministic for test reproducibility. Someone unfamiliar might worry about a leaked key.

  2. load_env sources user-provided files without validation. Since source executes arbitrary bash, a malicious .env.regtest could run arbitrary commands. For a dev tool this is acceptable (you're already trusting the repo), but worth noting for security-conscious environments.

  3. arkd-override compose: The ark container exposes port 7071 in addition to 7070. The original .env.defaults doesn't define an ARKD_ADMIN_PORT variable for 7071 — consider making it configurable for consistency, or document what 7071 is for (admin/gRPC port?).

  4. clean-env.sh custom arkd detection (lines 27-30): The grep-based detection (grep -v 'nigiri') is fragile — if the custom image name happens to contain "nigiri" it'll miss it. Consider checking against $ARKD_IMAGE directly instead.

  5. Plan document (docs/superpowers/plans/...) is 1011 lines. While thorough, shipping implementation plan artifacts in the repo long-term adds noise. Consider moving to a wiki or issue after the work is complete.

🔒 Security

  • No key handling concerns (regtest only, deterministic test keys).
  • No TLS/macaroon disabled flags are regtest-appropriate.
  • ARKD_UNLOCKER_TYPE=env with ARKD_UNLOCKER_PASSWORD=secret — fine for regtest.

Cross-repo impact

This is the foundation PR — ts-sdk#386, boltz-swap#106, and wallet#492 all depend on this landing first. The submodules in those PRs currently point to feat/shared-regtest-env-discovery branch, which will need updating to main/master once this merges.

Good work on the infrastructure consolidation. 👍

The Bitcoin Core restart for minrelaytxfee=0 breaks nbxplorer's connection
to bitcoind. When ark-wallet registers addresses with nbxplorer afterward,
nbxplorer can't forward block notifications, so ark-wallet never sees
funded transactions and arkd's balance stays at 0.

Gate the restart behind BITCOIN_LOW_FEE (default: true for backward compat).
SDKs that don't need low-fee transactions set BITCOIN_LOW_FEE=false in their
.env.regtest to skip the restart entirely.

When the restart IS used, also restart nbxplorer alongside chopsticks and
wait for it to fully sync before proceeding.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review — arkade-regtest#1

Scope: Shared regtest env with .env auto-discovery, ARKD_IMAGE override, delegator service, idempotent start, and comprehensive documentation.

Architecture — Solid ✅

The layered .env discovery chain (--env > ../.env.regtest > .env) is well-designed for the submodule use case. lib/env.sh avoids duplication across all three scripts. The ARKD_IMAGE override mechanism is clean — stop nigiri's arkd, start custom one on the same network.

Security Review ✅

  • ARKD_WALLET_SIGNER_KEY in .env.defaults is a hardcoded regtest-only key — appropriate for test environments
  • ARKD_PASSWORD defaults to "secret" — fine for regtest
  • No production credentials or mainnet-relevant secrets
  • Docker network isolation via nigiri external network is correct

Findings

1. Delegator service addition — nice scope expansion
Adding fulmine-delegator to docker-compose.ark.yml with dedicated ports (7010/7011/7012) enables ts-sdk delegator tests without repo-specific infra. Port mapping is clean and avoids conflicts with the main fulmine instance.

2. ARKD_ROUND_INTERVAL export missing ⚠️ Minor
Line exports ARKD_SESSION_DURATION but ARKD_ROUND_INTERVAL is defined in .env.defaults and used in docker-compose.arkd-override.yml but not exported in start-env.sh. Docker compose may not interpolate it correctly.

3. Wallet sync timeout is generous ℹ️ Nit
60 attempts × 3s = 180s for wallet sync. In regtest this should be near-instant. Consider a shorter timeout (30 attempts) with a clearer error message.

4. BITCOIN_LOW_FEE restart cascade ℹ️ Observation
Restarting bitcoin → chopsticks → nbxplorer is heavy but necessary for low-fee support. The BITCOIN_LOW_FEE=true default with opt-out via .env is the right call since most tests need it.

5. Plan/spec docs included in PR ℹ️
The 1000+ line plan and spec files under docs/superpowers/ add significant weight to the diff. Consider whether these belong in the repo long-term or should live in a separate knowledge repo.

Cross-Repo Impact

This PR is the foundation for arkade-os/ts-sdk#386, arkade-os/wallet#492, and future boltz-swap/dotnet-sdk migrations. The submodule currently points to the feat/shared-regtest-env-discovery branch — must be merged before consumer PRs can merge, and consumers should update submodule ref to the merge commit on main.

Verdict

Well-structured infrastructure consolidation. The idempotent start logic and comprehensive error diagnostics (log dumps on failure) are production-quality for a test harness. Minor export issue noted above.

… address

nigiri ark receive returns a CLIENT boarding address, not the server's
wallet address. Sending faucet funds there doesn't give the server
on-chain liquidity, so rounds fail with "not enough liquidity, balance: 0".

Use GET /v1/admin/wallet/address to get the actual server wallet address
and fund it directly. This ensures arkd has on-chain liquidity for
processing rounds and creating commitment transactions.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

Iterative review — new commit 1ae32d87 (fund arkd server wallet via admin API)

Good catch on the root cause: nigiri ark receive returns a client boarding address, not the server wallet. Funding that gives the client VTXOs but leaves the server with zero liquidity for processing rounds.

Using GET /v1/admin/wallet/address to fund the server directly is the correct fix. The fallback to nigiri ark receive if the admin endpoint isn't available is a nice defensive touch.

One thing to watch: this changes the funding flow for all consumers (wallet, ts-sdk, boltz-swap). If any test assumes there's a pre-existing client VTXO from the startup funding, it will break. The wallet and ts-sdk PRs look fine since they do their own test wallet setup, but worth verifying boltz-swap doesn't depend on it.

CI: no checks configured on this repo. Consider adding a basic smoke test workflow that runs start-env.sh + health checks.

Boltz uses Bitcoin Core's estimatesmartfee for on-chain transactions.
In a fresh regtest, estimatesmartfee fails without enough blocks
containing transactions. The old boltz-swap setup.mjs did 21 faucet
transactions to generate enough fee data.

Replicate this by doing 21 small faucet transactions to the server
wallet address, which both funds the server and creates the block
history needed for fee estimation.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

Iterative review — new commit d68e0cfc (21-tx server funding for fee estimation)

Good fix. Boltz uses estimatesmartfee which needs block history with transactions. The old boltz-swap setup.mjs did exactly this — 21 faucet txs to generate fee data. Replicating it here in the shared infra means no SDK needs to handle it individually.

Using the server wallet address (from admin API) for all 21 txs is efficient — it both funds the server and creates the fee estimation history in one step.

No issues with this commit.

Boltz creates its own wallet in Bitcoin Core for on-chain operations
like reverse swaps and chain swaps. Without funds in this wallet,
Boltz fails with "onchain coins could not be sent".

After Boltz restart, list Bitcoin Core wallets, find the Boltz wallet,
and fund it with 5 BTC via faucet.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 Arkana PR Review — arkade-regtest#1

Scope: Core shared regtest infrastructure with .env auto-discovery, ARKD_IMAGE override, idempotent startup, and submodule-friendly design.

Architecture — Looks Solid ✅

The layered env approach (.env.defaults--env / ../.env.regtest / .env) is clean and will work well across submodule consumers. The lib/env.sh extraction avoids duplication across start/stop/clean scripts.

Observations

1. ARKD_WALLET_SIGNER_KEY hardcoded in .env.defaults (line ~35)
This is a deterministic regtest key — fine for test environments. But worth a comment clarifying it is regtest-only so nobody copies it into production configs.

2. docker-compose.arkd-override.yml — env var passthrough
The compose file passes through ARKD_SCHEDULER_TYPE, ARKD_VTXO_TREE_EXPIRY, etc. via ${VAR:-default} syntax. Good — this means each SDK .env.regtest can tune arkd behavior without modifying the compose file.

3. fulmine-delegator service added to docker-compose.ark.yml
New service on ports 7010/7011/7012. This is consumed by ts-sdk#386 which updates delegator URLs from 70027012. Cross-repo coordination is correct.

4. BITCOIN_LOW_FEE=true default with restart
The Bitcoin Core restart for low-fee config can break nbxplorer connections (noted in comments). The BITCOIN_LOW_FEE=false escape hatch in .env.regtest is the right pattern. Both wallet and boltz-swap override this to false.

5. Idempotent start — detection via container names + image inspection
Using docker inspect ark --format to detect whether custom arkd is already running is robust. Good.

6. Implementation plan docs (1011 lines)
Comprehensive but large. Consider moving the plan doc to a wiki or removing it post-merge to avoid bloating the repo. The spec doc (279 lines) is valuable to keep.

Minor Nits

  • clean-env.sh line 24: the grep-based image detection might false-positive if someone names their custom image with "nigiri" in it. Consider checking if ARKD_IMAGE is set in the loaded env instead.
  • README.md still references arkade-os/arkade-regtest in the submodule add example but the actual repo is ArkLabsHQ/arkade-regtest. Should be consistent.

Verdict

Well-structured foundation for the shared regtest approach. The coordinated PRs in ts-sdk, boltz-swap, and wallet all consume this correctly. 👍

@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

Iterative review — new commit ff30d695 (increase server wallet funding to 21 BTC)

Increases individual faucet amounts from fractional to 1 BTC per tx across the 21 transactions. This ensures the server has meaningful liquidity (21 BTC) for processing larger test rounds and commitment trees, while still maintaining the 21-tx count needed for estimatesmartfee.

Mechanical config change. LGTM. ✅

The ARK fee settings (ARK_OFFCHAIN_INPUT_FEE, etc.) from .env.regtest
were never passed to the arkd container, causing SDKs that need zero
fees (ts-sdk, boltz-swap) to silently run with default 1% input fees.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

Follow-up review (new commit: eecb40e)

ARK fee env var passthrough to the arkd-override compose — LGTM.

- ARK_OFFCHAIN_INPUT_FEE=${ARK_OFFCHAIN_INPUT_FEE:-amount * 0.01}
- ARK_ONCHAIN_INPUT_FEE=${ARK_ONCHAIN_INPUT_FEE:-amount * 0.01}
- ARK_OFFCHAIN_OUTPUT_FEE=${ARK_OFFCHAIN_OUTPUT_FEE:-0.0}
- ARK_ONCHAIN_OUTPUT_FEE=${ARK_ONCHAIN_OUTPUT_FEE:-250.0}

This was the missing piece — ts-sdk and boltz-swap both set zero fees in .env.regtest, but those vars were never passed through to the container. Without this fix, the overrides were silently ignored and arkd ran with default 1% input fees, which would cause test failures in any SDK that expects zero-fee rounds.

One nit: The default ARK_ONCHAIN_OUTPUT_FEE=250.0 in the compose differs from .env.defaults which has ARK_ONCHAIN_OUTPUT_FEE="250.0" (quoted). Since these are string expressions evaluated by arkd, it should work fine, but worth being aware of if arkd ever does strict type checking on these values.

ARKD_ROUND_INTERVAL and ARK fee env vars were not exported, so
docker-compose used defaults instead of .env.regtest overrides.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 29, 2026

🔍 PR Review — arkade-regtest#1

Scope: Shared regtest env with .env auto-discovery, ARKD_IMAGE override, idempotent start, delegator service, and comprehensive startup diagnostics. Foundation for ts-sdk#386, boltz-swap#106, wallet#492 submodule integration.


Architecture

The .env layering chain (.env.defaults → first override from --env / ../.env.regtest / .env) is clean and well-suited for submodule consumption. The load_env() extraction to lib/env.sh avoids duplication across all three scripts.

The startup sequence reordering — nigiri → bitcoin restart → chopsticks/nbxplorer restart → arkd start — correctly addresses the root cause of the mid-flight chain disruption that broke arkd's block scheduler. The commit history shows systematic debugging of service dependency ordering issues that are genuinely tricky (nbxplorer ZMQ reconnection, chopsticks RPC loss, arkd block monitoring).

Security Notes

  1. ARKD_WALLET_SIGNER_KEY in .env.defaults — hardcoded regtest key. Fine for regtest, but worth a comment in the file noting this must never be used outside regtest. Currently the comment just says "only used when ARKD_IMAGE is set" — adding "regtest only" would be clearer.

  2. source of override filesload_env() sources user-provided .env.regtest files, which means arbitrary shell in those files executes. This is standard practice for shell env loading but worth being aware of in CI contexts. Not a blocker since the override files are tracked in each SDK repo.

  3. Admin API wallet creation flow — the seed → create → unlock → sync sequence via REST is correct and matches arkd's admin API contract. The fallback diagnostics (container status, logs, nbxplorer status) on failure are excellent for CI debugging.

Key Observations

  • Server wallet funding via admin API (GET /v1/admin/wallet/address) is the correct fix. nigiri ark receive returns a client boarding address, not the server's on-chain wallet — previous funding approach gave the server zero liquidity.

  • 21-tx funding pattern for Bitcoin Core fee estimation is correct — matches the original boltz-swap setup.mjs approach that generated enough block history for estimatesmartfee.

  • ARKD_SCHEDULER_TYPE=gocron + ARKD_ALLOW_CSV_BLOCK_TYPE=false default is the right call. v0.9.1 always treats VtxoTreeExpiry as seconds (requires gocron), and ALLOW_CSV_BLOCK_TYPE=false ensures consistent behavior across arkd versions.

  • BITCOIN_LOW_FEE gate is a good escape hatch. SDKs that don't need low-fee transactions can skip the disruptive Bitcoin Core restart entirely.

  • Timeout additions on all curl calls and timeout wrappers on blocking operations (settle, redeem-notes) prevent the CI hangs that were occurring.

Minor Issues

  1. clean-env.sh arkd-override detection: The grep -v 'nigiri' heuristic for detecting custom arkd images could false-positive if a custom image name happens to contain "nigiri". Consider checking against ARKD_IMAGE from the loaded env instead:

    if [ -n "${ARKD_IMAGE:-}" ]; then
      docker compose -f ... down ...
    fi
  2. stop-env.sh missing delegator port exports: DELEGATOR_GRPC_PORT, DELEGATOR_API_PORT, DELEGATOR_HTTP_PORT are not exported in stop-env.sh and clean-env.sh, but the ark compose file references them. If docker-compose reads the file during down, unset vars could cause warnings. Currently not blocking since down doesn't need port interpolation, but worth being consistent.

  3. start-env.sh line 404 — the redeem-notes step was removed entirely (previously $NIGIRI ark redeem-notes ...). This is correct since the note/redeem-notes flow was blocking on older versions, but means the server's VTXOs are all on-chain only. For regtest testing this is fine.

Cross-Repo Impact

This PR is the prerequisite for:

All three are already open and tracking this PR's branch. The spec docs (docs/superpowers/specs/ and docs/superpowers/plans/) provide comprehensive implementation plans for each SDK migration.

Verdict

Solid infrastructure work. The 48-commit iteration to get service dependency ordering right is the kind of thing that's hard to get right without live CI feedback. The final startup sequence is robust, well-diagnosed on failure, and correctly handles both nigiri-native and custom arkd paths. Minor cleanup items above are non-blocking.

Not all stacks include nbxplorer (e.g. dotnet-sdk uses nigiri's
built-in arkd without BTCPay). The BITCOIN_LOW_FEE restart path
now checks docker inspect before trying to restart nbxplorer.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 30, 2026

🔍 Iterative review (commit 9a409cdf)

Good fix — guards nbxplorer restart behind docker inspect check. Not all consuming stacks include nbxplorer (dotnet-sdk uses nigiri's built-in arkd without BTCPay).

if docker inspect nbxplorer >/dev/null 2>&1; then
  # restart + sync wait
fi

Clean approach. The docker inspect check is better than name-grepping docker ps -a since it works even if the container was stopped.

Cross-repo: Consumed by arkade-os/dotnet-sdk#56 which sets BITCOIN_LOW_FEE=false to skip the restart entirely for that stack.

No concerns. ✅

When the admin API isn't available (nigiri's built-in arkd), the
fallback only funded the onchain address but didn't convert to
offchain funds via redeem-notes. This left the CLI wallet without
offchain sats, causing "not enough funds" in dotnet-sdk tests.
@arkanaai
Copy link
Copy Markdown

arkanaai bot commented Mar 30, 2026

Iterative review (commit d343647)

New commit restores redeem-notes in the fallback funding path (when admin API is unavailable, e.g. nigiri built-in arkd). Good catch — without offchain funds the dotnet-sdk tests would fail with insufficient funds.

No concerns. The guard logic (timeout 60 docker exec ark arkd redeem-notes || true) keeps it non-fatal for versions where redeem-notes fails, consistent with the existing pattern.

@Kukks Kukks merged commit 0ddb42c into master Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant