Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion ci/test/00_setup_env_native_asan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ fi

export CONTAINER_NAME=ci_native_asan
export APT_LLVM_V="22"
export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev mold python3-zmq qt6-base-dev qt6-tools-dev qt6-l10n-tools libevent-dev libboost-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE} libcapnp-dev capnproto python3-pip"
export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev mold python3-zmq qt6-base-dev qt6-tools-dev qt6-l10n-tools libevent-dev libboost-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE} libcapnp-dev capnproto python3-pip curl ca-certificates"
export PIP_PACKAGES="--break-system-packages pycapnp"
export NO_DEPENDS=1
export GOAL="install"
export CI_LIMIT_STACK_SIZE=1
export RUN_ORD_TESTS=true
export ORD_VERSION=0.29.0
export ORD_LINUX_X86_64_SHA256=f65c758d71549954470aa7fe23b197478688fb4f910e84c2956cf9144078a94e
export BITCOIN_CONFIG="\
--preset=dev-mode \
-DSANITIZERS=address,float-divide-by-zero,integer,undefined \
Expand Down
18 changes: 18 additions & 0 deletions ci/test/03_test_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,24 @@ if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then
--failfast
fi

if [ "${RUN_ORD_TESTS:-false}" = "true" ]; then
ORD_TEST_DIR="${BASE_SCRATCH_DIR}/ord-${ORD_VERSION}"
ORD_ARCHIVE="${ORD_TEST_DIR}/ord.tar.gz"
mkdir -p "${ORD_TEST_DIR}"
curl --proto '=https' --tlsv1.2 --fail --location --retry 3 \
--output "${ORD_ARCHIVE}" \
"https://github.com/ordinals/ord/releases/download/${ORD_VERSION}/ord-${ORD_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
echo "${ORD_LINUX_X86_64_SHA256} ${ORD_ARCHIVE}" | sha256sum --check
tar --extract --gzip --file "${ORD_ARCHIVE}" --directory "${ORD_TEST_DIR}"
ORD="${ORD_TEST_DIR}/ord-${ORD_VERSION}/ord" \
LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" \
"${BASE_BUILD_DIR}/test/functional/test_runner.py" \
feature_ord_index.py \
--tmpdirprefix "${BASE_SCRATCH_DIR}/ord_test_runner/" \
--timeout-factor="${TEST_RUNNER_TIMEOUT_FACTOR}" \
--quiet
fi

if [ "${RUN_TIDY}" = "true" ]; then
cmake -B /tidy-build -DLLVM_DIR=/usr/lib/llvm-"${TIDY_LLVM_V}"/cmake -DCMAKE_BUILD_TYPE=Release -S "${BASE_ROOT_DIR}"/contrib/devtools/bitcoin-tidy
cmake --build /tidy-build "$MAKEJOBS"
Expand Down
1 change: 0 additions & 1 deletion depends/packages/qt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ $(package)_config_opts_darwin += -no-feature-freetype
$(package)_config_opts_darwin += -no-pkg-config

$(package)_config_opts_linux := -fontconfig
$(package)_config_opts_linux += -no-feature-process
$(package)_config_opts_linux += -no-feature-xlib
$(package)_config_opts_linux += -no-xcb-xlib
$(package)_config_opts_linux += -pkg-config
Expand Down
108 changes: 108 additions & 0 deletions doc/ord-inscriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Experimental Ord inscription interface

DogMode provides an experimental **Inscribe** page when Ord was enabled during
initial setup and the pinned Ord executable is installed. The page accepts one
local image or data file through drag and drop or a file picker, previews image
formats supported by Qt, and invokes the pinned Ord command-line interface.

The page detects the dedicated Bitcoin Core wallet named `ord`. It can create a
new wallet or restore one from BIP39 recovery words. New recovery words are
shown once in an application-owned, non-dismissible dialog even if the user
navigates away or closes the selected Qt wallet during creation. The words
cannot be selected or copied to either clipboard. The user must confirm that
they were recorded before continuing. A durable `ord/backup-required` marker
blocks funding-address display and inscriptions until acknowledgment. If the
application exits before backup completes, this gate stays closed on restart;
restore from a known backup or explicitly recover/back up the Core wallet before
using it. Do not delete that marker without verifying the backup. Restore words
are passed to Ord over standard input instead of process arguments. BIP39
passphrases are intentionally not
accepted because Ord 0.29.0 can only receive them through process arguments,
where other local processes may be able to read them.

Once the wallet is available, the page displays its cardinal balance before
non-common-sat exclusions, total balance, and a funding address. The wallet
selected in DogMode's toolbar is not used to fund inscriptions.

After the initial one-shot index build, DogMode runs Ord's HTTP server on a
kernel-assigned ephemeral loopback-only port. Ord binds port zero itself and
reports the selected port, avoiding a close-and-rebind race. Wallet commands
use that loopback endpoint, which keeps the Ord index synchronized while
DogMode is running without exposing the server to the local network. The Ord
HTTP server has no application-layer authentication: loopback limits it to
local processes but is not an authentication boundary. Transaction construction
and signing remain confined to the pinned Ord CLI and dedicated `ord` wallet.

The page supports:

- an explicit fee rate in sats/vB;
- an optional destination address;
- Ord's optional Brotli content compression; and
- an Ord `--dry-run` cost preview that must match the exact file and settings;
- confirmation immediately before transaction creation and broadcast.

The interface runs the equivalent of:

```sh
ord \
--chain <network> \
--bitcoin-data-dir <bitcoin-data-directory> \
--bitcoin-rpc-url <authenticated-wallet-scoped-gate> \
--cookie-file <private-gate-cookie> \
--config <private-empty-config> \
--index <managed-index.redb> \
--data-dir <ord-data-directory> \
--index-runes --index-sats \
wallet --server-url <loopback-ord-server> --name ord inscribe \
--fee-rate <sats-per-vbyte> \
--file <selected-file>
```

The destination and compression arguments are appended only when selected. A
preview copies the complete selected file into a private, immutable snapshot
and records its hash, fee, destination, and compression settings in a one-shot
manager authorization. Changing any input—or changing the original file
contents—requires a new preview before broadcast. Immediately before broadcast,
DogMode repeats the dry-run against the same snapshot and requires the mining
fee estimate to match. Ord then constructs the live transaction plan in a
separate CLI invocation, so a concurrent change to wallet state can still make
the live command fail or produce a different final fee. Review the returned
transaction result after broadcast. The preview reports Ord's mining-fee estimate,
the default 10,000-sat postage, and the wallet's cardinal balance before
non-common-sat exclusions. Insufficient safe funding fails closed.
DogMode does not invoke a shell, and Ord process output is bounded to 1 MiB.
Symbolic links, device files, files larger than 10 MiB, and oversized image
previews are rejected. Fee rates are limited to 0.1–1,000 sats/vB.

## Important safety notes

Creating an inscription broadcasts Bitcoin transactions, pays mining fees, and
cannot be undone. Verify the selected file, its size, fee rate, destination, and
the backup for the `ord` wallet before confirming. Ord may reject content that
would produce non-standard transactions. DogMode does not enable Ord's
`--no-limit`, reinscription, parent, delegate, metadata, or rare-sat options in
this initial interface.

The managed index enables inscription, rune, and sat indexing and verifies
these capabilities through the server status endpoint. Sat indexing by itself
does not protect non-common sats: before preview DogMode obtains Ord's cardinal
UTXOs and subtracts all outputs reported by `ord wallet sats`. The resulting
input allowlist stays fixed through revalidation and broadcast. A private,
authenticated loopback RPC gate filters wallet coin listings and rejects any
commit broadcast that spends an input outside that allowlist. Reveals may only
spend outputs of a successfully broadcast approved commit. Newly arriving
UTXOs cannot enter the plan, even if the wallet changes after preview. The
gate executes RPCs against `/wallet/ord` on DogMode's own node; it never uses
the Qt-selected wallet. This protection does not apply to direct terminal use.
Inherited `ORD_*` settings are stripped, and managed invocations explicitly pin
their configuration, index, cookie path, and Bitcoin RPC endpoint. These indexes
increase initial synchronization time and disk use, especially on mainnet.
Ord 0.29.0 cannot retrofit these tables into an index created without them, so
DogMode uses the separate versioned `ord/data-runes-sats-v1` directory and
leaves any legacy `ord/data` index untouched. Upgrades require a new index
synchronization and temporarily require space for both indexes.

The compression checkbox enables Ord's lossless Brotli compression. It does not
resize images or change image quality. Image transcoding should be implemented
and reviewed separately so that the exact bytes being inscribed are always
clear to the user.
82 changes: 82 additions & 0 deletions doc/ord.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Optional Ord integration

DogMode can install and initialize the [`ord`](https://github.com/ordinals/ord)
indexer as an explicit option during first-run setup. This integration does not
enable Ord by default. An experimental inscription page is available after Ord
is installed.

The follow-up experimental inscription interface is documented in
[`ord-inscriptions.md`](ord-inscriptions.md).

## What the option changes

Selecting **Download and synchronize Ord** disables pruning and enables the
Bitcoin Core options required by Ord: `txindex`, `server`, and `rest`. These
values are saved in `settings.json`. An explicit conflicting command-line value,
such as `-prune=1` or `-txindex=0`, causes startup to stop with an explanation
instead of silently overriding the command line.

After Bitcoin Core and its transaction index are synchronized, DogMode:

1. Opens the pinned Ord 0.29.0 release in the system browser when requested and
asks you to select the downloaded archive.
2. Verifies the selected archive against a checksum compiled into DogMode.
3. Extracts it with the platform `tar` program, checks `ord --version`, and
installs it atomically.
4. Runs `ord --index-runes --index-sats index update` in the background with
cookie authentication. These indexes supply asset information. The inscription
UI separately excludes non-common-sat outputs and enforces a frozen funding
input allowlist at its wallet-scoped RPC gate; indexing alone is not protection.

The Ord executable and index are stored below the network-specific Bitcoin data
directory:

```
ord/bin/0.29.0/ord
ord/data-runes-sats-v1/
```

On Windows the executable is named `ord.exe`. Testnet, testnet4, signet, and
regtest each use their own Bitcoin network data directory and Ord index.

## Terminal use

The executable is deliberately not added to `PATH`. Invoke it by its full path.
For a custom Bitcoin data directory, also pass the matching Bitcoin data and
cookie paths. For example on mainnet:

```sh
<bitcoin-data-dir>/ord/bin/0.29.0/ord \
--bitcoin-data-dir <bitcoin-data-dir> \
--cookie-file <bitcoin-data-dir>/.cookie \
--data-dir <bitcoin-data-dir>/ord/data-runes-sats-v1 \
--index <bitcoin-data-dir>/ord/data-runes-sats-v1/index.redb \
--index-runes \
--index-sats \
index info
```

Direct terminal spending bypasses the GUI's funding-input gate:
sat indexing alone does not stop Ord from selecting non-common sats. Inspect and
protect valuable outputs before any terminal operation. Ord is third-party
experimental software, distributed separately under
its own license. DogMode itself does not make network requests to install Ord;
the system browser performs the download. The rune and sat indexes require
significant additional synchronization time and disk space, especially on
mainnet. Deleting the `ord/` directory removes the installed executable and
index but does not change DogMode's saved full-node settings.

Ord 0.29.0 cannot add rune and sat tracking to an index that was originally
created without those options. DogMode therefore uses the versioned
`ord/data-runes-sats-v1` directory and leaves a legacy `ord/data` directory
untouched. Upgrading from an earlier build requires a new synchronization and
temporarily needs disk space for both indexes. After the new index is fully
synchronized and the dedicated Ord wallet is verified, the unused legacy
`ord/data` directory may be removed manually.

## Updating the pinned release

Update the version, URLs, and all platform checksums together in
`src/qt/ordinstaller.cpp`. The extended CI job independently downloads the
Linux archive, verifies its pinned checksum, and runs
`test/functional/feature_ord_index.py` against a regtest node.
9 changes: 9 additions & 0 deletions doc/release-notes-ord.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Optional Ord full-node setup
============================

The first-run data-directory dialog now offers an opt-in option to install and
synchronize Ord. Enabling it configures an unpruned node with `txindex`, RPC
server, and REST support, directs the user to the pinned official Ord release,
verifies the selected archive's checksum and version, and builds the Ord index
after Bitcoin synchronization. Ord remains a command-line tool in this release.
See `doc/ord.md` for storage, security, and terminal-use details.
16 changes: 15 additions & 1 deletion src/qt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ add_library(bitcoinqt STATIC EXCLUDE_FROM_ALL
optionsdialog.h
optionsmodel.cpp
optionsmodel.h
ordconfiguration.cpp
ordconfiguration.h
ordinstaller.cpp
ordinstaller.h
ordinscriptionpage.cpp
ordinscriptionpage.h
ordmanager.cpp
ordmanager.h
ordprocess.cpp
ordprocess.h
ordrecoverydialog.cpp
ordrecoverydialog.h
ordrpcgate.cpp
ordrpcgate.h
peertablemodel.cpp
peertablemodel.h
peertablesortproxy.cpp
Expand Down Expand Up @@ -146,6 +160,7 @@ set_property(SOURCE macnotificationhandler.mm
target_link_libraries(bitcoinqt
PUBLIC
Qt6::Widgets
Qt6::Network
PRIVATE
core_interface
bitcoin_cli
Expand Down Expand Up @@ -223,7 +238,6 @@ if(ENABLE_WALLET)
target_link_libraries(bitcoinqt
PRIVATE
bitcoin_wallet
Qt6::Network
)
endif()

Expand Down
Loading