Repository navigation
Conversation
This was referenced Oct 29, 2026
…at/arkade-lightning # Conflicts: # app/src/test/java/to/bitkit/repositories/PrivatePaykitRepoTest.kt # app/src/test/java/to/bitkit/repositories/WalletRepoTest.kt
A claimed swap now raises its received event and records its activity before the wallet re-reads its balance, which reads the chain and can fail.
…at/arkade-lightning # Conflicts: # app/src/main/java/to/bitkit/repositories/LightningRepo.kt # app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt # app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsViewModel.kt
Contributor
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
Collaborator
Author
|
Closing this PR: after a full mainnet QA run on Android and iOS, Bitkit goes with Spark for Lightning. Arkade worked end to end with real funds (LN send and receive, Lightning address, transfers to and from Savings), but it needs too much built and run on our side: chain access through block explorers, our own LN swap client and the activity history. The branch stays for reference. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Twin: synonymdev/bitkit-ios#1169
Dependency: synonymdev/bitkit-core#183
Refs:
This PR builds the Arkade (Ark Labs) alternative to #1697, so both can be tested on mainnet and compared hands-on. Spending becomes an Arkade balance, Lightning goes through Arkade Intents, and Savings keeps its ldk-node on-chain wallet. The UX matches the Spark draft: the same fallback rule, Funding entry points, transfer flows, Lightning Connections row and detail screen.
Description
ArkadeService, through a Rust binding on arkade-os/rust-sdk (ark-rs) over UniFFI, shared with the iOS twin. Bitkit doesn't embed JS. On mainnet builds only: bitkit-core starts no Lightning solver or LNURL server on Arkade's test network, so dev builds keep Arkade off. CI needs bitkit-core0.8.0-arkade.1published from feat: arkade spending in bitkit-core bitkit-core#183; until then this branch builds only against a locally built binding.m/86'/0'/1', BIP86). The SDK's default, account 0, would reuse Savings' Taproot keys. There is no new phrase to back up.lightning=carries the wallet's Lightning address as an LNURL. Arkade has no amountless invoice.lnurl.arkade.sh(lnurl-server) and registers the wallet's Arkade identity for offline receive. The server then hands a payer a solver hold invoice and claims the payment into the wallet while the app is closed. The address's token derives from the wallet's key, so a restore finds the same address.delegate.arkade.money, fee 0) can renew while it is closed, until Ark Labs replaces it with an Arkade Script approach. The Arkade screen shows the Lightning address and the next renewal.btc-lightning-lnurlendpoint when Arkade is the receive rail, so contacts can pay a Spending-only wallet with any amount, offline too. Paykit requests with an amount are paid over Arkade when no channel can carry them.ARKADE_EXIT, exported on start and on every change, encrypted like the other backups. A restore imports it before the wallet opens, then scans the operator for anything newer. The first start on an install also runs that scan, so a wallet restored from the phrase alone finds its outputs and swaps.Out of Scope
Risks for review
beta-solver), pinned from Ark Labs' docs, since the mainnet registry lists none. Ark Labs runs the only operator, the emulator, the relay, the delegate and the LNURL server.unilateralExitDelay605,184 s) and the user pays all fees.lnurl.arkade.shis Ark Labs' own instance, which Ark Labs says Bitkit may use; for a Bitkit domain, they issue an exclusive API key and Bitkit points its domain at their instance.Paykit's reusable Lightning endpoint
Arkade has no amountless invoice: each solver hold invoice is for one amount and expires after 25 minutes, so a reusable "pay me on Lightning" endpoint needs an LNURL-pay server that makes an invoice per payment. It also claims payments while the app is closed.
lnurl.arkade.sh), or point a Synonym domain at it via CNAME or A record, with an exclusive API key for issuing addresses on it. No self-hosting is needed.lnurl-serveris one container with SQLite and a domain. It claims offline receives co-signed by Ark Labs' public emulator, and holds preimages but no keys.Answers from Ark Labs
Kukks (Ark Labs) answered in the Arkade <> Bitkit group on 29 Oct.
delegate.arkade.money) is being phased out for a simpler approach on Arkade Script, almost ready. Renewal here sits behind one call (renew, plus the wallet's own pass 3 days before expiry), so it can switch without app changes; this PR invests nothing more in the delegate.ARKADE_EXITbackup carries the wallet's whole state, swap records included, and a restore imports it before the wallet starts.Swap-state backup (from Ark Labs' code)
A Lightning swap can't be rebuilt from the seed plus the operator's indexer:
@arkade-os/swaponly rebuilds Arkade-to-Arkade offers, and its swap contracts have no discovery. So these must be backed up per swap:rfqId, kind and state, the amounts and fee, the solver key,lock.hash,lockupAddressandlockupPkScript,refundLocktime,fundingTxid, and the invoicepreimageSaltHex, needed in the default static wallet mode) or the preimage itself when storedThese come back from the seed and the indexer: the refund key (the wallet's identity key), a preimage derived from an HD descriptor, lockup output state, revealed preimages, and the wallet's own addresses and balance.
The TypeScript SDK has no export or import of swap state, and Ark Labs' wallet dropped swaps from its Nostr backup when it moved to Intents (arkade-os/wallet#908). Bitkit's
ARKADE_EXITbackup carries the swap records with all of the above, throughexport_statein synonymdev/bitkit-core#183.Renewal after the delegate (from Ark Labs' code)
The replacement for
delegate.arkade.moneyis public but not released:delegatee.arkade.shreturned 502, while the mutinynet instance answeredDesign
N/A — no design available. Arkade reuses the Spark draft's screens.
Preview
Case 1 on the Rust engine (
b6092d340with bitkit-coreac2919b), a mainnet build with a new, unfunded wallet (QR and clock masked): Receive shows the Lightning address, then a 2,000-sat Arkade invoice from the empty wallet, 6 s after the amount is set.receive-arkade-rust.mp4
Cases 2 to 4 on a local regtest stack with test money (receive and send on
8e07c53d0, the offline receive ona559d37bb, with a local build of bitkit-core259c0ca), each on the Arkade balance alone, no channels: an invoice paid into the empty wallet (19,900 sats of 20,000 arrive, then 9,950 of 10,000), a 3,000-sat invoice paid for 3,013, and two payments to the Lightning address while the app was closed, listed at the next start.rt-android-receive2x.mp4
rt-android-send2x.mp4
rt-android-offline2x.mp4
Case 7 on regtest (
cf7ef8905): a funded wallet (12,935 sats, two receives, a Lightning address), reset in the app, then restored from its phrase: the balance, the two activity rows and the same Lightning address come back.rt-android-prewipe2x.mp4
rt-android-restore2x.mp4
QA Notes
Setup
0.8.0-arkade.1(or a local build of feat: arkade spending in bitkit-core bitkit-core#183). No key is needed: Arkade, the solver, the delegate and the LNURL server are Ark Labs' public mainnet services. Use small amounts (335 to 200,000 sats per Lightning payment).relaymode, lnurl-server 0.6.0 withOFFLINE_EMULATOR_URLset; then build the dev flavor withARKADE_REGTEST_SOLVER_PUBKEY=<the stack's solver key>(andARKADE_REGTEST_HOST, defaultlocalhost, withadb reversefor ports 7070, 3000, 7777, 9090 and 7012). Without the key, dev builds keep Arkade off. The stack'slnd-peerpays and issues the invoices.Journeys
arkade-transfer-to-spending.xml— with Arkade ready, the transfer buttons and Funding open the Arkade amount and confirm screenstransfer-unavailable-sheet.xml— now needs Arkade not running, since a ready Arkade replaces the sheetManual Tests
Automated Checks
ArkadeRepoTest.kt— the operator scan runs on the first start only, a settled boarding marks its deposit boarded, a broadcast deposit shows pending at once, a claimed receive and a paid send raise node events with amount and fee, an amountless invoice is refused, and a backup from another network is skipped while one from this network is imported on the next startArkadeRepoTest.kt— a payment that reached the wallet while it was off is listed at the next start, and a claimed receive is listed at the amount that reached the walletBackupRepoTest.kt,PrivatePaykitRepoTest.kt,LightningRepoTest.kt,WalletRepoTest.kt,WalletViewModelTest.kt,EditInvoiceVMTest.kt,DeriveBalanceStateUseCaseTest.kt,TransferViewModelTest.kt,AppViewModelSendFlowTest.kt— the Spark draft's cases, run against ArkadeEvidence
8e07c53d0anda559d37bbwith a local build of bitkit-core259c0ca, on an Android 15 emulator against the arkade-regtest stack, new wallet, no channels:lnd-peer: the swap went accepted → open → claimed in 20 s, and 19,900 sats arrived. A 10,000-sat one gave 9,950.lnd-peerpaid the wallet's Lightning address 4,000 and 2,000 sats; lnurl-server claimed them for the wallet, and at the next start Spending showed 3,980 and 1,990 more, each listed as a receive.quiet-badger, reset under Settings > Security after its backups uploaded, then restored from its phrase: Get Started after 36 s, then the same balance, the same two activity rows, and the same Lightning address (identical LNURL).cf7ef8905)regtest_tests.rs), which also restores the wallet from its phrase and backup with the same addresses, Lightning address and balance.b6092d340with a local build of bitkit-coreac2919b: a mainnet debug build on an Android 15 emulator, new wallet, no channels, no funds.lnurl.arkade.shLightning address as the QR'slightning=.ARKADE_EXIT).just compile,just testandjust lintpass against that binding.9aeb4b416, a store-signed mainnet debug build on an Android 15 emulator with a new wallet and no channels.arkade.computerin about 2 s, including its first-start operator scan.lnurl.arkade.shLightning address as the QR'slightning=LNURL.just compile,just testandjust lintpass locally on9aeb4b416.9aeb4b416(Preview).6dfa8c512(mainnet emulator, no Savings): Funding showed Transfer from Savings and Use Other Wallet above Manual Setup, and Transfer from Savings opened the Arkade amount screen.Gaps
Models used
claude-opus-5-5(reasoning:low)claude-opus-5-5(reasoning:low),claude-sonnet-5-5(reasoning: Not exposed)