Repository navigation
chore: fund spark regtest from the shared wallet - #1308
Conversation
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
[Low impact] The PR adds a manual funding path for Spark regtest development and CI work. Fix the multi-input retry before merging so concurrent funding does not fail despite enough usable funds. Findings
SummaryAdds
Reviews (1) · Last reviewed commit: "chore: fund spark regtest from the share..." · Reviewed by Greptile |
pwltr
left a comment
There was a problem hiding this comment.
Reviewed 2cd439e. The new funding script signs from the shared regtest wallet and broadcasts through Lightspark's mempool API; its code matches the Android twin, and 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
@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
left a comment
There was a problem hiding this comment.
No findings. Adds scripts/spark-regtest-fund.py, the same funder as synonymdev/bitkit-android#1891: spends from the shared regtest wallet behind SPARK_REGTEST_MNEMONIC, one random confirmed coin per send, retried with another coin on a broadcast error. Reviewed 2cd439e, full tier, static; I did not run it, since it spends from a shared wallet.
What I checked, and 4 candidates I ruled out
Read in full: the script; diffed it against the Android one (only the docstring differs)
Ruled out
- P2WPKH signing: scriptCode is the key's P2PKH script per BIP143, witness is DER sig +
SIGHASH_ALL+ compressed pubkey. - Fee underpaid:
vsizerounds up and counts a change output even when sub-dust change is dropped into the fee. - Retry picking the same coin: failed outpoints go into
skip, applied before both pick strategies. - Secret exposure: the mnemonic comes from the environment and is never printed.
CI: green apart from Run Tests, still running at review time; the PR touches no Swift.
Merge confidence: 4/5, a dev script with no test, not run here.
jvsena42
left a comment
There was a problem hiding this comment.
One LOW inline on the docstring; approving. The script doesn't ship: it isn't in the Xcode project or any build phase. No credential is committed or printed: the mnemonic comes only from SPARK_REGTEST_MNEMONIC, and errors print only the HTTP status and body. Keys are regtest-derived (m/84h/1h), so a wrong endpoint can't reach real funds. Signing, vsize rounding and dust change match the Android twin synonymdev/bitkit-android#1891, which merged. The LOW can be fixed here or in a follow-up, your choice.
Device gate: no device check needed: dev tooling only.
ben-kaufman
left a comment
There was a problem hiding this comment.
No new material findings at beaf8856. The latest changes only correct the funding instructions, and executable code is unchanged. The rare multi-input retry limitation remains accepted for this developer regtest tool. Live funding, concurrent sends and the uv run entry point remain unverified by this review.
Reviewer model: gpt-6.1-sol
Reasoning effort: xhigh
|
Merged: approved by @ben-kaufman on the current head, checks green, the review threads answered. |
Twin: synonymdev/bitkit-android#1891
This PR adds
scripts/spark-regtest-fund.py, which funds Spark regtest addresses from the shared Spark regtest wallet that Lightspark funded for our tests, so local runs and CI can fund them without faucet credentials.Description
spark-regtest-fund.pyspends from the wallet behind theSPARK_REGTEST_MNEMONICrepository secret: one P2WPKH address at BIP84m/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).SPARK_CHAIN_SERVICE_URL: Savings watches Bitkit's staging regtest, a different chain, so the docstring points Savings funding at the staging./lspdeposit.uv run(inlineembitdependency), and--balanceprints the wallet's confirmed and unconfirmed sats.Out of Scope
.github/workflows: no job funds from Spark regtest yet; a job that needs funds passesSPARK_REGTEST_MNEMONICfrom secrets and calls this script.Design
N/A — no UI changes.
Preview
N/A
QA Notes
Setup
SPARK_REGTEST_MNEMONICset to the shared wallet's recovery phrase (stored as a repository secret), anduvinstalled.Journeys
N/A — no user-visible behaviour change.
Manual Tests
SPARK_REGTEST_MNEMONIC="…" uv run scripts/spark-regtest-fund.py --balance→ prints the wallet addressbcrt1qef4prw6ezd0mr8s52a2hytmetjn9r3a0q7vcwsand its balanceSPARK_REGTEST_MNEMONIC="…" uv run scripts/spark-regtest-fund.py <bcrt1… address> 20000→ prints a txid thathttps://regtest-mempool.us-west-2.sparkinfra.net/api/tx/<txid>/statusknowsAutomated Checks
N/A
Evidence
b61c1bbf…6acc,be889c4d…0888), each on its own coin.SPARK_REGTEST_MNEMONICthe script exits with a message naming the variable.git diff --checkclean; no app code changed, so no build or device run.Gaps
None.
Models used
claude-opus-5-5(reasoning:Not exposed)claude-opus-5-5(reasoning:Not exposed)The session metadata available here names the model but not a reasoning setting.