快速开始¶
本指南带你签发第一个 LedgerFlow 授权令, 用授权验证 x402 支付。
注意: CLI 提供 fixture 生成与演示(
sample-warrant/sample-payment), 完整的授权令签发与验证以编程方式调用ledgerflow-core。
前置条件¶
第 1 步:克隆并测试¶
Bash
git clone https://github.com/longcipher/ledgerflow.git
cd ledgerflow
# 运行工作区测试(TDD + proptest,无 BDD)
just test
# 运行变异测试验证测试质量
just mutate
第 2 步:生成 fixture¶
CLI 提供确定性的演示 fixture:
Bash
# 生成示例授权令 fixture
cargo run -p ledgerflow-cli -- sample-warrant
# 生成带 LedgerFlow 授权数据的示例 x402 支付负载
cargo run -p ledgerflow-cli -- sample-payment
# 生成 m-of-n 审批签名(演示用)
cargo run -p ledgerflow-cli -- approve sha256:<request-hash>
# 显示信任锚配置提示
cargo run -p ledgerflow-cli -- trust-anchors
第 3 步:编程签发授权令¶
用 WarrantBuilder(typestate)创建根授权令:
Rust
use ledgerflow_core::{
AssetRef, MerchantConstraint, PaymentConstraint, PaymentRail,
ResourceConstraint, SigningKeyPair, WarrantBuilder,
};
// 签发者(人类/控制面)与持有者(代理)密钥
let issuer = SigningKeyPair::from_bytes(&[1_u8; 32]);
let agent = SigningKeyPair::from_bytes(&[2_u8; 32]);
let warrant = WarrantBuilder::new(now_ms)
.ttl_secs(3600)
.max_depth(4)
.issuer(issuer.signer_ref())
.holder(agent.signer_ref())
.merchant(MerchantConstraint::with_ids(vec!["merchant-a".to_string()]))
.resource(ResourceConstraint {
http_methods: vec!["POST".to_string()],
path_prefixes: vec!["/pay".to_string()],
})
.payment(
PaymentConstraint::new(10_000_000) // 10 USDC base units
.with_asset(AssetRef::new("USDC", Some("base".to_string())))
.with_rails(vec![PaymentRail::Onchain])
.with_schemes(vec!["exact".to_string()])
.with_payees(vec!["merchant-a".to_string()]),
)
.sign_with(&issuer, [0_u8; 8]);
委托(签发期衰减)¶
子授权令继承父约束并可**窄化**(签发期静态检查):
Rust
use ledgerflow_core::typestate::DelegatedWarrantBuilder;
let child = DelegatedWarrantBuilder::from(warrant)
.with_payment(PaymentConstraint::new(5_000_000)) // 缩小到 5 USDC
.issue_to(sub_agent.signer_ref(), &agent, now_ms, [0_u8; 8]);
第 4 步:构建 x402 支付¶
代理收到 x402 402 Payment Required 时,
用 ledgerflow-protocol 构建带 LedgerFlow 授权扩展的支付负载:
Rust
use ledgerflow_core::WarrantChain;
use ledgerflow_protocol::{
AcceptedQuote, HttpRequest, PaymentPayloadSeed,
build_payment_payload, merchant_payment_required,
};
// 商户广告 402 challenge(含 LedgerFlow 扩展)
let challenge = merchant_payment_required(
"challenge-1", "merchant-a", "/pay",
vec![AcceptedQuote::exact("USDC", 200, "merchant-a", Some("base".to_string()))],
60_000,
).ledgerflow.unwrap();
// 代理构建支付负载(warrant chain + PoP + approvals)
let payload = build_payment_payload(
&challenge,
&HttpRequest::new("POST", "merchant-a.example", "/pay", body),
AcceptedQuote::exact("USDC", 200, "merchant-a", Some("base".to_string())),
WarrantChain::single(warrant),
PaymentPayloadSeed {
payment_subject,
signer: agent,
created_at_ms: now_ms,
nonce: "nonce-1".to_string(),
payment_identifier: Some("payment-1".to_string()),
tool_args: Default::default(),
approvals: Vec::new(),
},
)?;
第 5 步:验证(商户端)¶
商户用 MerchantVerifier 验证支付负载:
Rust
use ledgerflow_core::{InMemoryRevocationCheck, TrustedIssuers};
use ledgerflow_protocol::{
MerchantVerifier, InMemoryWarrantRepository,
replay::InMemoryReplayStore,
};
let mut verifier = MerchantVerifier::new(
InMemoryReplayStore::default(),
InMemoryWarrantRepository::default(),
InMemoryRevocationCheck::new(),
);
let outcome = verifier.verify_payment(
&challenge, &request, &payload,
&trusted_issuers, // TrustedIssuers:根签发者必须命中
"web-search", // tool name(审批门用)
&tool_arguments,
now_ms,
)?;
// outcome.authorization 验证通过 → 继续 x402 结算
验证检查:
- 授权令链签名有效性(每个节点)+ 信任锚(根签发者)
- 委托链不变量 I1-I7(循环检测、TTL 单调、parent_hash 链)
- PoP 签名 + 新鲜度(60s)+ 时钟偏移
- 运行时合取约束(merchant/resource/tool/payment)
- 审批门(m-of-n 多签,如触发)
- 撤销预检(RevocationStore)
- 重放保护(challenge_id + nonce)
结算¶
验证通过后,Facilitator 的 /settle 做**原子重验**(撤销 + TTL + PoP + 金额)
再提交结算——闭合 TOCTOU 窗口:
