versa

Crates.ioversa
lib.rsversa
version1.4.0
created_at2024-09-11 18:53:59.887663+00
updated_at2025-09-04 19:15:31.935996+00
descriptionVersa types and utilities for developing Versa client applications in Rust
homepagehttps://versa.org
repositoryhttps://github.com/versa-protocol/versa-rust
max_upload_size
id1372181
size2,316,595
Thomas Constantine Moore (thomasmost)

documentation

https://docs.versa.org

README

Versa Rust

This crate is the official Versa SDK for Rust.

Crates.io Documentation

Versa uses semantic versioning to ensure the stability of its data model. The current schema version is 2.0.0

You can use this crate broadly in two ways: either just referencing the type bindings, or to implement a custom client in Rust.

You will need to enable either the client_sender or client_receiver feature to leverage the corresponding client implementation.

Documentation

Full API documentation is available at docs.rs/versa.

Quick Start

As a Sender

[dependencies]
versa = { version = "1", features = ["client_sender"] }
tokio = { version = "1", features = ["full"] }
use versa::client::VersaClient;
use versa::client_sender::VersaSender;
use versa::protocol::TransactionHandles;
use versa::schema::receipt::Receipt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a sending client
    let client = VersaClient::new("your_client_id".to_string(), "your_secret".to_string())
        .sending_client("2.0.0".to_string());

    // Register the receipt
    let handles = TransactionHandles::new()
        .with_customer_email("customer@example.com".to_string());
        
    let response = client.register_receipt(handles, None).await?;
    let (encryption_key, summary, receivers) = response.ready_for_delivery();

    // Create and send your receipt
    let receipt = Receipt { /* ... */ };
    
    for receiver in receivers {
        client.encrypt_and_send(receiver, summary.clone(), encryption_key.clone(), &receipt).await?;
    }
    
    Ok(())
}

As a Receiver

[dependencies]
versa = { version = "1", features = ["client_receiver"] }

See the documentation for complete examples.

Type Bindings

There are broadly two kinds of types represented in this repository: Protocol Bindings and the Receipt Schema

This repository references the root JSON schema files, at https://github.com/versa-protocol/schema, to generate the Rust bindings for a Versa receipt.

Protocol Bindings

Protocol Bindings represent the types of requests, responses, and error codes to be expected when developing client implementations according to the specifications of the Versa Protocol. These types are defined in the protocol directory.

Receipt Schema

The Receipt struct represents the receipt and invoice data schemas to be handled when developing client implementations according to the specifications of the Versa Protocol. These types are defined in receipt.rs

Build Process

This crate uses the typify crate to construct the receipt schema bindings from our json schema

Features

  • client Enables Versa client initialization with customer registration APIs
  • client_sender Enables the Versa sending client implementation
  • client_receiver Enables the Versa receiving client implementation
  • diesel Implements diesel traits for MySQL on certain structs (UNSTABLE: Use with caution)
  • validator Includes features related to validation of the Versa schema

Schema Validation

The validator feature makes it simple to validate incoming data from the Versa network and to generate a misuse code if necessary. Example usage:

use serde_json::Value;
use versa::protocol::{misuse::MisuseCode, WebhookEventType};

pub async fn validate(event: &WebhookEventType, data: &Value) -> Result<(), (MisuseCode, String)> {
  let validator = versa::schema::validator::Validator::new().allow_remote_lookup(true);
  validator.validate(event, data).await
}

For Developers

Interested in contributing to the official crate? Get started below:

Codegen

To avoid bundling build-dependencies like reqwest into the crate regardless of feature, codegen is a separate script (rather than employing build.rs). Make sure rust-script is installed, then run rust-script ./codegen.rs

Commit count: 0

cargo fmt