Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0df7a57
db: add RoundRepository.PatchForfeitTxs for forfeit-tx backfill
Kukks Jun 14, 2026
140c1ed
arkd: sign forfeit txs at collection time so they are broadcast-ready
Kukks Jun 14, 2026
8804c1e
backfill: add arkd-forfeit-backfill tool to sign existing unswept for…
Kukks Jun 14, 2026
adf2526
build: wire arkd-forfeit-backfill into build scripts
Kukks Jun 14, 2026
a71e6d5
backfill: wrap long signatures to satisfy golines
Kukks Jun 14, 2026
dcbc0ce
fraud: skip re-signing already-signed forfeit txs to avoid duplicate-…
Kukks Jun 14, 2026
9bea8e4
Require arkd-wallet to be initialized and unlocked out of band
bitcoin-coder-bob Jun 11, 2026
f200099
arkd-wallet: add create/unlock/status subcommands
bitcoin-coder-bob Jun 11, 2026
7366cec
Address review: escape wallet CLI JSON, disable Lock RPC
bitcoin-coder-bob Jun 12, 2026
7372cf4
Address review: stop arkd-wallet service at most once
bitcoin-coder-bob Jun 12, 2026
ea53d83
Address review: escape wallet JSON payloads and harden e2e HTTP helpers
bitcoin-coder-bob Jun 13, 2026
c968d25
Warn when app service startup is deferred
bitcoin-coder-bob Jun 14, 2026
dd8d5b0
arkd-wallet: split create and restore into separate CLI commands
bitcoin-coder-bob Jun 14, 2026
5d9ad68
arkd-wallet: warn about seed phrase security before printing it
bitcoin-coder-bob Jun 15, 2026
03d4fe9
Dial primary plus fallback arkd-wallets
bitcoin-coder-bob Jun 12, 2026
f11b43c
Sign sweeps with the primary or any fallback wallet
bitcoin-coder-bob Jun 12, 2026
e5d153f
Address review: named sweeper init, dedupe signingWallets
bitcoin-coder-bob Jun 12, 2026
bbb1937
docs: describe the sweep-fallback behavior in the README
bitcoin-coder-bob Jun 12, 2026
b6bb1a1
Address review: don't block sweep reconciliation when no wallet can sign
bitcoin-coder-bob Jun 13, 2026
bdfdc05
Persist primary/fallback wallet addresses in the settings domain
bitcoin-coder-bob Jun 12, 2026
33f927c
Address review: keep env fallback wallets on upgrade, normalize addrs
bitcoin-coder-bob Jun 12, 2026
3995eb9
Address review: reject commas in wallet addrs, dedupe addr codec
bitcoin-coder-bob Jun 12, 2026
c4103c5
docs: document wallet address settings in settings.md
bitcoin-coder-bob Jun 12, 2026
97d5541
Merge remote-tracking branch 'origin/master' into presign-forfeit-txs
bitcoin-coder-bob Jun 15, 2026
16830b5
fraud: broadcast pre-signed forfeits without the live signer
bitcoin-coder-bob Jun 15, 2026
06aa0d8
fix(db): fail loudly when PatchForfeitTxs targets a missing txid
bitcoin-coder-bob Jun 16, 2026
98f2463
fix(config): identify fallback wallet by host:port in readiness errors
bitcoin-coder-bob Jun 17, 2026
2738e65
docs: note fallback wallets are not yet used for sweeps
bitcoin-coder-bob Jun 17, 2026
ba566da
feat(config): reject fallback wallet that duplicates primary or anoth…
bitcoin-coder-bob Jun 17, 2026
45b1aa8
Merge remote-tracking branch 'origin/bob/arkd-multi-wallet-dial' into…
bitcoin-coder-bob Jun 17, 2026
be5ee75
refactor: tidy sweep-fallback signing helpers, comments, and test file
bitcoin-coder-bob Jun 17, 2026
e609b13
Merge origin/bob/arkd-sweep-fallback into bob/arkd-wallet-settings
bitcoin-coder-bob Jun 17, 2026
4e9d540
docs: clarify wallet-address env/settings hybrid behavior
bitcoin-coder-bob Jun 17, 2026
368bd80
refactor: trim wallet-address settings comments; drop restart warning
bitcoin-coder-bob Jun 17, 2026
e39ff38
refactor(sweep): consistent txid-first returns; avoid rebuild + unsig…
bitcoin-coder-bob Jun 18, 2026
77306d1
fix(arkd-wallet): select signer key per leaf across all multisig clos…
bitcoin-coder-bob Jun 18, 2026
711ca0f
Merge branch 'pr-1110' into bob/wallet-rotation-all
bitcoin-coder-bob Jun 18, 2026
d82d628
Merge branch 'bob/arkd-sweep-fallback' into bob/wallet-rotation-all
bitcoin-coder-bob Jun 18, 2026
c88c820
Merge branch 'bob/arkd-wallet-settings' into bob/wallet-rotation-all
bitcoin-coder-bob Jun 18, 2026
f0edd02
Merge branch 'bob/signer-key-leaf-guard' into bob/wallet-rotation-all
bitcoin-coder-bob Jun 18, 2026
15a8651
test(e2e): add TestEagerForfeitSurvivesWalletRotation; dedup compose env
bitcoin-coder-bob Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,13 @@ The `arkd` server can be configured using environment variables and the admin se
| `ARKD_REDIS_NUM_OF_RETRIES` | Maximum number of retries for Redis write operations in case of conflicts | - |
| `ARKD_ESPLORA_URL` | Esplora API URL | `https://blockstream.info/api` |
| `ARKD_WALLET_ADDR` | The arkd wallet address to connect to in the form `host:port` | - |
| `ARKD_WALLET_FALLBACK_ADDRS` | Additional arkd-wallet addresses (other LPs), comma-separated `host:port` list | - |
| `ARKD_SIGNER_ADDR` | The signer address to connect to in the form `host:port` | value of `ARKD_WALLET_ADDR` |
| `ARKD_NO_MACAROONS` | Disable macaroon authentication | `false` |
| `ARKD_NO_TLS` | Disable TLS | `true` |
| `ARKD_UNLOCKER_TYPE` | Wallet unlocker type (env, file) to enable auto-unlock | - |
| `ARKD_UNLOCKER_TYPE` | Macaroon (admin auth) unlocker type (env, file) to enable auto-unlock | - |
| `ARKD_UNLOCKER_FILE_PATH` | Path to unlocker file | - |
| `ARKD_UNLOCKER_PASSWORD` | Wallet unlocker password | - |
| `ARKD_UNLOCKER_PASSWORD` | Macaroon (admin auth) unlocker password | - |
| `ARKD_SCHEDULER_TYPE` | Scheduler type (gocron, block) | `gocron` |
| `ARKD_TLS_EXTRA_IP` | Extra IP addresses for TLS (comma-separated) | - |
| `ARKD_TLS_EXTRA_DOMAIN` | Extra domains for TLS (comma-separated) | - |
Expand Down Expand Up @@ -180,6 +181,16 @@ To connect `arkd` to `arkd-wallet` use this environment variable:
export ARKD_WALLET_ADDR=localhost:6060
```

### Configuring multiple LP wallets

`arkd` can be backed by a primary `arkd-wallet` plus additional wallets belonging to other liquidity providers. List the additional wallets with `ARKD_WALLET_FALLBACK_ADDRS`, a comma-separated list of `host:port` addresses:

```sh
export ARKD_WALLET_FALLBACK_ADDRS=localhost:6061,localhost:6062
```

Every wallet, primary and fallback, must be initialized and unlocked out of band (see [Setup arkd](#setup-arkd)) and must be on the same network as the primary; `arkd` validates this at startup and refuses to start otherwise. The primary wallet remains the sole source of the forfeit address, connector address, scanning and signing. The additional wallets are used only as sweep fallbacks: when a batch cannot be signed by the primary wallet (for example a batch created before this wallet became the primary), `arkd` tries each fallback wallet in turn until one can sign it. The swept funds always go to the primary wallet's address, whichever wallet signs.

### Connect to signer

By default, `arkd` makes use of the provided `arkd-wallet` also as signer, but you can customize its url either via environment variable or via API.
Expand All @@ -195,26 +206,31 @@ export ARKD_SIGNER_ADDR=localhost:7071

### Setup arkd

`arkd` does not manage the wallet lifecycle. Each `arkd-wallet` must be initialized and unlocked out of band before `arkd` is started: if the wallet is not initialized and unlocked, `arkd` refuses to start. This is what lets a single `arkd` be backed by more than one `arkd-wallet`.

1. Start the wallet:
```sh
arkd-wallet
```

2. Start arkd:
2. Initialize and unlock the wallet. `arkd` does not manage the wallet lifecycle, so this is done out of band against the `arkd-wallet`:
```sh
arkd
# Create a new wallet and unlock it (prints the seed, back it up)
arkd-wallet create --password <password>
```

3. Create a new wallet:
Or restore from mnemonic:
```sh
arkd wallet create --password <password>
arkd-wallet create --mnemonic "your twelve word mnemonic phrase here" --password <password>
```
By default these target `http://localhost:6060`; use `--url` to reach a wallet on another host. This wallet password is independent of the macaroon-service password used in step 5. After a wallet restart, unlock it again with `arkd-wallet unlock --password <password>`.

Or restore from mnemonic:
3. Start arkd:
```sh
arkd wallet create --mnemonic "your twelve word mnemonic phrase here" --password <password>
arkd
```
4. Only if you didn't configure either the wallet as signer, or a custom signer, you must load the signer before unlocking the wallet, or `arkd` will fail to start:

4. Only if you didn't configure either the wallet as signer, or a custom signer, you must load the signer, or `arkd` will be unable to start the ark service:
```sh
# If you configured a custom signer
arkd signer load --signer-url localhost:7071
Expand All @@ -223,7 +239,7 @@ export ARKD_SIGNER_ADDR=localhost:7071
```
Remember, if you use this command, you must use it at every restart unless you export the required environment variable(s).

5. Unlock the wallet:
5. If macaroon authentication is enabled and you did not configure an auto-unlocker, unlock the macaroon (admin auth) service so `arkd` can serve authenticated admin requests:
```sh
arkd wallet unlock --password <password>
```
Expand Down
13 changes: 13 additions & 0 deletions api-spec/openapi/swagger/ark/v1/admin.openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,19 @@
"null"
],
"format": "int64"
},
"walletAddr": {
"type": [
"string",
"null"
],
"description": "Primary and fallback arkd-wallet connection addresses. Seeded from env on\nfirst boot; changes take effect on the next restart."
},
"walletFallbackAddrs": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions api-spec/protobuf/ark/v1/admin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ message Settings {
optional bool build_version_header_required = 23;
optional string updated_at = 24;
optional bool digest_header_required = 25;
optional string wallet_addr = 26;
repeated string wallet_fallback_addrs = 27;
}

message GetSettingsRequest {}
Expand Down
32 changes: 27 additions & 5 deletions api-spec/protobuf/gen/ark/v1/admin.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions cmd/arkd-forfeit-backfill/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Command arkd-forfeit-backfill signs the operator's half of forfeit transactions
// that were persisted before arkd started signing forfeit txs at collection time.
//
// It connects to the same database and signer as arkd (via the standard arkd
// configuration / environment), so the arkd-wallet signer must be running and
// unlocked. It scans every unswept forfeited vtxo, signs the operator's half of
// its forfeit tx when missing, and persists the result. It is safe to run
// repeatedly: forfeit txs that already carry the operator signature are skipped.
package main

import (
"context"
"os"

"github.com/arkade-os/arkd/internal/backfill"
"github.com/arkade-os/arkd/internal/config"
log "github.com/sirupsen/logrus"
)

func main() {
cfg, err := config.LoadConfig()
if err != nil {
log.Fatalf("invalid config: %s", err)
}
log.SetLevel(log.Level(cfg.LogLevel))

repo, err := cfg.RepoManager()
if err != nil {
log.Fatalf("failed to init repositories: %s", err)
}
defer repo.Close()

signer, err := cfg.SignerService()
if err != nil {
log.Fatalf("failed to init signer: %s", err)
}

log.Info("starting forfeit-tx backfill...")
res, err := backfill.Run(context.Background(), repo.Vtxos(), repo.Rounds(), signer)
if err != nil {
log.Fatalf("forfeit-tx backfill failed: %s", err)
}

log.Infof(
"forfeit-tx backfill done: scanned=%d signed=%d already_signed=%d failed=%d",
res.Scanned, res.Signed, res.AlreadySigned, res.Failed,
)

// Non-zero exit when some forfeits could not be signed/persisted, so the
// operator (or a wrapping script) notices and re-runs after fixing the cause.
if res.Failed > 0 {
os.Exit(1)
}
}
Loading
Loading