# Phantasma Rust SDK

Rust SDK for the Phantasma blockchain with support for the Phoenix chain update.

The crate provides transaction building and signing, VM script helpers, Ed25519
keys/signatures, JSON-RPC access, and Carbon wire-format support.

The public API is organized around checked primitives:

- `crypto`: Ed25519 keys, WIF, Phantasma addresses, hashes, signatures.
- `binary`: VM binary readers and writers.
- `vm`: script building and VM object parsing.
- `transaction`: VM script transactions and proof-of-work helpers.
- `carbon`: Carbon wire formats, token/NFT schemas, signed Carbon transaction
  messages, and builder helpers.
- `rpc`: async JSON-RPC client, response models, state helpers, and send
  helpers for VM script and Carbon transactions.

All fallible APIs return `phantasma_sdk::Result<T>`. Public parsing code rejects
malformed input with explicit errors instead of panicking.

## Installation

```toml
[dependencies]
phantasma-sdk = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

## Read-Only RPC

```rust
use phantasma_sdk::{PhantasmaRpc, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let rpc = PhantasmaRpc::new("http://localhost:5172/rpc");
    let version = rpc.get_version().await?;
    println!("{} {}", version.version, version.commit);
    Ok(())
}
```

Indexers that need both typed models and archival/parity payloads can use the
`*_with_raw` helpers:

```rust
let response = rpc.get_block_by_height_with_raw("main", 123).await?;
println!("{} {}", response.value.hash, response.raw_result);
```

## Offline VM Script Transaction

```rust
use phantasma_sdk::{Address, PhantasmaKeys, Result, ScriptBuilder, Transaction, encode_hex};

fn main() -> Result<()> {
    let keys = PhantasmaKeys::try_from_slice(&[7u8; 32])?;
    let from = keys.address();
    let to = Address::from_hash(b"example receiver");

    let script = ScriptBuilder::begin()
        .allow_gas(from, Address::null(), 100_000, 21_000)
        .transfer_tokens("SOUL", from, to, 1)
        .spend_gas(from)
        .end_script()?;

    let mut tx = Transaction::new("mainnet", "main", script, 0).with_payload(b"example".to_vec());
    tx.sign(&keys);

    println!("{}", encode_hex(tx.to_bytes(true)));
    Ok(())
}
```

## Offline Carbon Transaction

```rust
use phantasma_sdk::{
    bytes32_from_public_key, sign_and_serialize_tx_msg_hex, PhantasmaKeys, Result, SmallString,
    TxMsg, TxMsgTransferFungible, TxPayload, TxType,
};

fn main() -> Result<()> {
    let keys = PhantasmaKeys::try_from_slice(&[7u8; 32])?;
    let signer = bytes32_from_public_key(&keys.public_key())?;
    let receiver = bytes32_from_public_key(&PhantasmaKeys::try_from_slice(&[9u8; 32])?.public_key())?;

    let msg = TxMsg {
        tx_type: TxType::TransferFungible,
        expiry: 1_759_711_416_000,
        max_gas: 10_000_000,
        max_data: 1_000,
        gas_from: signer,
        payload: SmallString::new("example")?,
        msg: TxPayload::TransferFungible(TxMsgTransferFungible {
            to: receiver,
            token_id: 1,
            amount: 1_000_000,
        }),
    };

    println!("{}", sign_and_serialize_tx_msg_hex(&msg, &keys)?);
    Ok(())
}
```

## Verification

Use `just verify` for the normal local gate:

```bash
just verify
```

That runs formatting checks, all-target compilation, unit tests, Clippy with
warnings denied, and docs with rustdoc warnings denied. Use `just release-check`
before publishing; it also verifies strict package creation and runs
`cargo publish --dry-run`.

The test suite includes cross-SDK vectors copied from the Python SDK fixture set,
including Carbon primitives, `IntX`, VM structs, Carbon transactions, VM
scripts, WIF/address/signature behavior, RPC request parsing, and hostile
input rejection paths.
