Files
observer/Cargo.toml
T
grenadeandClaude Opus 5.5 003a13e4ce feat: the NEAR sponsor for blackbeard wallets, off until configured
blackbeard-observer.near will create each blackbeard wallet's NEAR
account and relay its legs as NEP-366 meta-transactions, paying the gas
(blackbeard/wallet#81). This is that sponsor, built and off by default.

- blackbeard-core::sponsor judges a signed delegate action. It is decoded
  and verified by wallet-near, the code the wallet signs with, pinned by
  rev.
  - The sender must be the sponsored account of the delegate's own key.
  - Only the wallet's calls are relayed (intents.near ft_withdraw and
    mt_transfer; wrap.near ft_transfer_call, near_deposit and
    storage_deposit), each with a gas and deposit cap.
  - A pool swap to Ref DCL must pay the fee, at least ceil(amount × bps),
    in its input token to the fee account, in the same action.
  - Seven tests cover forged, misaddressed, over-limit and fee-less
    delegates.
- blackbeard-data::sponsor submits to gargravarr first, the node tracking
  the sponsor's shard, and returns at INCLUDED_FINAL.
- blackbeard-api::sponsor holds the key, one nonce counter, per-address,
  per-sender and daily limits. Routes:
  - GET /v1/near/sponsor: the terms;
  - POST /v1/near/accounts: create the account for a key, or find it;
  - POST /v1/near/relay: relay a signed delegate action.
  Without [near_sponsor] in the config, the terms say enabled: false and
  the POSTs answer 503. A configured key that will not load stops the
  daemon.
- blackbeard-cli near-sponsor-keygen writes a new ML-DSA-65 key, mode 600,
  where it will be used. It never overwrites.

The config template carries the section commented out, with the steps
to turn it on. Registering and funding the account are the operator's.

Refs #51

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NUx7SPonBnB3ofU4mH41WT
2026-10-09 13:39:12 +03:00

83 lines
3.9 KiB
TOML

[workspace]
resolver = "3"
members = ["crates/*"]
[workspace.package]
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
license = "GPL-3.0-or-later"
authors = ["Rob Thijssen <rob@lair.cafe>"]
repository = "https://git.lair.cafe/Quantus-Network/blackbeard.observer"
[workspace.dependencies]
getrandom = "0.3"
bs58 = "0.5"
# The blackbeard wallet's NEAR code (#51): the NEP-649 key, transactions and
# NEP-366 delegate actions. Pinned by rev so the sponsor and the wallet sign
# and read the same bytes; move it with the wallet, never ahead of it.
wallet-near = { git = "https://git.lair.cafe/blackbeard/wallet", rev = "f5c214e4bffa34c5bc3c5283737f92547cd98e1c" }
qp-rusty-crystals-dilithium = { version = "4.1.1", default-features = false, features = ["ml-dsa-65"] }
blackbeard-entities = { path = "crates/blackbeard-entities", version = "=0.1.0" }
blackbeard-core = { path = "crates/blackbeard-core", version = "=0.1.0" }
blackbeard-data = { path = "crates/blackbeard-data", version = "=0.1.0" }
anyhow = "1"
# NEAR view-call arguments travel base64-encoded, and so do a transaction's
# function-call arguments, which `blackbeard-core::near_tx` decodes.
base64 = "0.22"
axum = { version = "0.8", features = ["ws", "macros"] }
chrono = { version = "0.4", default-features = false, features = ["clock", "serde", "std"] }
clap = { version = "4", features = ["derive", "env"] }
figment = { version = "0.10", features = ["toml", "env"] }
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
hex = "0.4"
# The chain's own description of itself, and a decoder driven by it. This is the
# alternative to hand-written SCALE readers that rot on every runtime upgrade,
# and to pulling in subxt or the runtime crate to avoid writing them.
frame-metadata = { version = "23", default-features = false, features = ["current", "decode"] }
parity-scale-codec = { version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false }
scale-value = { version = "0.18", default-features = false }
# Only for `IgnoreVisitor`: the pre-flight walk in `Runtime::decode_checked`
# that keeps a bogus length prefix from sizing an allocation. Pinned to the
# version `scale-value` itself resolves, so both see one type registry.
scale-decode = { version = "0.16", default-features = false }
# Offline reverse geocoding, country level only. The embedded 180x90 dataset is
# 508 KiB and needs no network at all — see `blackbeard_core::geo`.
country-boundaries = "1"
rust_iso3166 = "0.2"
# The chain's own reward-address derivation, so the observer computes the same
# account `pallets/mining-rewards` pays rather than guessing or asking.
qp-poseidon-core = { version = "3.1.0", default-features = false }
# SS58 checksums only. Base58 is hand-rolled; this is not.
blake2 = { version = "0.10", default-features = false }
twox-hash = { version = "2", default-features = false, features = ["xxhash64"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls-native-roots"] }
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { version = "0.8", default-features = false, features = [
"postgres",
"runtime-tokio-rustls",
"macros", "json",
"migrate",
"chrono",
"bigdecimal",
] }
bigdecimal = "0.4"
primitive-types = { version = "0.13", default-features = false }
thiserror = "2"
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "rustls-tls-native-roots"] }
tower-http = { version = "0.6", features = ["cors", "trace", "compression-gzip"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
ts-rs = { version = "10", features = ["serde-compat", "chrono-impl", "no-serde-warnings"] }
url = "2"
[profile.release]
lto = "thin"
codegen-units = 1
strip = "debuginfo"