r402-tvm 0.17.1

TON (TVM) chain support for the x402 payment protocol.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(
    test,
    allow(
        unknown_lints,
        clippy::unused_async_trait_impl,
        reason = "in-crate mock impls of AFIT traits have no .await"
    )
)]
#![allow(
    clippy::doc_markdown,
    reason = "TON terms (W5R1, TEP-74, Highload, BoC, jetton) are not intra-doc links"
)]
#![allow(
    unexpected_cfgs,
    reason = "compile_error guard for forbidden tonlib-sys / tonlib-client"
)]

//! TON (TVM) chain support for the x402 payment protocol.
//!
//! This crate implements the x402 `"exact"` scheme for TON: the buyer signs a
//! W5R1 `internal_signed` message that authorizes one TEP-74 `jetton_transfer`,
//! and a facilitator Highload V3 wallet relays it while sponsoring gas.
//!
//! # Features
//!
//! - **CAIP-2 Addressing**: `tvm:-239` and `tvm:-3`
//! - **TEP-74 Payments**: exact jetton transfer of a token (USDT by default)
//! - **W5R1 wallets**: client payloads use opcode `internal_signed` (`0x73696e74`)
//! - **In-process facilitator**: REST verify and Highload V3 batch settle
//!
//! # Feature Flags
//!
//! - `server` — server-side price tag generation
//! - `client` — client-side W5R1 settlement signing
//! - `facilitator` — facilitator-side payment verification and settlement
//! - `telemetry` — `tracing` instrumentation

#[cfg(any(feature = "tonlib-sys", feature = "tonlib-client"))]
compile_error!("r402-tvm must never depend on tonlib-sys or tonlib-client");

#[cfg(not(any(feature = "client", feature = "facilitator")))]
use base64 as _;
#[cfg(not(any(feature = "client", feature = "server", feature = "facilitator", test)))]
use serde_json as _;
#[cfg(feature = "telemetry")]
use tracing_core as _;
#[cfg(test)]
use wiremock as _;

/// Default USDT decimal precision.
pub const DEFAULT_TOKEN_DECIMALS: u8 = 6;

/// Default `maxTimeoutSeconds` and client `validUntil` offset.
pub const DEFAULT_MAX_TIMEOUT_SECONDS: u64 = 300;

/// Default W5R1 subwallet number used when deriving `walletId`.
pub const DEFAULT_W5R1_SUBWALLET_NUMBER: u16 = 0;

/// Highload V3 `subwalletId` used by the facilitator wallet.
pub const DEFAULT_HIGHLOAD_SUBWALLET_ID: u32 = 0x10ad;

/// Highload V3 `timeout` (seconds).
pub const DEFAULT_HIGHLOAD_TIMEOUT: u32 = 3600;

/// Nanotons attached per relayed inner message, before the client's forward TON.
pub const DEFAULT_RELAY_AMOUNT: u128 = 40_000_000;

/// Provisional inner TON attached to the source jetton wallet (before emulation).
pub const DEFAULT_JETTON_WALLET_MESSAGE_AMOUNT: u128 = 30_000_000;

/// Facilitator native TON floor (nanotons).
pub const MIN_FACILITATOR_TON_BALANCE: u128 = 1_040_000_000;

/// Inner-gas pad applied to client-side jetton-wallet fee estimates.
pub const DEFAULT_TVM_INNER_GAS_BUFFER: u128 = 7_100_000;

/// Outer-gas pad applied to facilitator relay amount estimates.
pub const DEFAULT_TVM_OUTER_GAS_BUFFER: u128 = 500_000;

/// Dummy address used only for client-side inner-value emulation.
pub const DEFAULT_TVM_EMULATION_ADDRESS: &str =
    "0:0f8110d76414005a9f0a7deb4d15938b1cd8db22df3f160ed5b48337735abb62";

/// Dummy W5 `walletId` used only for client-side inner-value emulation.
pub const DEFAULT_TVM_EMULATION_WALLET_ID: u32 = 2_147_483_409;

/// Dummy seqno used only for client-side inner-value emulation.
pub const DEFAULT_TVM_EMULATION_SEQNO: u32 = 1;

/// Dummy relay amount used only for client-side inner-value emulation.
pub const DEFAULT_TVM_EMULATION_RELAY_AMOUNT: u128 = 130_000_000;

/// Default Toncenter / TonAPI request timeout.
pub const DEFAULT_TONCENTER_TIMEOUT_SECONDS: u64 = 2;

/// Default emulation request timeout.
pub const DEFAULT_TONCENTER_EMULATION_TIMEOUT_SECONDS: u64 = 10;

/// Trace confirmation wait cap.
pub const DEFAULT_TRACE_CONFIRMATION_TIMEOUT_SECONDS: u64 = 20;

/// Settlement batcher idle flush interval.
pub const DEFAULT_SETTLEMENT_BATCH_FLUSH_INTERVAL_SECONDS: u64 = 1;

/// Settlement batcher size that triggers an immediate flush.
pub const DEFAULT_SETTLEMENT_BATCH_FLUSH_SIZE: usize = 100;

/// Maximum Highload V3 actions in one flush.
pub const DEFAULT_SETTLEMENT_BATCH_MAX_SIZE: usize = 185;

/// Default `validUntil` offset when `maxTimeoutSeconds` is omitted.
pub const DEFAULT_VALID_UNTIL_OFFSET: u64 = 5 * 60;

/// Send mode: pay fees separately.
pub const SEND_MODE_PAY_FEES_SEPARATELY: u8 = 1;

/// Send mode: ignore errors.
pub const SEND_MODE_IGNORE_ERRORS: u8 = 2;

/// TEP-74 `jetton_transfer` opcode.
pub const JETTON_TRANSFER_OP: u32 = 0x0f8a_7ea5;

/// W5R1 `internal_signed` opcode (`"sint"`).
pub const INTERNAL_SIGNED_OP: u32 = 0x7369_6e74;

/// W5R1 `external_signed` opcode (`"sign"`).
pub const EXTERNAL_SIGNED_OP: u32 = 0x7369_676e;

/// W5 `send_msg` out-action opcode.
pub const SEND_MSG_OP: u32 = 0x0ec3_c86d;

/// Canonical W5R1 code hash (hex).
pub const W5R1_CODE_HASH: &str = "20834b7b72b112147e1b2fb457b84e74d1a30f04f737d4f62a668e9552d2b72f";

/// Canonical Highload V3 code hash (hex).
pub const HIGHLOAD_V3_CODE_HASH: &str =
    "11acad7955844090f283bf238bc1449871f783e7cc0979408d3f4859483e8525";

/// BoC hex of the W5R1 wallet code.
pub const W5R1_CODE_HEX: &str = "b5ee9c7241021401000281000114ff00f4a413f4bcf2c80b01020120020d020148030402dcd020d749c120915b8f6320d70b1f2082106578746ebd21821073696e74bdb0925f03e082106578746eba8eb48020d72101d074d721fa4030fa44f828fa443058bd915be0ed44d0810141d721f4058307f40e6fa1319130e18040d721707fdb3ce03120d749810280b99130e070e2100f020120050c020120060902016e07080019adce76a2684020eb90eb85ffc00019af1df6a2684010eb90eb858fc00201480a0b0017b325fb51341c75c875c2c7e00011b262fb513435c280200019be5f0f6a2684080a0eb90fa02c0102f20e011e20d70b1f82107369676ebaf2e08a7f0f01e68ef0eda2edfb218308d722028308d723208020d721d31fd31fd31fed44d0d200d31f20d31fd3ffd70a000af90140ccf9109a28945f0adb31e1f2c087df02b35007b0f2d0845125baf2e0855036baf2e086f823bbf2d0882292f800de01a47fc8ca00cb1f01cf16c9ed542092f80fde70db3cd81003f6eda2edfb02f404216e926c218e4c0221d73930709421c700b38e2d01d72820761e436c20d749c008f2e09320d74ac002f2e09320d71d06c712c2005230b0f2d089d74cd7393001a4e86c128407bbf2e093d74ac000f2e093ed55e2d20001c000915be0ebd72c08142091709601d72c081c12e25210b1e30f20d74a111213009601fa4001fa44f828fa443058baf2e091ed44d0810141d718f405049d7fc8ca0040048307f453f2e08b8e14038307f45bf2e08c22d70a00216e01b3b0f2d090e2c85003cf1612f400c9ed54007230d72c08248e2d21f2e092d200ed44d0d2005113baf2d08f54503091319c01810140d721d70a00f2e08ee2c8ca0058cf16c9ed5493f2c08de20010935bdb31e1d74cd0b4d6c35e";

/// BoC hex of the Highload V3 wallet code.
pub const HIGHLOAD_V3_CODE_HEX: &str = "b5ee9c7241021001000228000114ff00f4a413f4bcf2c80b01020120020d02014803040078d020d74bc00101c060b0915be101d0d3030171b0915be0fa4030f828c705b39130e0d31f018210ae42e5a4ba9d8040d721d74cf82a01ed55fb04e030020120050a02027306070011adce76a2686b85ffc00201200809001aabb6ed44d0810122d721d70b3f0018aa3bed44d08307d721d70b1f0201200b0c001bb9a6eed44d0810162d721d70b15800e5b8bf2eda2edfb21ab09028409b0ed44d0810120d721f404f404d33fd315d1058e1bf82325a15210b99f326df82305aa0015a112b992306dde923033e2923033e25230800df40f6fa19ed021d721d70a00955f037fdb31e09130e259800df40f6fa19cd001d721d70a00937fdb31e0915be270801f6f2d48308d718d121f900ed44d0d3ffd31ff404f404d33fd315d1f82321a15220b98e12336df82324aa00a112b9926d32de58f82301de541675f910f2a106d0d31fd4d307d30cd309d33fd315d15168baf2a2515abaf2a6f8232aa15250bcf2a304f823bbf2a35304800df40f6fa199d024d721d70a00f2649130e20e01fe5309800df40f6fa18e13d05004d718d20001f264c858cf16cf8301cf168e1030c824cf40cf8384095005a1a514cf40e2f800c94039800df41704c8cbff13cb1ff40012f40012cb3f12cb15c9ed54f80f21d0d30001f265d3020171b0925f03e0fa4001d70b01c000f2a5fa4031fa0031f401fa0031fa00318060d721d300010f0020f265d2000193d431d19130e272b1fb00b585bf03";

/// USDT jetton minter on TON mainnet (`tvm:-239`).
pub const USDT_MAINNET_MINTER: &str =
    "0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe";

/// Test USDT jetton minter on TON testnet (`tvm:-3`).
pub const USDT_TESTNET_MINTER: &str =
    "0:f418a04cf196ebc959366844a6cdf53a6fd6fff1eadafc892f05210bba31593e";

/// Toncenter REST root for mainnet.
pub const TONCENTER_MAINNET_BASE_URL: &str = "https://toncenter.com";

/// Toncenter REST root for testnet.
pub const TONCENTER_TESTNET_BASE_URL: &str = "https://testnet.toncenter.com";

/// TonAPI REST root for mainnet.
pub const TONAPI_MAINNET_BASE_URL: &str = "https://tonapi.io";

/// TonAPI REST root for testnet.
pub const TONAPI_TESTNET_BASE_URL: &str = "https://testnet.tonapi.io";

pub mod chain;
pub mod codecs;
pub mod exact;

mod networks;

#[cfg(any(feature = "client", feature = "facilitator"))]
pub mod provider;
#[cfg(any(feature = "client", feature = "facilitator"))]
pub mod trace;

#[cfg(any(feature = "client", feature = "facilitator"))]
pub use chain::TvmRpc;
#[cfg(feature = "facilitator")]
pub use chain::{HighloadV3Config, TvmChainProvider};
pub use exact::TvmExact;
#[cfg(feature = "client")]
pub use exact::client::{TvmExactClient, TvmW5Signer};
pub use networks::*;