diff options
| author | Adam Soltys <[email protected]> | 2026-08-02 17:07:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-02 17:07:26 -0700 |
| commit | bff3692ed92dbce4aa1e71f1ba6ec491645eb5db (patch) | |
| tree | 9840735d57148571b8adf3f9e4e4bf4279451d61 /src/ark | |
| parent | 404350a32f26c892fa7b3b65f222ebc955be8a36 (diff) | |
| download | coinosv3-bff3692ed92dbce4aa1e71f1ba6ec491645eb5db.tar.gz coinosv3-bff3692ed92dbce4aa1e71f1ba6ec491645eb5db.zip | |
Ark: partial moves to Savings via an exact-amount split
Into Savings now has an amount field with a Max button. Max (or the full
balance) keeps the existing whole-balance cooperative offboard. A
partial amount first mints a vtxo of exactly that amount with a
self-send — the mailbox delivers self-sends, verified on regtest — then
offboards just that vtxo, so the number typed is the number that leaves
Spending (fees still come off what arrives, shown on the success
screen). startOffboard accepts a vtxo subset for this; an exact-match
vtxo skips the split. The unilateral exit page remains reachable from a
link under the field.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
Diffstat (limited to 'src/ark')
| -rw-r--r-- | src/ark/manager.js | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/ark/manager.js b/src/ark/manager.js index 3b54582..5617cf1 100644 --- a/src/ark/manager.js +++ b/src/ark/manager.js @@ -363,13 +363,19 @@ export class ArkManager { return action; } - // ---- offboard (collaborative exit: all spendable vtxos -> one on-chain output) ---- - async startOffboard(spk, address) { + // ---- offboard (collaborative exit: spendable vtxos -> one on-chain output) ---- + // Whole vtxos only — there is no change on this path. Default is everything + // spendable; vtxoIds selects a subset (the feature splits an exact-amount + // vtxo first via a self-send when the user asks for a partial move). + async startOffboard(spk, address, vtxoIds) { if (this.pendingActions().some((a) => a.type === 'offboard')) { throw new Error('an offboard is already in progress'); } - const inputs = this.state.vtxos.filter((v) => v.state === 'spendable'); + const inputs = vtxoIds + ? vtxoIds.map((id) => this._vtxo(id)) + : this.state.vtxos.filter((v) => v.state === 'spendable'); if (!inputs.length) throw new Error('no spendable ark balance'); + if (inputs.some((v) => !v || v.state !== 'spendable')) throw new Error('vtxo not spendable'); if (this.info.maxOffboardInputs && inputs.length > this.info.maxOffboardInputs) { throw new Error(`too many coins for one offboard (${inputs.length}) — refresh/consolidate first`); } |
