Skip to main content

Crate cow_sdk_app_data

Crate cow_sdk_app_data 

Source
Expand description

§cow-sdk-app-data

CoW Protocol app-data document generation, typed validation, CID conversion, and the IPFS read transport seam.

⚠️ Alpha — 0.1.0-alpha. Pre-release and not security-audited; the public API may change before 0.1.0. It is published as a pre-release, so Cargo selects it only when you opt in (cow-sdk-app-data = "0.1.0-alpha.10"). Review it yourself before relying on it with real funds.

appData is the canonical metadata attached to every CoW Protocol order. This crate builds deterministic app-data documents, validates them through typed metadata construction, computes their keccak256 digest, and converts between the 32-byte hex hash and the supported CID encoding (CIDv1 + raw codec + keccak-256 multihash).

Registering a document is an orderbook concern: hash it locally with this crate, then submit the full document through OrderbookApi::upload_app_data, which stores it under its hash. The IPFS read seam is the secondary path, for resolving a document by hash directly from a gateway when it is not available through the orderbook.

§Install

[dependencies]
cow-sdk-app-data = "0.1.0-alpha.10"

§Minimal example

Tag a document with a validated AppCode, validate its modelled metadata, and compute the canonical content and keccak256 digest in a single call. Chain with_* setters for environment, signer, hooks, flashloan hints, or open-ended metadata before the terminal into_validated:

use cow_sdk_core::AppCode;
use cow_sdk_app_data::AppDataParams;

let code = AppCode::new("my-app")?;
let validated = AppDataParams::new(code)
    .with_environment("production")
    .into_validated()?;

// Ready to register through the orderbook:
//   PUT /api/v1/app_data/{hash}
//     hash = validated.info.app_data_hex      (0x-prefixed keccak256 digest)
//     body = validated.info.app_data_content  (canonical JSON)
assert_eq!(validated.info.app_data_hex.len(), 66); // "0x" + 32-byte digest

§CID conversion

Convert between the 32-byte app-data hash and its CID form. The transform is pure and offline — no network — and round-trips losslessly:

use cow_sdk_app_data::{app_data_hex_to_cid, cid_to_app_data_hex};

let hex = "0x0000000000000000000000000000000000000000000000000000000000000000";
let cid = app_data_hex_to_cid(hex)?;
assert_eq!(cid_to_app_data_hex(&cid)?, hex);

§Reading a document from IPFS

The primary way to read a document you registered is the orderbook GET /api/v1/app_data/{hash} request, served from the orderbook database with no gateway involved. The IPFS read seam is the secondary, not-in-database path: it derives the keccak-256 CIDv1 from an app-data hash and reads it through a fetch transport you supply, so the SDK stays decoupled from any specific HTTP stack.

The seam is async, so native and browser runtimes can plug in their own HTTP client; cow-sdk-js implements it over JavaScript’s CowFetchCallback, and browser and non-browser wasm runtimes share the same app-data contract. Because documents are addressed by a keccak-256 CID, the gateway must be able to resolve keccak-CID documents — a generic public gateway cannot.

use cow_sdk_app_data::{AppDataError, IpfsFetchTransport, fetch_doc_from_app_data_hex};

struct IpfsClient;

impl IpfsFetchTransport for IpfsClient {
    async fn get(&self, uri: &str) -> Result<String, AppDataError> {
        // Issue the GET with your HTTP client of choice and return the body.
        let _ = uri;
        Ok(r#"{"version":"1.4.0","metadata":{}}"#.to_owned())
    }
}

let app_data_hex =
    "0x337aa6e6c2a7a0d1eb79a35ebd88b08fc963d5f7a3fc953b7ffb2b7f5898a1df";
let doc = fetch_doc_from_app_data_hex(app_data_hex, client, None).await?;
assert_eq!(doc["version"], "1.4.0");

Pass None to read from the default CoW gateway, or Some(uri) to target a specific keccak-CID-capable gateway. When you already hold a CID rather than a hash, fetch_doc_from_cid takes the same transport.

§Canonical JSON

App-data document canonicalisation routes through serde_jcs::to_string per RFC 8785 (JSON Canonicalization Scheme). The serializer sorts object keys by UTF-16 code unit value and emits a deterministic byte sequence for any equivalent document shape, so the resulting CID is byte-identical to the canonical form the upstream @cowprotocol/cow-sdk TypeScript helper would produce for the same input. Documents whose object keys carry code points whose UTF-16 ordering and UTF-8 byte ordering disagree are pinned by parity/fixtures/app_data/canonical_json_utf16.json; ASCII-only documents are byte-identical to any earlier bytewise canonicalisation.

The cow AppDataHash is a cow-owned #[repr(transparent)] newtype over alloy_primitives::B256 per ADR 0052; the canonical CID conversion is the free function app_data_hex_to_cid, which takes the hash’s to_hex_string form. The digest input fed to alloy_primitives::keccak256 is the canonical-JSON byte stream produced by serde_jcs.

§Feature flags

FeatureDefaultEnables
tracingoffEmits tracing spans and enables cow-sdk-core’s tracing.

§Where this fits

This crate builds and validates app-data and converts hex ↔ CID. It does not perform IPFS networking itself — you supply an IpfsFetchTransport — and it does not sign, submit, or attach app-data to an order. Registering a document is an orderbook concern via OrderbookApi::upload_app_data (cow-sdk-orderbook); the digest and content also feed cow-sdk-trading. Only the CIDv1 + raw + keccak-256 shape is supported; CIDv0 is rejected.

§Where to next

§License

Licensed under GPL-3.0-or-later. See the workspace LICENSE file for the full text. CoW Protocol app-data generation, validation, CID conversion, and the IPFS read transport seam.

§Quick start

Build a minimal SDK-attribution document tagged with a validated AppCode, validate its modelled metadata, and produce a payload ready for PUT /api/v1/app_data/{hash}:

use cow_sdk_core::AppCode;
use cow_sdk_app_data::AppDataParams;

let code = AppCode::new("my-app")?;
let validated = AppDataParams::new(code).into_validated()?;

// validated.info.app_data_content — canonical JSON for PUT /app_data
// validated.info.app_data_hex     — 0x-prefixed keccak256 digest

Chain with_* setters before the terminal call to add environment, signer, hooks, flashloan hints, or open-ended metadata. See AppDataParams for the full setter surface and additional examples.

Re-exports§

pub use cid::app_data_hex_to_cid;
pub use cid::cid_to_app_data_hex;
pub use errors::AppDataError;
pub use fetch::IpfsFetchPolicy;
pub use fetch::IpfsFetchTransport;
pub use fetch::fetch_doc_from_app_data_hex;
pub use fetch::fetch_doc_from_app_data_hex_with_policy;
pub use fetch::fetch_doc_from_cid;
pub use fetch::fetch_doc_from_cid_with_policy;
pub use info::APP_DATA_APPROACHING_LIMIT_RATIO;
pub use info::APP_DATA_MAX_BYTES;
pub use info::AppDataSource;
pub use info::AppDataValidated;
pub use info::AppDataValidation;
pub use info::AppDataWarning;
pub use info::app_data_cid;
pub use info::app_data_content;
pub use info::app_data_info;
pub use info::app_data_info_hex;
pub use info::stringify_deterministic;
pub use metadata::FlashloanHints;
pub use metadata::Hook;
pub use metadata::HookList;
pub use metadata::QuoteMetadata;
pub use schema::extract_schema_version;
pub use schema::generate_app_data_doc;
pub use schema::validate_app_data_doc;
pub use types::AppDataDoc;
pub use types::AppDataInfo;
pub use types::AppDataParams;
pub use types::DEFAULT_APP_CODE;
pub use types::DEFAULT_IPFS_READ_URI;
pub use types::IpfsConfig;
pub use types::LATEST_APP_DATA_VERSION;
pub use types::MetadataMap;
pub use types::PartnerFee;
pub use types::PartnerFeePolicy;
pub use types::SchemaVersion;

Modules§

cid
CID conversion helpers for app-data hashes and documents. CID conversion helpers for app-data documents.
errors
App-data crate error types.
fetch
IPFS fetch policies and read transport seams.
info
Deterministic app-data rendering and digest helpers.
metadata
Typed sub-metadata shapes carried inside the app-data envelope. Typed sub-metadata shapes carried inside the app-data envelope.
schema
Schema generation and validation helpers.
types
Shared app-data types, constants, and configuration structs. Shared app-data types, constants, and configuration structs.