Skip to main content
l402-kit 的所有错误均遵循结构化 JSON 格式,以便代理能够以编程方式解析并采取相应行动。
{
  "error": "ERROR_CODE",
  "code": 402,
  "cause": "Human-readable explanation",
  "action": "recommended_action",
  "retry": false
}

错误代码

PAYMENT_FAILED

{
  "error": "PAYMENT_FAILED",
  "code": 402,
  "cause": "Insufficient balance in wallet",
  "action": "increase_budget",
  "retry": false
}
钱包无法支付发票。请检查余额和 budgetSats 限额。

TOKEN_EXPIRED

{
  "error": "TOKEN_EXPIRED",
  "code": 402,
  "cause": "Macaroon expiry timestamp exceeded",
  "action": "request_new_invoice",
  "retry": true
}
L402 令牌已生成,但在其 TTL(默认:1 小时)到期前未被使用。请重试请求以获取新的发票。

BUDGET_EXCEEDED

{
  "error": "BUDGET_EXCEEDED",
  "code": 402,
  "cause": "Session budget of {n} sats exhausted",
  "action": "stop_or_increase_budget",
  "retry": false
}
代理在当前会话中的花费已超过 budgetSats。请提高预算或结束会话。

INVALID_MACAROON

{
  "error": "INVALID_MACAROON",
  "code": 402,
  "cause": "Macaroon is not valid base64 JSON",
  "action": "request_new_invoice",
  "retry": true
}
macaroon 无法被解码,通常由令牌损坏引起。请从头重试。

TOKEN_ALREADY_USED

{
  "error": "TOKEN_ALREADY_USED",
  "code": 401,
  "cause": "Preimage was already presented — replay attack blocked",
  "action": "do_not_retry",
  "retry": false
}
重放保护已触发。每个 preimage 只能使用一次,请勿重复使用令牌。

NODE_UNREACHABLE

{
  "error": "NODE_UNREACHABLE",
  "code": 503,
  "cause": "Lightning node did not respond within timeout",
  "action": "retry_with_backoff",
  "retry": true
}
Lightning 提供商无法访问。请使用指数退避策略进行重试。

INVOICE_EXPIRED

{
  "error": "INVOICE_EXPIRED",
  "code": 402,
  "cause": "BOLT11 invoice expired before payment was submitted",
  "action": "request_new_invoice",
  "retry": true
}
BOLT11 发票已过期(默认:600 秒)。请重试原始请求以获取新的发票。

WRONG_PREIMAGE

{
  "error": "WRONG_PREIMAGE",
  "code": 402,
  "cause": "SHA256(preimage) does not match paymentHash in macaroon",
  "action": "check_wallet_payment",
  "retry": false
}
加密验证失败。该 preimage 无法证明此发票已完成支付。

在代理中处理错误

import { l402 } from "l402-kit/agent";

try {
  const res = await client.fetch("https://api.example.com/data");
} catch (err: any) {
  if (err.error === "BUDGET_EXCEEDED") {
    // stop and report to user
  } else if (err.retry === true) {
    // safe to retry after short delay
    await sleep(1000);
    const res = await client.fetch("https://api.example.com/data");
  }
}