phase 2.1-2.4: send path — submit + status, txbuilder, wallet.send, wallet.tx_status

chain backend grew submit_tx (POST /submittx, raw cbor body) and
tx_status (POST /tx_info → Confirmed{block,epoch}|NotFound). serde
tag-based status enum so the mcp tool returns clean json.

new core::tx module: ProtocolParams + InputUtxo + build_signed_payment.
two-pass fee refinement — build unsigned, measure size, add witness
overhead constant (128 bytes for vkey+sig+cbor framing), recompute
real fee, build with final fee, sign once (PrivateKey doesn't impl
Clone in pallas-wallet, so we don't double-sign). change below
min-utxo merges into fee instead of emitting dust.

added pallas-txbuilder + pallas-wallet 0.32 deps. PaymentKey gains
crate-private xprv() accessor; payment_key_to_private converts
ed25519-bip32 XPrv → pallas-wallet PrivateKey::Extended via the
64-byte extended secret bytes.

mcp tools.rs: 4 → 6 tools.
- wallet.send (to_address, lovelace, force) with hard-cap guard
- wallet.tx_status (tx_hash) → status json
SendArgs/TxStatusArgs use schemars derive so rmcp generates proper
input schemas. config.rs adds max_send_lovelace (default 100 ADA,
ALDABRA_MAX_SEND_LOVELACE env override).

37 unit tests. mcp tools/list smoke confirms all 6 tools register
with correct schemas (force defaults false, lovelace required uint64,
to_address required string).

phase 2.5 (native-asset send), 2.6 (cold-sign offline mode), and
2.7 (real preprod smoke against a funded wallet) still open.
This commit is contained in:
Sulkta 2026-05-04 11:18:33 -07:00
parent 2b4fdff0c0
commit 44bae07bc9
11 changed files with 821 additions and 29 deletions

68
Cargo.lock generated
View file

@ -87,6 +87,8 @@ dependencies = [
"pallas-codec",
"pallas-crypto",
"pallas-primitives",
"pallas-txbuilder",
"pallas-wallet",
"serde",
"thiserror 1.0.69",
"zeroize",
@ -205,6 +207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc"
dependencies = [
"bitcoin_hashes",
"rand_core 0.6.4",
"serde",
"unicode-normalization",
]
@ -453,6 +456,12 @@ dependencies = [
"cryptoxide",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "equivalent"
version = "1.0.2"
@ -1078,6 +1087,15 @@ dependencies = [
"serde",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.18"
@ -1287,6 +1305,56 @@ dependencies = [
"serde_json",
]
[[package]]
name = "pallas-traverse"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be7fbb1db75a0b6b32d1808b2cc5c7ba6dd261f289491bb86998b987b4716883"
dependencies = [
"hex",
"itertools",
"pallas-addresses",
"pallas-codec",
"pallas-crypto",
"pallas-primitives",
"paste",
"serde",
"thiserror 1.0.69",
]
[[package]]
name = "pallas-txbuilder"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff83ae515a88b1ecf5354468d9fd3562d915e5eceb5c9467f6b1cdce60a3e9a"
dependencies = [
"hex",
"pallas-addresses",
"pallas-codec",
"pallas-crypto",
"pallas-primitives",
"pallas-traverse",
"pallas-wallet",
"serde",
"serde_json",
"thiserror 1.0.69",
]
[[package]]
name = "pallas-wallet"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "086f428e68ab513a0445c23a345cd462dc925e37626f72f1dbb7276919f68bfa"
dependencies = [
"bech32",
"bip39",
"cryptoxide",
"ed25519-bip32",
"pallas-crypto",
"rand 0.8.6",
"thiserror 1.0.69",
]
[[package]]
name = "parking_lot"
version = "0.12.5"