From 0755c2c563f640ccadb21012e3d42d16458df2de Mon Sep 17 00:00:00 2001 From: retraca Date: Wed, 3 Jun 2026 21:37:15 +0700 Subject: [PATCH] spel-cli: support account_id instruction arguments spel-framework's IDL generator emits the primitive type "account_id" for AccountId arguments (account_types.rs), but the CLI's submit path (parse_primitive / primitive_to_dynamic) has no account_id arm, so any instruction with an AccountId argument fails with "type mismatch: expected account_id". The path went untested because the e2e fixture types key arguments as [u8; 32]. nssa's AccountId is SerializeDisplay / DeserializeFromStr, i.e. a base58 string on the wire, so this normalizes the input (base58 / 0xhex / Public-prefixed) to canonical base58 and serializes it as a string. Verified on a locally-run standalone sequencer: an instruction taking an AccountId argument now builds, signs, submits, and lands, checked against on-chain state. Existing programs that typed key args as [u8; 32] are unaffected. --- spel-cli/src/parse.rs | 9 +++++++++ spel-cli/src/serialize.rs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/spel-cli/src/parse.rs b/spel-cli/src/parse.rs index 705c0f8..e7e89d6 100644 --- a/spel-cli/src/parse.rs +++ b/spel-cli/src/parse.rs @@ -98,6 +98,15 @@ fn parse_primitive(raw: &str, prim: &str) -> Result { _ => Err(format!("Invalid bool '{}': expected true/false", raw)), }, "string" | "String" => Ok(ParsedValue::Str(raw.to_string())), + // nssa AccountId is SerializeDisplay/DeserializeFromStr: a base58 string on the + // wire, not 32 raw bytes. Normalize any input (base58 / 0xhex / Public-prefixed) + // to canonical base58 and carry it as a string. + "account_id" => { + use base58::ToBase58 as _; + crate::hex::decode_bytes_32(raw) + .map(|b| ParsedValue::Str(b.to_base58())) + .map_err(|e| format!("Invalid account_id '{}': {}", raw, e)) + } other => Ok(ParsedValue::Raw(format!("{}({})", other, raw))), } } diff --git a/spel-cli/src/serialize.rs b/spel-cli/src/serialize.rs index 1b40c79..ade1c14 100644 --- a/spel-cli/src/serialize.rs +++ b/spel-cli/src/serialize.rs @@ -125,6 +125,8 @@ fn primitive_to_dynamic(prim: &str, val: &ParsedValue) -> Result Ok(DynamicValue::Tuple( vals.iter().map(|v| DynamicValue::U32(*v)).collect(), )), + // nssa AccountId serializes via Display (base58 string), not as raw bytes. + ("account_id", ParsedValue::Str(s)) => Ok(DynamicValue::Str(s.clone())), _ => Err(SerializeError::TypeMismatch { expected: prim.to_string(), got: format!("{:?}", val),