phase 3.2: cip-25 metadata via the pallas fork
unblocks named mints. wallet.mint now accepts an optional `metadata`
arg (json object); explorers + wallets render the asset with name/image
instead of <asset1xyz...>.
new aldabra-core::metadata module:
- json_to_metadatum: serde_json::Value → Metadatum (recursive). numbers
must fit i64 (cardano metadata Int width). strings >64 bytes split
into Array<Text> chunks at utf-8 char boundaries (CIP-25 v2
long-string convention). null is rejected.
- build_cip25_aux_data(policy_id_hex, asset_name_hex, json_value):
builds the label-721 wrapper (Map { 721: Map { policy_bytes:
Map { name_bytes: attrs }, "version": "2.0" } }), wraps in
AuxiliaryData::PostAlonzo, returns cbor bytes.
mint module:
- new build_signed_mint_with_metadata + build_unsigned_mint now take
optional cip25_metadata. backward-compat: build_signed_mint is a
thin no-metadata wrapper.
- prepare_mint + build_mint_staging plumb aux_data_cbor through.
staging.auxiliary_data(bytes) is the new fork API surface — when
set, conway::build_conway_raw decodes + computes
auxiliary_data_hash automatically.
- regression test build_signed_mint_with_metadata_produces_aux_hash:
decodes the resulting signed cbor, asserts both
body.auxiliary_data_hash is Some and tx.auxiliary_data is present.
catches the failure mode where metadata is silently dropped.
mcp wallet.mint gains a `metadata` arg field surfaced via schemars
JsonSchema. tools/list shape correctly carries the optional json
object.
depends on Sulkta-Coop/pallas@feat-aux-data — vendored via
[patch.crates-io] in the workspace Cargo.toml. PR upstream pending.
56 → 65 unit tests. 8 → 8 mcp tools (count unchanged, wallet.mint
gained an arg).
This commit is contained in:
parent
532b3d3558
commit
218d1ac94b
7 changed files with 450 additions and 20 deletions
|
|
@ -26,8 +26,9 @@ use std::sync::Arc;
|
|||
|
||||
use aldabra_chain::{ChainBackend, KoiosClient};
|
||||
use aldabra_core::{
|
||||
build_signed_mint, build_signed_payment_with_assets, build_unsigned_payment_with_assets,
|
||||
hex_decode, AssetSpec, InputUtxo, Network, PaymentKey, PolicySpec, ProtocolParams,
|
||||
build_signed_mint_with_metadata, build_signed_payment_with_assets,
|
||||
build_unsigned_payment_with_assets, hex_decode, AssetSpec, InputUtxo, Network, PaymentKey,
|
||||
PolicySpec, ProtocolParams,
|
||||
};
|
||||
use rmcp::{model::ServerInfo, schemars, tool, ServerHandler};
|
||||
use serde::Deserialize;
|
||||
|
|
@ -156,6 +157,12 @@ pub struct MintArgs {
|
|||
/// to the wallet's payment key.
|
||||
#[serde(default)]
|
||||
pub invalid_after_slot: Option<u64>,
|
||||
/// Optional CIP-25 v2 metadata: a JSON object with the asset's
|
||||
/// per-attributes (`name`, `image`, `description`, `mediaType`,
|
||||
/// `files`, etc.). Wallets and explorers display this when
|
||||
/// rendering the asset.
|
||||
#[serde(default)]
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[tool(tool_box)]
|
||||
|
|
@ -394,7 +401,7 @@ impl WalletService {
|
|||
|
||||
#[tool(
|
||||
name = "wallet.mint",
|
||||
description = "Mint or burn a native asset under a wallet-generated single-sig policy. Args: dest_address, dest_lovelace (ADA to attach to the mint output, ≥ ~1.5 ADA for an asset-bearing utxo), asset_name_hex, quantity (positive=mint, negative=burn), invalid_after_slot (optional). Returns the tx hash on success. NB: this version does not attach CIP-25 metadata — pallas-txbuilder 0.32 doesn't surface auxiliary_data yet."
|
||||
description = "Mint or burn a native asset under a wallet-generated single-sig policy, optionally with CIP-25 v2 metadata. Args: dest_address, dest_lovelace (≥ 1.5 ADA for asset-bearing UTXO), asset_name_hex, quantity (positive=mint, negative=burn), invalid_after_slot (optional), metadata (optional CIP-25 JSON object: {name, image, description, mediaType, files, ...}). Returns the tx hash on success."
|
||||
)]
|
||||
async fn wallet_mint(
|
||||
&self,
|
||||
|
|
@ -404,6 +411,7 @@ impl WalletService {
|
|||
asset_name_hex,
|
||||
quantity,
|
||||
invalid_after_slot,
|
||||
metadata,
|
||||
}: MintArgs,
|
||||
) -> Result<String, String> {
|
||||
if quantity == 0 {
|
||||
|
|
@ -443,7 +451,7 @@ impl WalletService {
|
|||
None => PolicySpec::single_sig(&self.inner.payment_key),
|
||||
};
|
||||
|
||||
let cbor = build_signed_mint(
|
||||
let cbor = build_signed_mint_with_metadata(
|
||||
&self.inner.payment_key,
|
||||
self.inner.network,
|
||||
&inputs,
|
||||
|
|
@ -453,6 +461,7 @@ impl WalletService {
|
|||
&policy,
|
||||
&asset_name_hex,
|
||||
quantity,
|
||||
metadata.as_ref(),
|
||||
&ProtocolParams::default(),
|
||||
)
|
||||
.map_err(|e| format!("build/sign mint: {e}"))?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue