Tinylayer Mutinynet wallet
tinylayer-wallet is a one-coin educational CLI for protocol 2. It derives a
BIP448 funding address without registration, performs encrypted off-chain
transfers, watches the canonical funding lineage, replaces stale states, and
settles after a 12-block contest delay.
It supports Mutinynet only.
Build
cargo build --locked --release -p tinylayer-wallet
alias tinylayer-wallet="$PWD/target/release/tinylayer-wallet"
Set a password or pass --password-file:
export ENCLAVIA_WALLET_PASSWORD='replace this'
Every wallet directory and secret file must have Unix mode 0700/0600.
Initialize
Production Enclavia:
tinylayer-wallet --data-dir alice init \
--enclave-url wss://<deployment>.enclavia.io \
--pcr0 <96-hex> \
--pcr1 <96-hex> \
--pcr2 <96-hex>
The output includes a fee address. Fund it with Mutinynet sats before an exit; those sats pay for the P2A package child while the statecoin amount stays constant.
Local workload testing is explicit and unsafe:
tinylayer-wallet --data-dir alice init \
--enclave-url http://127.0.0.1:8080 \
--unsafe-plaintext \
--explorer-url https://mutinynet.com/api
Never use --unsafe-plaintext with meaningful secrets.
Create and fund a coin
tinylayer-wallet --data-dir alice coin new --amount-sat 100000
This command:
- Fetches stateless service info and pins the global Enclavia key.
- Generates client, capability, and settlement secrets.
- Builds initial update
U1with a placeholder prevout. - Computes BIP446 TemplateHash.
- Builds a funding tree whose bootstrap leaf commits to
U1. - Saves everything before printing the address.
It does not allocate enclave state.
Send exactly 100,000 sats from the Mutinynet faucet to the returned address. After confirmation:
tinylayer-wallet --data-dir alice coin bind \
--outpoint <funding-txid>:<vout>
The wallet independently checks confirmation, amount, script, and unspent
status. The null prevout in U1 is replaced with the concrete funding outpoint;
its TemplateHash does not change.
If the service never returns, Alice can still publish U1 and settle.
Alice to Bob
Initialize Bob, then create a receiver request:
tinylayer-wallet --data-dir bob init \
--enclave-url wss://<deployment>.enclavia.io \
--pcr0 <96-hex> --pcr1 <96-hex> --pcr2 <96-hex>
tinylayer-wallet --data-dir bob transfer request \
--output bob-request.json
Authenticate the request file or its digest out of band. It controls the next capability, settlement key, and transport encryption key.
Alice sends:
tinylayer-wallet --data-dir alice transfer send \
--request bob-request.json \
--output bob-package.json
On the first transfer this command rechecks the confirmed funding output, then
lazily sends Enclavia only coin ID, capability hash, and TemplateHash(U1).
The workload has no Bitcoin or network access. Alice builds state 2, stores the
exact request, obtains one Enclavia signature, and encrypts the complete history
to Bob. Public deployments must gate activation outside Enclavia.
After Enclavia accepts state 2, Alice no longer controls a valid current capability. Output failure is recovered by repeating the same command and request; the saved package is emitted without another transition.
Bob accepts:
tinylayer-wallet --data-dir bob transfer receive \
--request bob-request.json \
--package bob-package.json
Bob verifies funding, both signatures on every non-bootstrap state, ordered locktimes, history length, current Enclavia status, transferred client key, and his latest settlement key before saving the coin.
Repeat the same three commands for Bob to Carol. No Bitcoin transaction is broadcast during either transfer.
Status
tinylayer-wallet --data-dir bob status
The local report shows funding outpoint, state number, activation state, and fee
address. Use --json before the subcommand for machine-readable one-line JSON.
Exit and stale-state defense
Fund the fee address first:
tinylayer-wallet --data-dir bob fee-address
Then run:
tinylayer-wallet --data-dir bob exit \
--destination <mutinynet-address>
The command follows the funding outspend:
- unspent funding: bind the latest update to the funding live leaf;
- bootstrap owner: publish
U1through its committed leaf; - known stale state: reconstruct that state’s hidden tree from encrypted history and bind the latest update to its output;
- unknown spend: fail closed.
A zero-fee update and fee-paying P2A child are submitted as a package. Repeat the command to see the contest countdown. After 12 confirmations, repeat once more to sign and broadcast settlement through the latest withdrawal leaf.
No Enclavia call occurs during exit or stale-state replacement.
Public proof sequence
The intended demonstration uses three wallet directories:
fund Alice
Alice → Bob
Bob → Carol
stop Enclavia
publish Alice's U1
confirm U1
run Carol exit: U3 is rebound to U1:0
confirm U3
wait 12 blocks
run Carol exit again: settlement broadcasts
Record the funding, stale update, rebound latest update, P2A children, and settlement transaction IDs. The client test already asserts that U3’s client and Enclavia signature bytes do not change during rebinding; the public chain proves Mutinynet consensus accepts them.
Operational boundaries
- The CLI stores one coin at a time.
- Transfer files grow with state history and are capped at 8 MiB.
- Duplicate payments to a used funding script are unsupported.
- The wallet must run or delegate monitoring during the 12-block contest.
- The default public explorer is a convenience, not an independently verified chain source.
- Mutinynet may reorganize or reset experimental deployments.
- This is not a mainnet wallet.