Network Working Group D. Borthwick
Internet-Draft InsumerAPI
Intended status: Informational 13 May 2026
Expires: 14 November 2026
Wallet State Attestation: Signed Booleans about On-Chain State
draft-borthwick-wallet-state-attestation-00
Abstract
This document defines Wallet State Attestation: a primitive in which
an issuer reads on-chain state for a wallet address, evaluates one or
more operator-defined conditions, and returns a cryptographically
signed boolean (or structured fact profile) that any verifier can
check offline using a published JWKS endpoint. The primitive enables
condition-based access decisions without identity presentation,
credential exchange, or trust in the issuer at runtime. This
document describes the request and response surface, the signing
algorithm posture, the JWKS discovery pattern, and the security and
privacy considerations of the primitive. It does not define a new
wire protocol; rather, it profiles existing IETF building blocks
(JWT, JWKS, JOSE) for the wallet-state-attestation use case.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 14 November 2026.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
Borthwick Expires 14 November 2026 [Page 1]
Internet-Draft Wallet State Attestation May 2026
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Position Relative to Identity Primitives . . . . . . . . 3
1.3. Position Relative to Credentials . . . . . . . . . . . . 3
1.4. Position Relative to Other Documents . . . . . . . . . . 4
1.5. Use Cases . . . . . . . . . . . . . . . . . . . . . . . . 5
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5
3. Architecture Overview . . . . . . . . . . . . . . . . . . . . 6
4. Request Shape . . . . . . . . . . . . . . . . . . . . . . . . 7
5. Response Shape . . . . . . . . . . . . . . . . . . . . . . . 8
6. Signing Algorithm . . . . . . . . . . . . . . . . . . . . . . 10
7. JWKS Discovery . . . . . . . . . . . . . . . . . . . . . . . 11
8. JWT Format . . . . . . . . . . . . . . . . . . . . . . . . . 11
9. Optional Merkle Proofs . . . . . . . . . . . . . . . . . . . 12
10. Security Considerations . . . . . . . . . . . . . . . . . . . 13
10.1. Single-Issuer Architecture . . . . . . . . . . . . . . . 13
10.2. Freshness Anchors and Replay Considerations . . . . . . 14
10.3. Refuse-on-Observation-Failure . . . . . . . . . . . . . 14
10.4. What This Primitive Does Not Protect Against . . . . . . 15
10.5. Algorithm Agility . . . . . . . . . . . . . . . . . . . 15
11. Privacy Considerations . . . . . . . . . . . . . . . . . . . 15
11.1. Boolean by Default . . . . . . . . . . . . . . . . . . . 15
11.2. Merkle Mode Trade-Off . . . . . . . . . . . . . . . . . 16
11.3. No PII . . . . . . . . . . . . . . . . . . . . . . . . . 16
11.4. Wallet Address Handling . . . . . . . . . . . . . . . . 16
11.5. Awareness of Observation . . . . . . . . . . . . . . . . 16
12. What This Is Not . . . . . . . . . . . . . . . . . . . . . . 16
13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 17
14. References . . . . . . . . . . . . . . . . . . . . . . . . . 17
14.1. Normative References . . . . . . . . . . . . . . . . . . 17
14.2. Informative References . . . . . . . . . . . . . . . . . 18
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 19
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19
Borthwick Expires 14 November 2026 [Page 2]
Internet-Draft Wallet State Attestation May 2026
1. Introduction
1.1. Motivation
Existing access-control primitives --- OAuth 2.0 [RFC6749], OIDC
[OIDC-CORE], SAML, and the broader credential-presentation family ---
answer the question "who is this user?" by accepting a presented
artifact (token, assertion, credential) from a holder.
Wallet State Attestation answers a different question: "does this
wallet currently satisfy a specified condition over on-chain state?"
The holder presents nothing. An issuer reads canonical on-chain
state for a specified wallet address, evaluates the operator-defined
condition, and returns a signed boolean. Verifiers check the
signature offline using a published JWKS endpoint.
This is a distinct primitive from identity verification, credential
issuance, or holder-presentation flows. It belongs in a parallel
category --- what this document terms wallet-state-attestation ---
alongside, not within, the existing credential-presentation stack.
1.2. Position Relative to Identity Primitives
OAuth and OIDC prove who a subject is. Wallet State Attestation
proves what a wallet currently holds, owns, or has been attested to
in on-chain state.
These are complementary, not competing. A system may use OAuth to
authenticate a human or service principal, then call a wallet-state
attestation issuer to verify that a wallet associated with that
principal satisfies an on-chain condition. The two primitives
operate on different subjects (identity vs. wallet state) and answer
different questions.
1.3. Position Relative to Credentials
Wallet State Attestation is *not* a Verifiable Credential (W3C VC)
[VC-DATA-MODEL], an mDoc / ISO/IEC 18013-5 mobile document, an eIDAS
attestation, a SAML assertion, or an OIDC ID token. These are
credential-presentation primitives: an authority issues a credential,
the holder presents it, the verifier checks the issuer's signature
over the holder's presented bytes.
Wallet State Attestation does not involve credential presentation.
The holder does not present anything. The issuer pulls public on-
chain state directly, evaluates a condition, and signs the result.
The signed payload is an observation about external state, not a
credential about the holder's identity.
Borthwick Expires 14 November 2026 [Page 3]
Internet-Draft Wallet State Attestation May 2026
This document treats the credential / VC / eIDAS / SAML stack as
adjacent prior art for explicit non-conflation purposes. See
Section 12 ("What This Is Not") for the full enumeration.
1.4. Position Relative to Other Documents
Wallet State Attestation is referenced or adopted in the following
public artifacts (all informative; see References):
* *Knowledge Context Protocol (KCP) RFC-0004* [KCP-0004] --- defines
an attestation_url / attestation_jwks mechanism in KCP YAML
manifests for verifying agent eligibility before access. The
pattern is mechanism-agnostic; wallet state attestation is one
valid implementation shape.
* *Verifiable Intent (VI) environment.* constraint family*
[VI-ENVIRONMENT] --- defines an environmental constraint family
for autonomous-mode (L3) execution in agent commerce, establishing
family-wide vocabulary (attestation_url, max_attestation_age),
composition rules, and IANA registry mechanics for individual
constraint types. The wallet-state-attestation primitive is the
reference implementation shape used by VI's
environment.wallet_state constraint type.
* *Agent Governance Vocabulary* [AGV] --- defines wallet_state as a
foundation-layer signal type with named production issuers.
* *Open Agent Trust Registry (OATR)* [OATR] --- third-party trust
registry of attestation issuers, including wallet-state-
attestation issuers.
* *Draft ERC-8210 Agent Assurance Protocol* [ERC-8210] --- proposed
IRiskHook verification taxonomy identifies wallet state
attestation as the representative shape for pre-commitment
eligibility verification (one of three categories in the
verification framework, alongside post-hoc resolution evidence and
behavioral reputation).
* *Universal Commerce Protocol (UCP) identity-linking*
[UCP-IDENTITY] --- wallet attestation acknowledged as a reserved
extensibility point for future non-OAuth identity-mechanism types.
Wallet state attestation is *not* dependent on or normatively related
to any of these documents. They are listed as evidence of adoption
and as informative context for readers seeking to understand where
the primitive is in use.
Borthwick Expires 14 November 2026 [Page 4]
Internet-Draft Wallet State Attestation May 2026
1.5. Use Cases
Common deployments of wallet state attestation include:
* *Condition-based access* --- gating API access, content access, or
commerce flows on whether a specified wallet holds a specified
token, NFT, or attested status at request time, without exposing
actual balance or transaction history.
* *Agent-to-agent trust verification* --- autonomous agents
verifying counterparty wallet state (holdings, attested compliance
status, etc.) before transaction execution.
* *Compliance gating* --- verifying on-chain compliance attestations
(KYC status from external attestors, country attestations,
sanctions clearance) against a wallet without handling personally-
identifiable information.
* *Pre-commitment eligibility* --- agent commerce protocols
verifying that an agent wallet satisfies pre-conditions
(sufficient stake, sufficient balance, attested status) before
contract commitment.
The primitive is read-only and does not interact with chain state
beyond observation. Implementations issue attestations on demand;
attestations are short-lived and expire (typically thirty minutes;
see Section 5).
2. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
The following terms are used throughout this document:
*Issuer* --- The party that reads on-chain state, evaluates
conditions, and signs the resulting attestation. The issuer is the
sole signer of attestations within its declared scope (see
Section 10.1).
*Holder* --- The wallet whose on-chain state is observed. The holder
does not present anything in this primitive; the issuer reads chain
state directly. The holder need not be aware of any individual
attestation.
Borthwick Expires 14 November 2026 [Page 5]
Internet-Draft Wallet State Attestation May 2026
*Verifier* --- The party that consumes the attestation, checks the
signature against the issuer's published JWKS, and acts on the
result.
*Condition* --- An operator-defined predicate over wallet state.
Examples include: "balance of token T at address A is greater than or
equal to value V", "wallet A owns NFT N", "wallet A has a valid on-
chain attestation of type T from attestor X".
*Attestation* --- The signed payload returned by the issuer in
response to a request. Distinguish explicitly from a credential
(which is presented by a holder), from a JWT claim in the credential
sense (which carries identity information), and from a VC (which is
issued by an authority over a holder's presented identity). An
attestation in this document's sense is an issuer-signed observation
about public on-chain state.
*Fact profile* --- A multi-condition, multi-dimension attestation
payload consisting of a structured collection of independently-signed
condition results. Used for richer wallet-state queries where a
single boolean is insufficient. Distinguish explicitly from a "trust
score" or "reputation rating" --- a fact profile contains observed
evidence organized by dimension, not an opinion or aggregate.
*Block reference* --- Chain-specific freshness evidence included in
every attestation. EVM chains MUST include block number and block
timestamp. XRPL MUST include ledger index and ledger hash. Solana
MUST include slot. Bitcoin MUST include block height and block hash
(chain-tip evidence; see Section 9 for Bitcoin-specific
considerations).
*Condition hash* --- A SHA-256 hash of the JSON serialization of the
evaluated condition, with top-level keys sorted in lexical order,
represented as a 0x-prefixed lowercase hexadecimal string, included
in the response for tamper-evidence over the condition itself.
3. Architecture Overview
The primitive operates as a three-step pipeline: *read -> evaluate ->
sign*.
1. The issuer receives a request specifying a wallet address, a
chain identifier, and one or more conditions.
2. The issuer reads canonical on-chain state for the specified
wallet at the current chain tip (or, where supported, at a
specified block).
Borthwick Expires 14 November 2026 [Page 6]
Internet-Draft Wallet State Attestation May 2026
3. The issuer evaluates each condition against the observed state.
4. The issuer signs the result and returns the attestation.
The attestation is *deterministic*: the same inputs evaluated against
the same chain state at the same block produce the same output. A
verifier can independently re-derive the attestation by reading the
same chain state and applying the same condition logic.
The primitive is *read-only*: the issuer does not modify chain state,
does not request a wallet signature from the holder, and does not
custody any assets. The issuer is a passive reader of public chain
state.
For each chain referenced in the request, the issuer captures a
chain-tip reference (block number and block timestamp for EVM chains;
ledger index and, where available, ledger hash for XRPL; slot for
Solana; block height and block hash for Bitcoin) at attestation time.
The chain-tip reference is carried inside each per-condition result
and is therefore covered by the issuer's signature. If a required
chain observation cannot be acquired, the issuer MUST NOT sign the
attestation; see Section 10.3.
This document does not specify how the issuer reads chain state (RPC
routing, indexer choice, archive node selection), how it manages
signing keys (HSM, software, federated), or how it handles chain-
specific edge cases (reorgs, finality, data availability). These are
implementation concerns, deliberately left out of scope.
4. Request Shape
A request is a JSON object with the following structure:
{
"wallet": "
",
"chainId": "",
"conditions": [
{
"type": "",
"...": ""
}
],
"options": {
"format": "json",
"proof": "none"
}
}
Borthwick Expires 14 November 2026 [Page 7]
Internet-Draft Wallet State Attestation May 2026
*wallet* --- A chain-specific address string. EVM addresses use the
standard 0x-prefixed hexadecimal form. Solana addresses use base58.
XRPL addresses use the r-address format. Bitcoin addresses MAY use
any standard format (P2PKH, P2SH, bech32 / SegWit, bech32m /
Taproot). Implementations MAY accept the wallet in a chain-specific
field (e.g., solanaWallet, xrplWallet, bitcoinWallet) when the
address format is ambiguous.
*chainId* --- A chain identifier. EVM chains use a numeric chain
identifier consistent with CAIP-2 [CAIP-2], expressible as integer
(e.g., 1 for Ethereum mainnet) or string. Non-EVM chains use a
string identifier (solana, xrpl, bitcoin).
*conditions* --- A list of one or more condition objects. Each has a
type field discriminating the condition category, and type-specific
fields specifying the parameters of that category. This document
does not enumerate all possible condition types. Common categories
include token balance evaluation, NFT ownership evaluation, on-chain
attestation reference (e.g., reference to an Ethereum Attestation
Service entry), and identity-registry membership evaluation.
Implementations MAY define additional condition types.
*options.format* --- Selects the response envelope. Values: "json"
(default; raw JSON object) or "jwt" (RFC 7519 JWT token).
*options.proof* --- Requests an optional cryptographic proof layer.
Values: "none" (default) or "merkle" (where supported by the
underlying chain; returns [EIP-1186] Merkle storage proofs anchored
to the block header).
5. Response Shape
A response contains a signed attestation object together with the
signature and key identifier. The signed attestation object has the
following structure:
Borthwick Expires 14 November 2026 [Page 8]
Internet-Draft Wallet State Attestation May 2026
{
"id": "",
"pass": true,
"results": [
{
"condition": 0,
"label": "",
"type": "",
"chainId": "",
"met": true,
"evaluatedCondition": { /* condition object */ },
"conditionHash": "0x",
"blockNumber": "",
"blockTimestamp": ""
}
],
"attestedAt": ""
}
The signature is computed over a JSON serialization of this object
with field order id, pass, results, attestedAt. The signature, the
key identifier (kid), expiry timestamp (expiresAt), and any
deployment-specific wrappers are transmitted alongside the signed
object but are NOT part of the signed bytes. A typical wire response
carries the signed object plus these adjacent fields:
{
"attestation": {
/* signed object above */
"expiresAt": ""
},
"sig": "",
"kid": ""
}
Field semantics (signed object):
*id* --- An opaque attestation identifier. Implementation-specific
format. Useful for correlation and logging; not used for
verification.
*pass* --- The aggregate result. Default semantics: logical AND of
all per-condition met values. Operators MAY specify alternate
combination logic in extensions.
*results* --- An array of per-condition result objects. Each MUST
include the per-condition met boolean, the condition type, the
verbatim evaluatedCondition (as it was evaluated, after any
Borthwick Expires 14 November 2026 [Page 9]
Internet-Draft Wallet State Attestation May 2026
normalization), and the conditionHash (SHA-256 of the JSON
serialization of evaluatedCondition with top-level keys sorted
lexically). Each result MUST include chain-specific freshness
evidence: blockNumber and blockTimestamp for EVM chains; ledgerIndex
and (where available) ledgerHash for XRPL; slot for Solana;
blockHeight and blockHash for Bitcoin. All such freshness fields are
inside the signed results array and are therefore covered by the
issuer's signature. Implementations MAY include additional
informational fields (condition index, label, etc.) echoed from the
request.
*attestedAt* --- ISO 8601 timestamp of when the attestation was
signed.
Field semantics (adjacent, unsigned):
*expiresAt* --- ISO 8601 timestamp of when the attestation expires.
Verifiers MUST check expiry. Recommended default: thirty minutes
after attestedAt. Implementations MAY use shorter expiries; longer
expiries SHOULD be justified by the use case. expiresAt is
transmitted with the attestation but is not part of the signed
payload; verifiers concerned with tamper-evidence over the expiry
SHOULD use the JWT format (Section 8), where exp is a signed claim.
*kid* --- Key identifier (RFC 7517) for the public key used to sign
this attestation. Verifiers use this to look up the appropriate
public key in the issuer's JWKS. kid is transmitted alongside the
signed payload but is not part of the signed bytes; verifiers
identify the verification key by trying the issuer's published JWKS
entries indexed by the transmitted kid. The JWT format embeds kid in
the protected header where it is covered by the JWT signature.
*sig* --- The signature. Default: ECDSA P-256 signature over the
JSON serialization of the signed object, in base64-encoded P1363 (raw
R || S) format. See Section 6.
The signature scope includes the evaluatedCondition and conditionHash
fields nested inside results, ensuring the signature is tamper-
evident over both the result and the condition that produced it.
6. Signing Algorithm
The default signing algorithm is *ECDSA with P-256 curve and SHA-256
(ES256)* per [RFC7518].
The signed bytes are the JSON serialization of the signed object (id,
pass, results, attestedAt) using deterministic field-order
serialization in that order. Verifiers MUST verify the signature
Borthwick Expires 14 November 2026 [Page 10]
Internet-Draft Wallet State Attestation May 2026
against the exact bytes the issuer produced; verifiers reconstructing
the preimage from a parsed JSON object MUST preserve the original
field order. Issuers and verifiers SHOULD treat the signed bytes as
opaque transport-layer material, not a re-serializable JSON object.
For nested objects whose key order is not externally meaningful
(notably the evaluatedCondition object hashed into conditionHash),
keys are sorted in lexical order before serialization. See [RFC8785]
for a general canonical-JSON scheme; this document does not require
RFC 8785 conformance for the outer signed payload, because the outer
field set is fixed and ordered by this specification.
The signature output is the raw P1363 (R || S) representation of the
ECDSA signature, base64-encoded (88 characters for P-256).
Implementations producing DER-encoded ECDSA signatures MUST convert
to P1363 before transmission.
Implementations MAY support additional algorithms (ES384, EdDSA /
Ed25519). Algorithm selection is encoded in the JWKS entry indexed
by kid. Verifiers MUST consult the JWKS entry to determine the
algorithm before verifying.
7. JWKS Discovery
The issuer publishes its public key set at a discoverable HTTPS
endpoint following [RFC7517]. The recommended path is /.well-known/
jwks.json per [RFC5785].
Each JWKS entry MUST include kid, kty, crv, alg, x, and y fields
appropriate for the curve and algorithm. Issuers MAY publish
multiple active keys simultaneously to support key rotation.
Key rotation: when the issuer rotates signing keys, the new public
key MUST be published in JWKS before the issuer signs any attestation
with the corresponding private key. Retired public keys SHOULD
remain published in JWKS for a duration at least equal to the longest
possible outstanding attestation expiry (typically the default
thirty-minute window).
Verifiers MUST cache the JWKS appropriately (HTTP cache headers as
published by the issuer; the issuer SHOULD set Cache-Control: max-
age=3600 or shorter).
8. JWT Format
When options.format is "jwt", the response is wrapped in an RFC 7519
JWT.
Borthwick Expires 14 November 2026 [Page 11]
Internet-Draft Wallet State Attestation May 2026
Protected header: {"alg": "ES256", "typ": "JWT", "kid": ""}
per [RFC7519]. The kid in the protected header is covered by the JWT
signature.
Standard claims:
* iss --- issuer identifier (e.g., the issuer's base URL)
* sub --- wallet address (the subject of the attestation)
* jti --- JWT identifier (typically the attestation id)
* iat --- issuance timestamp (Unix seconds)
* exp --- expiry timestamp (Unix seconds)
Custom claims carrying the attestation payload:
* pass --- aggregate result
* results --- per-condition result array
* conditionHash --- array of per-condition conditionHash values, in
results order
* blockNumber --- chain block reference (typically the first
result's blockNumber, where chain-homogeneous)
* blockTimestamp --- chain block timestamp (typically the first
result's blockTimestamp)
The JWT signature is computed by the issuer using the corresponding
private key. Verifiers verify using any standard JWT library that
supports ES256 and JWKS discovery.
The JWT format provides signed coverage of exp and kid (via standard
claim and protected header, respectively); deployments requiring
tamper-evident expiry or signed key-identifier binding SHOULD use the
JWT format rather than the JSON format described in Section 5.
9. Optional Merkle Proofs
When options.proof is "merkle" and the underlying chain supports
Merkle storage proofs (typically EVM chains for storage-slot-mappable
conditions), the response MAY include [EIP-1186] Merkle storage
proofs anchored to the block header for each per-condition result.
Borthwick Expires 14 November 2026 [Page 12]
Internet-Draft Wallet State Attestation May 2026
Merkle proofs permit trustless verification: a verifier can
independently check the Merkle proof against the block reference
without trusting the issuer's evaluation. When a Merkle proof is
included (proof.available is true in the per-result proof object),
the proof object MUST include the block reference and the storage
slot path.
Not all conditions or chains support Merkle proofs. Implementations
MUST indicate proof availability per result and MAY return
proof.available: false with a reason field when proof generation is
unsupported for the condition or chain (e.g., NFT ownership
conditions, non-storage-slot-mappable conditions, non-EVM chains).
*Privacy trade-off:* Merkle proofs reveal raw on-chain values (e.g.,
the actual token balance). The default "none" mode preserves privacy
by returning only the boolean result. Operators MUST consider
whether the trustlessness benefit of Merkle proofs is worth the
privacy cost in each deployment.
Bitcoin, XRPL, and Solana have different state-proof models and may
not support Merkle proofs in the [EIP-1186] sense. Implementations
targeting those chains MAY define chain-appropriate proof shapes or
MAY return proof.available: false.
For Bitcoin specifically: the UTXO model does not permit reproducible
balance-at-block queries. Bitcoin implementations anchor the
attestation to the chain tip (block height + block hash) at
observation time as the cryptographically-bound freshness evidence
appropriate to the UTXO model. The blockHeight and blockHash are
covered by the issuer's signature inside the result and bind the
observation to a recent chain tip rather than to a specific block's
historical state. Issuers MUST refuse to sign Bitcoin attestations
when the chain-tip lookup fails; see Section 10.3.
10. Security Considerations
10.1. Single-Issuer Architecture
This document describes a single-issuer attestation primitive. The
issuer is the sole signer of attestations within its declared scope.
This is a deliberate design choice for several reasons:
1. *Deterministic signature surface.* Verifiers can independently
re-derive an attestation from chain state without resolving
issuer trust hierarchies, federation policies, or multi-party
signing logic.
Borthwick Expires 14 November 2026 [Page 13]
Internet-Draft Wallet State Attestation May 2026
2. *No re-signing or wrapping.* Attestations cannot be re-signed by
intermediaries, aggregated under a wrapper signature, or
repackaged in derivative forms. The original observation's
signature is the authoritative artifact end-to-end.
3. *Unambiguous attribution.* For audit, dispute resolution, and
accountability, the issuer is unambiguously identified by the
JWKS endpoint and signing key.
Multi-issuer federation, key delegation, cross-issuer attestation
aggregation, and threshold signing are explicitly out of scope for
this document. Future Internet-Drafts MAY define such mechanisms as
separate primitives, but they are distinct from the single-issuer
wallet-state attestation defined here.
10.2. Freshness Anchors and Replay Considerations
The cryptographically-bound freshness anchors are the block reference
inside each per-condition result and the attestedAt timestamp in the
outer signed payload. Both are covered by the issuer's signature.
Verifiers requiring strict tamper-evident freshness derive their
policy from these signed anchors (e.g., "reject if attestedAt is
older than thirty minutes", or "reject if blockTimestamp is older
than sixty seconds").
The expiresAt field is an issuer-provided TTL hint, transmitted
alongside the attestation but outside the signed payload in the JSON
format described in Section 5. Verifiers MAY honor expiresAt
directly as a convenience. Deployments requiring tamper-evident
expiry SHOULD use the JWT format described in Section 8, where exp is
a signed claim.
For replay-sensitive deployments, implementations MAY include a nonce
binding or audience binding in custom JWT claims (when the JWT format
is used). This document does not normatively specify these
extensions; deployments requiring replay protection beyond freshness
checking SHOULD define them explicitly in their integration profile.
10.3. Refuse-on-Observation-Failure
Issuers MUST refuse to sign an attestation when any required
observation fails: chain-tip lookup, balance query, on-chain
attestation registry lookup, or any other data source the condition
depends on. A successfully signed attestation therefore implies that
all underlying observations were acquired against a current chain
reference at attestation time. Partial or degraded observations MUST
NOT be signed.
Borthwick Expires 14 November 2026 [Page 14]
Internet-Draft Wallet State Attestation May 2026
Verifiers MAY cross-check the included block reference against an
independent chain source if the deployment requires it.
10.4. What This Primitive Does Not Protect Against
* *Chain-level reorganizations after attestation.* If a chain reorgs
after an attestation has been signed, the historical state
observed in the attestation may no longer be canonical. Operators
handling this concern SHOULD use chains with strong finality,
SHOULD use sufficiently old block references, or SHOULD include
reorg-handling logic in their verification flow.
* *Off-chain state changes.* This primitive observes on-chain state
only. It does not attest to off-chain identity, off-chain
agreements, or off-chain commitments.
* *Malicious issuer.* A compromised or malicious issuer could sign
false attestations. This is mitigated by: (a) JWKS publication of
signing keys, (b) optional Merkle proofs for trustless
verification (where supported), (c) condition hashes for tamper-
evidence over the evaluated logic, and (d) deterministic re-
derivation by independent verifiers.
10.5. Algorithm Agility
The default ES256 algorithm is widely supported and provides 128-bit
security. Implementations supporting additional algorithms MUST
include the algorithm in the JWKS entry indexed by kid. Verifiers
MUST check the algorithm before verifying.
Algorithm migration: when the cryptographic landscape changes (e.g.,
post-quantum migration), issuers can rotate to new algorithms via
JWKS without breaking the verification protocol. The protocol
surface remains stable.
11. Privacy Considerations
11.1. Boolean by Default
The default response mode returns only the result of condition
evaluation, never the underlying on-chain value. A verifier learns
whether a wallet satisfies a condition (e.g., "holds at least 100
USDC") but does not learn the actual balance.
This is the privacy-preserving default and SHOULD be used unless
specific deployment requirements justify a less-private mode.
Borthwick Expires 14 November 2026 [Page 15]
Internet-Draft Wallet State Attestation May 2026
11.2. Merkle Mode Trade-Off
When options.proof is "merkle", raw on-chain values are revealed for
trustless verification. Operators MUST consider the privacy
implications of revealing actual balances or asset holdings in each
deployment.
11.3. No PII
The primitive operates on public on-chain state only. No personally-
identifiable information is collected, processed, signed, or
transmitted.
11.4. Wallet Address Handling
The wallet address is the subject of the query but is public
information on the underlying chain. Issuers SHOULD NOT log or
retain wallet addresses beyond what is required for service delivery,
abuse prevention, and operational integrity. Implementations
targeting privacy-conscious deployments SHOULD document their
address-handling policy.
11.5. Awareness of Observation
This primitive observes public chain state without holder
participation. The holder is not required to consent to nor be aware
of any individual attestation, consistent with the public nature of
blockchain state. Deployers operating in regulated or consumer-
facing contexts SHOULD consider whether their deployment context
requires additional transparency mechanisms; such mechanisms are out
of scope for this document.
12. What This Is Not
This section explicitly enumerates adjacent primitives that wallet
state attestation is *not*, to prevent conflation:
* *Not a Verifiable Credential (W3C VC) [VC-DATA-MODEL].* VCs are
issued by an authority, presented by a holder, and verified
against the holder's presented bytes. Wallet state attestations
are pulled by the issuer from public chain state without holder
presentation.
* *Not an mDoc or eIDAS attestation.* mDocs (ISO/IEC 18013-5) are
pre-issued, batched, and stored by the holder for later
presentation. Wallet state attestations are issued on demand, are
short-lived, and are not stored by the holder.
Borthwick Expires 14 November 2026 [Page 16]
Internet-Draft Wallet State Attestation May 2026
* *Not a SAML assertion or OIDC ID token.* These primitives carry
identity claims about a user. Wallet state attestations carry
observations about wallet state, with no identity component.
* *Not a reputation score, trust score, or credit rating.* A wallet
state attestation contains observed facts (boolean results,
optionally with structured fact profiles). It does not contain
opinions, scores, ratings, or aggregated judgments. A separate
primitive built on top of wallet state attestations might produce
a score; this primitive does not.
* *Not a settlement attestation, delivery attestation, or
transaction proof.* Wallet state attestation is read-only state
observation at observation time. It does not attest to action
confirmation, transaction completion, or delivery of goods or
services.
* *Not an oracle in the price-feed sense.* This primitive observes
specific wallet state on demand for a specific request; it does
not publish continuous data streams or aggregate market data.
These distinctions are essential to keeping wallet state attestation
as a distinct primitive in the agent-commerce, condition-based-
access, and verification ecosystems.
13. IANA Considerations
This document has no IANA actions.
14. References
14.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
.
[RFC5785] Nottingham, M. and E. Hammer-Lahav, "Defining Well-Known
Uniform Resource Identifiers (URIs)", RFC 5785,
DOI 10.17487/RFC5785, April 2010,
.
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517,
DOI 10.17487/RFC7517, May 2015,
.
Borthwick Expires 14 November 2026 [Page 17]
Internet-Draft Wallet State Attestation May 2026
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
DOI 10.17487/RFC7518, May 2015,
.
[RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token
(JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,
.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, .
14.2. Informative References
[AGV] "Agent Governance Vocabulary", n.d.,
.
[CAIP-2] "Chain Agnostic Improvement Proposal 2: Blockchain ID
Specification", n.d.,
.
[EIP-1186] "Ethereum Improvement Proposal 1186: RPC-Method to get
Merkle Proofs", n.d.,
.
[ERC-8210] "Draft Ethereum Improvement Proposal 8210: Agent Assurance
Protocol", n.d., .
[KCP-0004] "Knowledge Context Protocol RFC-0004: Trust, Provenance,
and Compliance", n.d., .
[OATR] "Open Agent Trust Registry", n.d.,
.
[OIDC-CORE]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and
C. Mortimore, "OpenID Connect Core 1.0", n.d.,
.
[RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
RFC 6749, DOI 10.17487/RFC6749, October 2012,
.
Borthwick Expires 14 November 2026 [Page 18]
Internet-Draft Wallet State Attestation May 2026
[RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON
Canonicalization Scheme (JCS)", RFC 8785,
DOI 10.17487/RFC8785, June 2020,
.
[UCP-IDENTITY]
"Universal Commerce Protocol: Identity Linking", n.d.,
.
[VC-DATA-MODEL]
Sporny, M., "Verifiable Credentials Data Model", n.d.,
.
[VI-ENVIRONMENT]
Borthwick, D. and M. Msebenzi, "Verifiable Intent ---
environment.* Constraint Family", May 2026,
.
Acknowledgments
The author thanks the IETF community for ongoing discussion of
attestation primitives in the agentic and wallet-state space.
Author's Address
Douglas Borthwick
InsumerAPI
New Canaan, CT
United States of America
Email: douglas@insumermodel.com
Borthwick Expires 14 November 2026 [Page 19]