Skip to content

chore: fund spark regtest from the shared wallet - #1891

Merged
ovitrif merged 1 commit into
masterfrom
feat/spark-regtest-fund-mnemonic
Nov 12, 2026
Merged

ovitrif merged 1 commit into
masterfrom
feat/spark-regtest-fund-mnemonic

Conversation

@ovitrif

@ovitrif ovitrif commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

Twin: synonymdev/bitkit-ios#1308

This PR switches scripts/spark-regtest-fund.py from Lightspark's API faucet to the shared Spark regtest wallet that Lightspark funded for our tests, so local runs and CI can fund Spark regtest addresses without faucet credentials.

Description

  • spark-regtest-fund.py now spends from the wallet behind the SPARK_REGTEST_MNEMONIC repository secret: one P2WPKH address at BIP84 m/84'/1'/0'/0/0, used for receive and change. It signs locally and broadcasts through Lightspark's regtest mempool API (regtest-mempool.us-west-2.sparkinfra.net), so FAUCET_USERNAME/FAUCET_PASSWORD are no longer needed.
  • Each send spends one random confirmed coin that covers it, and retries with another coin on a broadcast error. The API's address index lags the mempool, and several jobs and agents spend from the same wallet, so a largest-first pick would make concurrent senders collide on one coin.
  • It runs with uv run (inline embit dependency), and --balance prints the wallet's confirmed and unconfirmed sats.

Out of Scope

  • .github/workflows: no job funds from Spark regtest yet; a job that needs funds passes SPARK_REGTEST_MNEMONIC from secrets and calls this script.

Design

N/A — no UI changes.

Preview

N/A

QA Notes

Setup

SPARK_REGTEST_MNEMONIC set to the shared wallet's recovery phrase (stored as a repository secret), and uv installed.

Journeys

N/A — no user-visible behaviour change.

Manual Tests

  • 1. SPARK_REGTEST_MNEMONIC="…" uv run scripts/spark-regtest-fund.py --balance → prints the wallet address bcrt1qef4prw6ezd0mr8s52a2hytmetjn9r3a0q7vcws and its balance
  • 2. SPARK_REGTEST_MNEMONIC="…" uv run scripts/spark-regtest-fund.py <bcrt1… address> 20000 → prints a txid that https://regtest-mempool.us-west-2.sparkinfra.net/api/tx/<txid>/status knows

Automated Checks

N/A

Evidence

  • 1: printed the wallet with 10,629,090 sats confirmed.
  • 2: two sends started at the same moment from separate processes both broadcast (b61c1bbf…6acc, be889c4d…0888) and reached the mempool, each on its own coin.
  • Without SPARK_REGTEST_MNEMONIC the script exits with a message naming the variable.
  • git diff --check clean; no app code changed, so no build or device run.

Gaps

None.

Models used

  • Planning/scoping: claude-opus-5-5 (reasoning: Not exposed)
  • Implementation: claude-opus-5-5 (reasoning: Not exposed)
  • Review: Not performed

The session metadata available here names the model but not a reasoning setting.

@ovitrif ovitrif self-assigned this Nov 12, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T15:36:19.554086Z 089abaf PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ovitrif
ovitrif requested review from a team, ben-kaufman and pwltr and removed request for a team November 12, 2026 15:34

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 089abaf239

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/spark-regtest-fund.py Resolved
@greptile-apps

greptile-apps Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect one developer and CI funding utility for Spark regtest.

Fix the multi-input retry path before merging so concurrent sends do not fail despite enough available funds.

Findings

  1. P1 Retries discard usable coins ▶

Summary

Replaces Lightspark's authenticated faucet with local spending from the shared regtest wallet.

  • The funding script spends from a shared Spark regtest wallet.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Read shared wallet mnemonic] --> B[Derive wallet address and key]
  B --> C[Fetch confirmed coins]
  C --> D[Pick coins and sign payment]
  D --> E[Broadcast payment]
  E -->|Success| F[Print transaction ID]
  E -->|HTTP error| G[Skip every selected coin]
  G -->|Attempts remain| D
Loading

Reviews (1) · Last reviewed commit: "chore: fund spark regtest from the share..." · Reviewed by Greptile

Comment thread scripts/spark-regtest-fund.py Resolved

@pwltr pwltr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 089abaf. The funding script now signs from the shared regtest wallet and broadcasts through Lightspark's mempool API; the fee estimate, segwit signing and change handling check out.

Low — A failed multi-input send drops every picked coin from the retry. When no single coin covers the send, pick() combines several, and on a broadcast error scripts/spark-regtest-fund.py:108 skips all of them, though another sender may have spent only one. The retry can then exit with "Insufficient confirmed funds" while the wallet still has enough. Skipping only the coins that turned out spent, or re-reading the UTXO list before retrying, would avoid it.

Review details

General review
Model: Claude Opus 5.5
Reasoning effort: high

@github-actions

Copy link
Copy Markdown
Contributor

Regtest APK

Built from 089abaf (run).

Download bitkit-dev-debug universal APK (expires in 30 days).

@ovitrif

ovitrif commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Low — A failed multi-input send drops every picked coin from the retry.

@pwltr Thanks. I'm keeping it as is: multi-input sends only happen when no single coin covers the amount, and the wallet holds 40 coins of 200k sats, so a normal test-wallet funding always spends one coin. In the rare multi-input case a lost race exits cleanly with nothing sent, and a rerun after the next block (about a minute) reads a fresh UTXO list.

@talosmachina talosmachina left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings. scripts/spark-regtest-fund.py now spends from the shared regtest wallet behind SPARK_REGTEST_MNEMONIC (BIP84 m/84'/1'/0'/0/0, signed locally, broadcast to the regtest mempool API) instead of calling the authenticated faucet. Reviewed 089abaf, full tier, static; I did not run it, since it spends from a shared wallet.

What I checked, and 5 candidates I ruled out

Read in full: the script at the head, and the removed faucet version
Callers: nothing else in the repo references the script or FAUCET_USERNAME/FAUCET_PASSWORD, so no workflow breaks with the faucet path gone
Twin: identical to synonymdev/bitkit-ios#1308 apart from the docstring

Ruled out

  • P2WPKH signing: BIP143 scriptCode is the P2PKH script of the key, which is what sighash_segwit gets; witness is DER sig + SIGHASH_ALL + compressed pubkey.
  • Fee underpaid: vsize rounds every component up (11 + 68 per input + destination + a change output), and a dropped sub-dust change goes to the fee.
  • Retry reusing a spent coin: the failed attempt's outpoints go into skip, which both the single-coin and the largest-first paths filter on.
  • Secret exposure: the mnemonic is only read from the environment; errors print the API path and response, never the key.
  • Unconfirmed coins: only confirmed coins are picked, so a send never chains on another job's unconfirmed change.

CI: green.

Merge confidence: 4/5, a dev script with no test, not run here.

@ovitrif

ovitrif commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator Author

Merged: approved by @pwltr, checks green, the review threads answered.

@ovitrif
ovitrif merged commit 3526525 into master Nov 12, 2026
18 checks passed
@ovitrif
ovitrif deleted the feat/spark-regtest-fund-mnemonic branch November 12, 2026 16:15
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.

3 participants