#[non_exhaustive]pub enum Capability {
ReadBalance,
ProposeTransaction,
SuggestDestination,
ObserveEvent,
SignPayment,
ReadRules,
SignRuleCreate,
}Expand description
A wallet capability that a toolset may declare in its manifest.
#[non_exhaustive] so that future releases can add capability kinds without
a breaking change to downstream consumers that match on the enum.
There is deliberately no SignTransaction variant. Signing is not
grantable as a flat capability — the sign-transaction token in a manifest
is refused with ToolsetFormatError::BareSignTransactionForbidden.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
ReadBalance
Read the account balance of the agent’s configured account.
Maps to the read-balance token.
ProposeTransaction
Propose a transaction for user review (but not sign or submit it).
Maps to the propose-transaction token.
SuggestDestination
Suggest a destination address for a payment.
Maps to the suggest-destination token.
ObserveEvent
Observe a ledger event (streaming / webhook subscription).
Maps to the observe-event token.
SignPayment
Sign and submit a classic payment transaction (signing-adjacent; gated).
Maps to the sign-payment token.
§Inert at declaration
Declaring sign-payment in a toolset manifest confers NOTHING at parse
time or install time — unlike the ungated capabilities above, which
immediately grant their matrix tool at dispatch. This capability is
INERT until the wallet’s first-invoke gate queues an out-of-band user
approval and, after the operator approves, converts it into a runtime
grant stored in the grant store.
The first-invoke gate fires on every invocation where no current, matching grant exists (first call, expired grant, novel destination / asset / amount-bucket).
Even with a current grant, the per-action payment approval fires
unconditionally for every toolset-routed payment. sign-payment NEVER
replaces per-action approval; it is an additive first-invoke consent
layered before it.
ReadRules
Read the agent’s own context rules (spending-limit budgets, expiry, signer/policy counts) via the read-only rules-observability tools.
Maps to the read-rules token. Separately grantable from
read-balance: rule visibility and balance visibility are distinct
concerns, so a toolset must request each independently.
SignRuleCreate
Install an agent-proposed context rule on-chain (signing-adjacent; gated).
Maps to the sign-rule-create token.
§Inert at declaration
Same posture as Capability::SignPayment: declaring sign-rule-create
confers NOTHING at parse or install time. This capability is INERT
until the wallet’s first-invoke gate queues an out-of-band operator
approval and, after the operator approves, converts it into a
runtime grant.
Even with a current grant, the per-proposal RuleProposalSimulated
attestation fires unconditionally for every toolset-routed
stellar_rule_create_commit call. sign-rule-create NEVER replaces
that per-action approval; it is an additive first-invoke consent
layered before it — same relationship sign-payment has to the
per-action PaymentSimulated approval.
Implementations§
Source§impl Capability
impl Capability
Sourcepub fn is_key_touching(self) -> bool
pub fn is_key_touching(self) -> bool
Returns true if this capability involves access to the agent’s signing
key (either for signing or key-derivation purposes).
This predicate is the single source of truth for the install-time attestation gate. The gate calls this function and NEVER matches the capability variant directly, so that a future key-touching capability forces a compile error here until classified.
The explicit match with NO wildcard arm (_ =>) ensures that every
future variant addition requires a conscious classification decision —
a compile error here is intentional, not accidental. Any future
key-touching capability (such as a key-derivation variant) must be
classified as true when added.
§Examples
use stellar_agent_toolsets::Capability;
assert!(Capability::SignPayment.is_key_touching());
assert!(!Capability::ReadBalance.is_key_touching());
assert!(!Capability::ProposeTransaction.is_key_touching());
assert!(!Capability::SuggestDestination.is_key_touching());
assert!(!Capability::ObserveEvent.is_key_touching());