API Reference¶
All public symbols exported from routeweiler.__all__.
Client¶
routeweiler.client.Routeweiler ¶
Async HTTP client that transparently handles 402 Payment Required.
Mirrors the httpx.AsyncClient method surface (get/post/put/delete/
patch/head/options/request). Use as an async context manager to ensure
the underlying connection pool is closed cleanly:
async with Routeweiler(funding=[Funding.base_usdc(wallet=signer)]) as c:
resp = await c.get("https://api.vendor.com/data")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
funding
|
list[FundingSource]
|
One or more funding sources (e.g. |
required |
policy
|
Policy | None
|
Optional |
None
|
budget_envelope
|
str | BudgetEnvelope | None
|
Controls which spending envelope the client draws from. Three forms are accepted:
Budget enforcement requires a |
None
|
trace_sink
|
SqliteTraceSink | None
|
SQLite trace sink. Pass |
None
|
agent_id
|
str | None
|
Optional identifier for the calling agent. Written into TraceEvent.agent_id and used as part of the sticky routing key. |
None
|
session_id
|
str | None
|
Optional session identifier. Used as part of the sticky routing key so multiple logical sessions sharing one client get independent sticky state. |
None
|
envelopes
property
¶
Namespace for creating and managing spending envelopes.
Requires trace_sink to be configured; methods raise RuntimeError
when called without one.
get
async
¶
Send a GET request, transparently handling any 402 Payment Required.
post
async
¶
Send a POST request, transparently handling any 402 Payment Required.
put
async
¶
Send a PUT request, transparently handling any 402 Payment Required.
delete
async
¶
Send a DELETE request, transparently handling any 402 Payment Required.
patch
async
¶
Send a PATCH request, transparently handling any 402 Payment Required.
head
async
¶
Send a HEAD request, transparently handling any 402 Payment Required.
options
async
¶
Send an OPTIONS request, transparently handling any 402 Payment Required.
request
async
¶
Send an arbitrary HTTP request, transparently handling any 402 Payment Required.
aclose
async
¶
Close the connection pool, budget store, credential store, and trace sink.
Funding¶
routeweiler.funding.Funding ¶
Namespace of factory helpers for funding sources passed to Routeweiler(funding=[...]).
Each static method returns a concrete funding source. This class is not
meant to be instantiated; use the static methods directly (Funding.base_usdc(...),
Funding.lightning_lnd(...), etc.).
base_usdc
staticmethod
¶
USDC on Base mainnet (chain ID 8453).
base_sepolia_usdc
staticmethod
¶
USDC on Base Sepolia testnet (chain ID 84532).
lightning_lnd
staticmethod
¶
lightning_lnd(
*,
client: LightningNodeClient,
network: Literal[
"bitcoin",
"bitcoin-testnet",
"bitcoin-regtest",
"bitcoin-signet",
],
node_pubkey: str,
max_fee_msat: int = 1000,
) -> LightningFundingSource
Lightning on the specified network.
Use LightningFundingSource.create(client, network) when you want
the node pubkey populated automatically via an async getinfo call.
This synchronous factory requires it to be passed explicitly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
LightningNodeClient
|
A |
required |
network
|
Literal['bitcoin', 'bitcoin-testnet', 'bitcoin-regtest', 'bitcoin-signet']
|
The Bitcoin network the node operates on. |
required |
node_pubkey
|
str
|
Hex-encoded 33-byte compressed pubkey of the node. |
required |
max_fee_msat
|
int
|
Per-payment fee cap (default 1000 msat). |
1000
|
tempo_pathusd_moderato
staticmethod
¶
PathUSD on Tempo Moderato testnet (chain ID 42431).
PathUSD is the primary faucet-funded stablecoin on Moderato.
Use Funding.tempo_usdc() for Tempo mainnet USDC.
stripe
staticmethod
¶
stripe(
*,
api_key: str,
customer: str,
payment_method: str,
currency: str = "usd",
spt_creator: SptCreator | None = None,
) -> StripeFundingSource
Stripe fiat / card funding source for MPP-SPT payments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
Buyer's Stripe secret key ( |
required |
customer
|
str
|
Buyer's Stripe customer id ( |
required |
payment_method
|
str
|
Buyer's saved Stripe payment method id ( |
required |
currency
|
str
|
ISO-4217 lowercase currency this source covers (default |
'usd'
|
spt_creator
|
SptCreator | None
|
Optional injected SPT creator; defaults to
|
None
|
tempo_usdc
staticmethod
¶
USDC on Tempo mainnet (chain ID 42430).
routeweiler.funding.EvmFundingSource
dataclass
¶
An EVM wallet plus the (network, asset) pair it can pay on.
Use the Funding factory methods rather than constructing directly::
from routeweiler import Funding
source = Funding.base_usdc(wallet=signer) # Base mainnet USDC
source = Funding.base_sepolia_usdc(wallet=signer) # Base Sepolia testnet
Attributes:
| Name | Type | Description |
|---|---|---|
wallet |
LocalAccount
|
An |
network |
str
|
x402 network identifier (e.g. |
asset |
str
|
Canonical token name ( |
routeweiler.funding.LightningFundingSource
dataclass
¶
A Lightning node client plus the network it operates on.
client must satisfy the LightningNodeClient protocol. Pass an
LndClient for real usage, or a FakeLndClient in tests.
network must match the BOLT-11 HRP prefix of invoices this source
can pay:
"bitcoin" → lnbc...
"bitcoin-testnet" → lntb...
"bitcoin-regtest" → lnbcrt...
"bitcoin-signet" → lntbs...
node_pubkey is populated at construction time (via get_node_pubkey)
and used in trace events for audit. Pass it explicitly to avoid an
extra async round-trip when constructing in sync context, or use the
create() factory which awaits it automatically.
max_fee_msat is the per-payment fee cap passed to the node. Can be
overridden per-call in LightningFundingSource.pay_invoice().
create
async
classmethod
¶
create(
client: LightningNodeClient,
network: Literal[
"bitcoin",
"bitcoin-testnet",
"bitcoin-regtest",
"bitcoin-signet",
],
*,
max_fee_msat: int = 1000,
) -> LightningFundingSource
Async factory that populates node_pubkey from the client.
pay_invoice
async
¶
Delegate to the underlying client, applying the per-source fee cap.
routeweiler.funding.TempoFundingSource
dataclass
¶
A Tempo signer plus the network and asset it operates on.
signer must satisfy the TempoSigner protocol. Pass an
EthAccountTempoSigner for real usage, or a FakeTempoSigner in tests.
network must match the Tempo network identifier:
"tempo-moderato" → chain ID 42431 (testnet)
"tempo" → chain ID 42430 (mainnet, reserved)
asset is the canonical short name of the TIP-20 token:
"pathusd" → Moderato testnet (faucet-funded)
"usdc" → Tempo mainnet
rpc_url is the JSON-RPC endpoint used to fetch the on-chain nonce before
signing. Leave empty to skip RPC nonce fetching (offline / test mode).
The Funding factory methods set this to the canonical endpoint for each network.
routeweiler.funding.StripeFundingSource
dataclass
¶
A Stripe buyer profile used for MPP-SPT fiat payments.
Use Funding.stripe(...) rather than constructing directly.
spt_creator defaults to a StripeSptCreator built from api_key.
Pass a FakeSptCreator (or any SptCreator-conforming object) to
override in tests without monkey-patching.
Attributes:
| Name | Type | Description |
|---|---|---|
api_key |
str
|
Buyer's Stripe secret key ( |
customer |
str
|
Buyer's Stripe customer id ( |
payment_method |
str
|
Buyer's saved Stripe payment method id ( |
currency |
str
|
ISO-4217 lowercase currency this source covers ( |
spt_creator |
SptCreator
|
Injected SPT creator; defaults to |
Policy¶
routeweiler.policy.dsl.Policy ¶
Bases: RouteweilerModel
Routing policy for a Routeweiler client.
Pass an instance as policy to Routeweiler(...)::
from routeweiler import Policy, PolicyRule, RuleMatch, Routeweiler
policy = Policy(
default_rail="x402",
currency="usd",
rules=[
PolicyRule(
name="cap-per-call",
when=RuleMatch(url_matches="*"),
max_per_call_minor_units=500,
),
],
)
async with Routeweiler(funding=[...], policy=policy) as client:
...
Rules are evaluated first-match-wins, top to bottom.
policy_hash is a stable SHA-256 fingerprint used in trace events.
currency declares the reference currency for max_per_call_minor_units
rules when no budget_envelope is configured on the client. When a
budget_envelope is set, its cap_currency takes precedence. If any
rule declares max_per_call_minor_units and neither currency nor a
budget_envelope is provided, Routeweiler raises ValueError at
construction time.
policy_hash
cached
property
¶
SHA-256 fingerprint of this policy. Format: 'sha256:<64hex>'.
routeweiler.policy.dsl.PolicyRule ¶
Bases: RouteweilerModel
A single entry in a Policy.rules list (first-match wins).
When the when predicate matches a challenge, the rule's action fields
(deny, prefer, max_per_call_minor_units) are applied. Only the
first matching rule takes effect — later rules are not evaluated::
PolicyRule(
name="cap-per-call",
when=RuleMatch(url_matches="*"),
max_per_call_minor_units=500, # 5.00 USD in cents
)
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Human-readable label; appears in trace events and error messages. |
when |
RuleMatch
|
Condition that activates this rule. |
prefer |
list[Rail] | None
|
Rails to prefer (score-boosted) when this rule fires. |
deny |
bool
|
If |
max_per_call_minor_units |
int | None
|
Reject challenges whose amount exceeds this limit (in the reference currency's minor units). |
reason |
str | None
|
Optional human-readable reason included in |
routeweiler.policy.dsl.RuleMatch ¶
Bases: RouteweilerModel
Condition predicate for a PolicyRule.
All non-None fields are combined with AND. Use any for an OR of
sub-conditions::
# Match any x402 request on the "base" network:
RuleMatch(network="base")
# Match requests to *.example.com that use the "exact" scheme:
RuleMatch(url_matches="*.example.com", scheme="exact")
# OR: either of the above:
RuleMatch(any=[RuleMatch(network="base"), RuleMatch(url_matches="*.example.com")])
At least one condition must be set; ValueError is raised otherwise.
routeweiler.policy.engine.PolicyDecision
dataclass
¶
Outcome of evaluating a NormalizedChallenge against a Policy.
Attributes:
| Name | Type | Description |
|---|---|---|
rule_name |
str | None
|
Name of the rule that fired, or |
deny |
bool
|
Whether the challenge should be rejected outright. |
prefer |
tuple[Rail, ...]
|
Rails to score-boost in the routing engine
(empty tuple when the rule did not specify |
max_per_call_minor_units |
int | None
|
Per-call spend cap from the matching rule, or |
reason |
str | None
|
Optional human-readable reason for a denial. |
routeweiler.policy.engine.PolicyEngine ¶
Evaluates a NormalizedChallenge against a Policy (first-match wins).
Constructed automatically by Routeweiler; exposed in __all__ for
callers that build a custom orchestration layer on top of the rail adapters.
default_rail
property
¶
The default_rail from the policy — used as a routing tie-breaker.
evaluate ¶
Evaluate challenge against the policy and return a decision.
Iterates policy.rules in order and returns the PolicyDecision for
the first rule whose when predicate matches. Falls back to a no-op
default decision when no rule matches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge
|
NormalizedChallenge
|
The parsed challenge to evaluate. |
required |
Returns:
| Type | Description |
|---|---|
PolicyDecision
|
A |
PolicyDecision
|
decision with |
Budgets¶
routeweiler.budgets.schema.BudgetEnvelope ¶
Bases: RouteweilerModel
Declarative spec for creating a spending envelope inside Routeweiler.__aenter__.
Pass an instance as budget_envelope to Routeweiler(...) to have the
envelope created idempotently when the client enters its context — no separate
client.envelopes.create(...) call or two-step construction required::
async with Routeweiler(
funding=[Funding.base_usdc(wallet=signer)],
trace_sink=TraceSink.sqlite("rw.db"),
budget_envelope=BudgetEnvelope(
id="session-abc",
cap_minor_units=500,
cap_currency="usd",
allowed_rails=["x402", "l402"],
ttl_seconds=3_600,
),
) as client:
...
If an envelope with the same id already exists in the database the spec is
silently ignored and the existing envelope is used.
routeweiler.budgets.schema.BudgetEnvelopeRecord ¶
Bases: RouteweilerModel
Persisted spending envelope — the DB-row shape returned by BudgetStore.
Caps are in minor units of cap_currency (USD cents, EUR cents, JPY whole yen,
GBP pence). Budget enforcement always runs locally via SQLite at MVP.
routeweiler.budgets.schema.DrawReceipt ¶
Bases: RouteweilerModel
Ed25519-signed token authorizing a single budget draw.
The signature covers all other fields. Issuance and verification logic live in budgets/receipts.py; this model is the wire/storage shape.
routeweiler.budgets.local.BudgetStore ¶
Single-process SQLite budget counter.
Uses BEGIN IMMEDIATE transactions for atomic cap-check + insert. Budget enforcement is always local (no hosted counter at MVP). Initialises the envelopes and draws tables on construction (idempotent).
The reaper task is started by calling await store.start() once
the event loop is running (e.g. from Routeweiler.__aenter__).
get_envelope_currency_sync ¶
Return the cap_currency for an envelope, or None if not found.
Synchronous — safe to call from the Routeweiler constructor and start().
get_envelope_allowed_rails_sync ¶
Return the allowed_rails list for an envelope (empty list if not found).
Synchronous — safe to call from the Routeweiler constructor and start().
load_fmv_snapshot_sync ¶
Return the stored FMV snapshot rates for an envelope, or None if absent.
load_fmv_snapshot
async
¶
Async wrapper for load_fmv_snapshot_sync.
create_envelope
async
¶
create_envelope(
envelope_id: str,
*,
cap_minor_units: int,
cap_currency: EnvelopeCurrency,
allowed_rails: list[Rail],
allowed_origins_glob: list[str] | None = None,
ttl_seconds: int,
owner_agent_id: str | None = None,
) -> None
Insert a new envelope row and create the Ed25519 keypair.
Raises sqlite3.IntegrityError on duplicate id.
create_envelope_if_absent
async
¶
Create an envelope from spec only when no row with that id exists.
Returns True when a new envelope was inserted, False when an
existing row was found (which is left untouched). Delegates to
:meth:create_envelope so keystore creation, FMV snapshot fetch, and
the DB insert all follow the same code path.
draw
async
¶
draw(
*,
envelope_id: str,
request_id: str,
idempotency_key: str,
amount_reserved_minor_units: int,
rail_quoted: Rail,
ttl_seconds: int = _DEFAULT_DRAW_TTL_SECONDS,
) -> DrawReceipt
Atomically reserve capacity from the envelope and return a signed receipt.
BEGIN IMMEDIATE → cap check → idempotency → INSERT → COMMIT. Raises BudgetExceededError, EnvelopeNotFoundError, EnvelopeFrozenError, or EnvelopeExpiredError on rejection.
confirm
async
¶
Transition a reserved draw to settled with the actual settled amount.
rollback
async
¶
Transition a reserved draw to rolled_back, freeing its reserved capacity.
Trace¶
routeweiler.trace.schema.TraceEvent ¶
Bases: RouteweilerModel
One structured audit record per Routeweiler HTTP call.
Emitted by TraceEmitter and persisted by SqliteTraceSink to the
trace_events table. Every call — paid, free, or failed — produces
exactly one TraceEvent.
payment is None when the call did not reach the payment step (e.g.
the request succeeded without a 402, or the budget draw was rejected before
payment was attempted).
routeweiler.trace.sink_sqlite.TraceSink ¶
Factory namespace for trace sink backends.
Use TraceSink.sqlite(path) to enable local tracing::
async with Routeweiler(
funding=[...],
trace_sink=TraceSink.sqlite("./routeweiler.db"),
) as client:
...
Passing trace_sink=None (the default) disables tracing and budget
enforcement entirely.
sqlite
classmethod
¶
sqlite(
path: str | Path = "./routeweiler-traces.db",
*,
url_mode: UrlEncoding = "raw",
) -> SqliteTraceSink
Create a local SQLite-backed sink.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
File path for the SQLite database (created if absent). |
'./routeweiler-traces.db'
|
url_mode
|
UrlEncoding
|
Controls URL storage. |
'raw'
|
routeweiler.trace.sink_sqlite.SqliteTraceSink ¶
Append-only SQLite writer for TraceEvent records.
One sqlite3 connection per sink (WAL mode, check_same_thread=False). All blocking I/O is offloaded to a thread via asyncio.to_thread so the event loop is never blocked.
Rails¶
routeweiler.rails.base.RailAdapter ¶
Bases: Protocol
Protocol every rail adapter implements.
The adapter lifecycle per payment
can_handle— detect a 402 as belonging to this rail.parse— decode the challenge intoNormalizedChallenge.match_funding— confirm a funding source is available.pay— produce aPaymentResult(builds the signed credential and authorization header).confirm— read the server's settlement proof from the response.
The canonical implementation path: override pay and confirm.
Adapters may use private helpers (e.g. _sign) but must not expose them
through this Protocol.
rail
instance-attribute
¶
Rail identity (e.g. "x402") — maps policy prefer lists to adapters.
proof_type
instance-attribute
¶
Proof category produced by this rail ("txid", "preimage", "spt_id").
can_handle ¶
Return True if this adapter recognizes the 402 challenge.
parse ¶
Decode the 402 response into a NormalizedChallenge.
Raises ChallengeParseError on malformed or unsupported payloads.
match_funding ¶
match_funding(
challenge: NormalizedChallenge,
funding: Sequence[FundingSource],
) -> FundingSource | None
Return the first funding source that can satisfy this challenge, or None.
Called by the router after parsing to check funding availability before committing to a payment attempt.
pay
async
¶
Execute the payment and return a PaymentResult.
Raises SigningError (or a rail-specific payment error) on failure.
confirm
async
¶
Read settlement proof from the server's successful reply.
When no settlement header is present (mock/testnet), returns a
SettlementInfo with tx_hash=None and success derived from the
HTTP status code.
routeweiler.rails.base.PaymentResult
dataclass
¶
Output of RailAdapter.pay().
Attributes:
| Name | Type | Description |
|---|---|---|
header_name |
str | None
|
HTTP header to set on the retry request (e.g.
|
header_value |
str | None
|
The header string. |
credential |
dict[str, Any] | None
|
Rail-specific persisted credential (e.g.
|
proof_type |
ProofType
|
Category of payment proof produced by this rail. |
proof_value |
str | None
|
Proof string (preimage hex for L402, SPT id for MPP-SPT,
tx hash for MPP-Tempo). For x402, |
routeweiler.rails.base.SettlementInfo
dataclass
¶
Rail-agnostic payment proof from the server's response headers.
All fields except success are optional because the spec allows a
facilitator to omit them (e.g. in testnet / mock scenarios).
Normalized challenge¶
routeweiler.normalized.NormalizedChallenge ¶
Bases: RouteweilerModel
Rail-agnostic representation of a 402 Payment Required challenge.
Every rail adapter parses its wire format into this shape before the
routing engine and budget counter see it. The rail field acts as a
discriminator: raw is the corresponding *RailRaw subtype
(X402RailRaw, L402RailRaw, MppTempoRailRaw, or MppSptRailRaw).
Errors¶
routeweiler.errors.RouteweilerError ¶
Bases: Exception
Base for all Routeweiler exceptions.
routeweiler.errors.PaymentError ¶
Bases: RouteweilerError
Raised when a 402 payment flow cannot be completed.
routeweiler.errors.BudgetError ¶
Bases: PaymentError
Base for budget envelope failures.
routeweiler.errors.BudgetExceededError ¶
Bases: BudgetError
Drawing this amount would breach the envelope's flat cap.
Attributes:
| Name | Type | Description |
|---|---|---|
envelope_id |
The envelope that rejected the draw. |
|
requested_minor_units |
Amount that was requested. |
|
available_minor_units |
Remaining headroom at the time of the draw. |
routeweiler.errors.EnvelopeNotFoundError ¶
Bases: BudgetError
No envelope row matches the requested id.
routeweiler.errors.EnvelopeFrozenError ¶
Bases: BudgetError
Envelope status is not 'active' (frozen or revoked).
routeweiler.errors.EnvelopeExpiredError ¶
Bases: BudgetError
Envelope expires_at is in the past.
routeweiler.errors.PolicyError ¶
Bases: PaymentError
Base for policy-engine failures.
routeweiler.errors.PolicyDeniedError ¶
Bases: PolicyError
A policy rule with deny: true matched the challenge.
Attributes:
| Name | Type | Description |
|---|---|---|
reason |
Human-readable reason string from the rule's |
|
rule_name |
Name of the matching rule, or |
routeweiler.errors.PolicyMaxPerCallExceededError ¶
Bases: PolicyError
The challenge amount exceeds the policy's max_per_call_minor_units limit.
Attributes:
| Name | Type | Description |
|---|---|---|
rule_name |
Name of the matching rule, or |
|
requested |
Challenge amount in the reference currency's minor units. |
|
limit |
Per-call cap from the matching rule. |
routeweiler.errors.NoFeasibleRailError ¶
Bases: PolicyError
No rail remains after policy, funding, and failover filters are applied.
routeweiler.errors.RailExecutionError ¶
Bases: PaymentError
Base for errors that occur while executing a payment.
routeweiler.errors.SigningError ¶
Bases: RailExecutionError
The rail adapter failed to produce a signed payment payload.
routeweiler.errors.InvoicePaymentError ¶
Bases: RailExecutionError
Lightning node returned a terminal payment failure (no_route, channel offline, etc.).
routeweiler.errors.SptCreationError ¶
Bases: RailExecutionError
Stripe rejected or failed to create the Shared Payment Token.
Raised when the Stripe API call in MppSptAdapter.pay() fails for any
reason: network error, declined card, invalid customer or payment_method,
expired payment method, Stripe API outage, etc.
routeweiler.errors.MppChargeFailedError ¶
Bases: RailExecutionError
MPP server rejected the credential or payment did not settle.
Returned when the server responds 402 with a Problem-Details body
(verification-failed, payment-insufficient, invalid-challenge)
or with a non-2xx status that lacks a Payment-Receipt header.
routeweiler.errors.MppReceiptVerificationError ¶
Bases: RailExecutionError
The Payment-Receipt header is malformed or mismatches our credential.
Raised when the receipt cannot be decoded, fails Pydantic validation, or
the challengeId / method fields do not match what we sent.
routeweiler.errors.PostCommitPaymentError ¶
Bases: RailExecutionError
A pay() exception raised AFTER funds committed on the wire.
Signals to the auth flow that the budget draw must be confirmed (not rolled back) and that failover must not proceed — the rail's payment cannot be re-issued without double-spending.
routeweiler.errors.PreimageMismatchError ¶
Bases: PostCommitPaymentError
sha256(preimage) != invoice payment_hash; the node returned a corrupt preimage.
routeweiler.errors.RailParsingError ¶
Bases: PaymentError
Base for errors that occur while parsing a 402 challenge.
routeweiler.errors.ChallengeParseError ¶
Bases: RailParsingError
The PAYMENT-REQUIRED header could not be decoded or validated.
routeweiler.errors.ChallengeExpiredError ¶
Bases: RailParsingError
Rail challenge expired before the client could pay.
Examples: BOLT-11 invoice expiry, L402 macaroon valid_until caveat,
MPP challenge expires auth-param.
routeweiler.errors.RailNotSupportedError ¶
Bases: PaymentError
No registered adapter can handle the 402 challenge.
routeweiler.errors.NoFundingForRailError ¶
Bases: PaymentError
None of the available funding sources match the server's accepted payment options.
routeweiler.errors.CredentialError ¶
Bases: PaymentError
Base for credential store failures.
routeweiler.errors.CredentialNotFoundError ¶
Bases: CredentialError
No credential row matches the given id.
routeweiler.errors.InvalidCredentialTransitionError ¶
Bases: CredentialError
Attempted state transition is not allowed by the credential state machine.
routeweiler.errors.ManifestParseError ¶
Bases: CredentialError
A service-shape manifest YAML is malformed, fails schema validation, or contains an invalid id_extractor (unknown prefix, bad regex).
routeweiler.errors.KeystoreError ¶
Bases: PaymentError
Base for keystore failures.
routeweiler.errors.KeystoreNotFoundError ¶
Bases: KeystoreError
No key file exists for the given envelope id.
routeweiler.errors.KeystoreAlreadyExistsError ¶
Bases: KeystoreError
A key file already exists for the given envelope id; will not overwrite.
routeweiler.errors.FmvUnavailableError ¶
Bases: PaymentError
No cached FMV rate is available for the required currency pair.
routeweiler.errors.ReceiptVerificationError ¶
Bases: PaymentError
Ed25519 signature on a DrawReceipt is invalid or the payload was tampered with.