Skip to content

MoveIndustries/mpp-movement

mpp-movement

Rust SDK for the Machine Payments Protocol (MPP) on Movement Network.

Lets any client — agents, apps, or humans — pay for any service in the same HTTP request using HTTP 402 (Payment Required). Supports one-time charges, streaming payments via payment channels, and any Fungible Asset token (MOVE, USDC.e, USDCx, etc.).

Built on the MovementStreamChannel Move contract for on-chain payment channel settlement.

Install

cargo add mpp --git https://github.com/andygolay/mpp-movement --features movement,client,server

Quick Start

Server

use mpp::server::{Mpp, movement, MovementConfig};

// Create a payment handler — currency, realm, secret all have smart defaults
let mpp = Mpp::create_movement(movement(MovementConfig {
    recipient: "0x3e9e...",
})
.rest_url("https://testnet.movementnetwork.xyz/v1")
.secret_key("my-secret"))?;

// Generate a charge challenge for $0.10
let challenge = mpp.movement_charge("0.10")?;

With the Axum extractor, you can gate any route behind a payment in one line:

use mpp::server::axum::{MppCharge, ChargeConfig};

struct TenCents;
impl ChargeConfig for TenCents {
    fn amount() -> &'static str { "0.10" }
}

async fn paid_endpoint(charge: MppCharge<TenCents>) -> &'static str {
    "You paid! Here's your content."
}

Client (one-time charge)

use mpp::client::{Fetch, MovementProvider};

let provider = MovementProvider::new(signing_key, "https://testnet.movementnetwork.xyz/v1")?;

// Automatic 402 handling: GET → 402 → pay on-chain → retry with credential → 200
let resp = client.get(url).send_with_payment(&provider).await?;

Works with any FA token — the SDK picks the right transfer function (aptos_account::transfer for native MOVE, primary_fungible_store::transfer for USDC.e, USDCx, etc.).

Client (session / streaming)

use mpp::client::{Fetch, MovementSessionProvider};

let session = MovementSessionProvider::new(signing_key, rest_url)?
    .with_max_deposit(1_000_000);

// First request: opens payment channel on-chain automatically
let resp = client.get(url).send_with_payment(&session).await?;

// Subsequent requests: off-chain vouchers, no gas!
let resp = client.get(url).send_with_payment(&session).await?;
let resp = client.get(url).send_with_payment(&session).await?;

println!("Total spent: {} base units", session.cumulative());

Voucher Signing

use mpp::protocol::methods::movement::voucher;

// Sign a voucher (off-chain, matches on-chain MovementStreamChannel contract)
let sig = voucher::sign_voucher(&signing_key, &channel_id, cumulative_amount);

// Verify (server-side)
let valid = voucher::verify_voucher(&channel_id, amount, &sig, &pubkey, &authorized_pubkey);

Feature Flags

Feature Description
movement Movement Network support (ed25519, BCS, sha3-256)
client Client-side payment providers + REST client
server Server-side session method, channel store, SSE metering
axum Axum extractor for per-route payment gating
tower Tower middleware for server-side integration
middleware reqwest-middleware with PaymentMiddleware
observability Structured logging via tracing (zero-cost when disabled)
utils Hex/rand utilities

Examples

All examples run against Movement testnet with real on-chain transactions. See examples/.

Fortune Teller (one-time charge)

Server uses Mpp::create_movement() + Axum MppCharge extractor. Client uses MovementProvider + send_with_payment().

cd examples/rust
cargo run --bin movement-payment-server    # Terminal 1
cargo run --bin movement-payment-client    # Terminal 2

Multi-Fetch Scraper (session payments)

Server verifies vouchers via SessionMethod. Client uses MovementSessionProvider — opens a channel on the first request, then sends off-chain vouchers for subsequent requests.

cd examples/rust
cargo run --bin movement-multifetch-server    # Terminal 1
cargo run --bin movement-multifetch-client    # Terminal 2

Pay-Per-Token LLM Streaming (SSE + payment channels)

Server streams tokens via Server-Sent Events, settling vouchers on-chain periodically. Client opens a channel and pays per token batch.

cd examples/rust
cargo run --bin movement-sse-server    # Terminal 1
cargo run --bin movement-sse-client    # Terminal 2

Streaming Demo (React)

A browser-based demo that connects to the SSE server. Users connect a Movement wallet, open a payment channel, and stream AI text paid with off-chain vouchers.

cargo run --manifest-path examples/rust/Cargo.toml --bin movement-sse-server  # Terminal 1
cd examples/token-stream && pnpm install && pnpm dev                            # Terminal 2

Open http://localhost:5173. Supports MOVE, USDCx, and USDC.e — configure via .env files (see examples/rust/.env.example).

Voice Call (React + Rust)

Pay-per-second voice calls using WebRTC + MPP payment channels. Trustless design — vouchers flow peer-to-peer over a WebRTC data channel, the server never touches funds. See examples/voice-call/.

cd examples/voice-call/server && cargo run                    # Terminal 1
cd examples/voice-call/client && pnpm install && pnpm dev     # Terminal 2

On-Chain Contract

Settles on the MovementStreamChannel Move contract deployed on Movement testnet:

Module: 0x74f1060add0c641a0c10bb5bab2bf5fd05f94d7c25055f2419fa82d7bbf2b1e8

Entry functions: open, settle, top_up, close, request_close, withdraw

Supports any Fungible Asset token. Default: MOVE (0xa).

Architecture

src/
├── protocol/          # Core HTTP 402 protocol (headers, types, traits)
│   ├── core/          # Challenge, credential, receipt parsing/formatting
│   ├── intents/       # ChargeRequest, SessionRequest schemas
│   ├── traits/        # ChargeMethod, SessionMethod traits
│   └── methods/
│       └── movement/  # Movement-specific implementation
│           ├── charge.rs         # ChargeRequest extension trait
│           ├── voucher.rs        # ed25519 voucher signing/verification
│           ├── method.rs         # Server-side charge verification
│           ├── session_method.rs # Server-side session/channel lifecycle
│           ├── rest_client.rs    # Movement REST API client
│           ├── network.rs        # Network configuration
│           └── types.rs          # MovementMethodDetails
├── client/
│   └── movement/
│       ├── mod.rs     # MovementProvider (charge payments)
│       └── session.rs # MovementSessionProvider (auto-managed channels)
├── server/
│   ├── mpp.rs         # Mpp handler (challenge generation + verification)
│   ├── axum.rs        # Axum MppCharge extractor
│   ├── sse.rs         # Server-Sent Events metering
│   └── middleware.rs  # Tower middleware
└── store.rs           # Channel state persistence

Protocol

Built on the "Payment" HTTP Authentication Scheme, an open specification proposed to the IETF. See mpp.dev/protocol for the protocol overview.

Contributing

git clone https://github.com/andygolay/mpp-movement
cd mpp-movement
cargo test --features movement,server,client,axum

License

Licensed under either of Apache License, Version 2.0 or MIT License at your option.

About

Rust SDK for the Machine Payments Protocol (MPP) on Movement Network

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors