oid4vp

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 21 Imported by: 0

README

go-oid4vp

OpenID for Verifiable Presentations 1.0 — the verifier (Relying Party) protocol engine in Go: signed Request Objects (JAR/RFC 9101) with WRPAC x5c, request_uri lifecycle, encrypted direct_post.jwt response processing with per-session ephemeral keys, Digital Credentials API (DCAPI) request and response shapes, same-device response_code return, transaction_data, and OID4VP error-response mapping.

  • Storage-free: bring your own SessionStore (in-memory reference included; contract test suite exported in package storetest).
  • HTTP-free: services own transport; this library builds and consumes protocol payloads.
  • All cryptography via github.com/gmb-eudi/go-eudi-crypto (ECCG-pinned policy; algorithms are configured and policy-validated, never chosen by tokens).
  • client_id prefix v1: x509_san_dns only; verifier_attestation is an extension point (constructor rejects it until implemented).
  • Response encryption keys are per-session ephemeral; static operator decryption keys are not supported.

Implemented specs: OpenID4VP 1.0 (final) §5/§6/§8/§12.1, Annex A, Annex B; RFC 9101; HAIP 1.0 (final); ARF 2.9 RPRC_19a; CIR 2024/2982 Art. 3.

Status: pre-v1. API frozen no earlier than OIDF conformance pass.

Documentation

Overview

Package oid4vp implements the verifier (Relying Party) side of OpenID for Verifiable Presentations 1.0: signed Request Objects (RFC 9101 JAR) carrying the operator WRPAC, request_uri lifecycle, encrypted direct_post.jwt response processing with per-session ephemeral keys, Digital Credentials API shapes (Annex A), same-device response_code return ([OID4VP §8.2/§8.3]), and OID4VP error responses.

The package is storage-free (SessionStore interface; in-memory reference implementation; contract suite in storetest) and HTTP-free (services own transport). All cryptography is delegated to github.com/gmb-eudi/go-eudi-crypto; algorithms come from configuration validated against the ECCG policy, never from tokens.

Error mapping guidance for services (the err:domain:reason taxonomy) is on each sentinel in errors.go; wallet-boundary serialization is (*Engine).ErrorResponse — OID4VP error shapes, not problem+json.

Index

Constants

View Source
const (
	// DefaultSessionTTL bounds request_uri fetch + wallet interaction.
	DefaultSessionTTL = 5 * time.Minute
	// DefaultMaxResponseBody caps wallet-posted bodies (oversized
	// body defense).
	DefaultMaxResponseBody = 1 << 20
)
View Source
const ClientIDPrefixX509SANDNS = "x509_san_dns"

ClientIDPrefixX509SANDNS is the only client_id prefix supported in v1 ([OID4VP §5] client identifier prefixes — verifier_attestation is an extension point, rejected by New until implemented).

Variables

View Source
var (
	// Session / store lifecycle.
	ErrSessionInvalid     = errors.New("oid4vp: invalid session")              // programming error; 500 at boundary
	ErrSessionNotFound    = errors.New("oid4vp: session not found or expired") // err:session:not-found
	ErrSessionExpired     = errors.New("oid4vp: session expired")              // err:session:not-found
	ErrSessionConsumed    = errors.New("oid4vp: session already consumed")     // err:session:consumed
	ErrSessionNotConsumed = errors.New("oid4vp: session must be obtained via SessionStore.ConsumeOnce")

	// Engine configuration / request spec.
	ErrConfig                    = errors.New("oid4vp: invalid engine config")
	ErrSANMismatch               = errors.New("oid4vp: client DNS name does not match a SAN dNSName in the WRPAC leaf") // [OID4VP §5] x509_san_dns
	ErrUnsupportedClientIDPrefix = errors.New("oid4vp: unsupported client_id prefix")                                   // x509_san_dns only in v1
	ErrSpec                      = errors.New("oid4vp: invalid request spec")
	ErrNoRegistration            = errors.New("oid4vp: registration reference required in every request (ARF RPRC_19a)")
	ErrFlowMismatch              = errors.New("oid4vp: operation not valid for this session flow")

	// request_uri lifecycle.
	ErrRequestURIConsumed    = errors.New("oid4vp: request object already served (single-use request_uri)") // [OID4VP §5] request_uri
	ErrWalletMetadataInvalid = errors.New("oid4vp: wallet metadata rejected")

	// Response processing. All map to
	// err:presentation:invalid-response unless noted.
	ErrBodyTooLarge        = errors.New("oid4vp: response body exceeds configured cap")
	ErrMalformedResponse   = errors.New("oid4vp: malformed response")
	ErrDecrypt             = errors.New("oid4vp: response decryption failed")               // stale/foreign key, bad JWE
	ErrStateMismatch       = errors.New("oid4vp: state does not match session")             // err:presentation:nonce-mismatch
	ErrAPVMismatch         = errors.New("oid4vp: JWE apv does not match the session nonce") // err:presentation:nonce-mismatch
	ErrUnknownCredentialID = errors.New("oid4vp: vp_token key does not identify a credential query")

	// Same-device return, [OID4VP §8.2/§8.3/§12.1].
	ErrNoResponseCode       = errors.New("oid4vp: no response_code minted for this session")
	ErrResponseCodeMismatch = errors.New("oid4vp: response_code is not bound to this session") // err:presentation:nonce-mismatch
	ErrResponseCodeConsumed = errors.New("oid4vp: response_code already used")                 // err:session:consumed

	// DCAPI, OID4VP Annex A.
	ErrOriginNotExpected = errors.New("oid4vp: response origin not in expected_origins")

	// transaction_data (phase-2 flag).
	ErrTransactionDataDisabled   = errors.New("oid4vp: transaction_data requested but the phase-2 flag is off")
	ErrTransactionDataInvalid    = errors.New("oid4vp: invalid transaction_data entry")
	ErrTransactionDataMissing    = errors.New("oid4vp: transaction_data_hashes missing from presentation")
	ErrTransactionDataUnexpected = errors.New("oid4vp: transaction_data_hashes present but none were requested")
	ErrTransactionDataMismatch   = errors.New("oid4vp: transaction_data_hashes do not match the request")

	// SessionTranscript delegation.
	ErrTranscriptParams = errors.New("oid4vp: presentation lacks the parameters for a SessionTranscript")
)

Sentinel errors. Libraries return typed errors; services map them to err:domain:reason problem codes. The mapping each sentinel is expected to receive is noted inline. None of these messages ever carries attribute values, request bodies, or token contents — never leaked to the wallet.

Functions

func SessionTranscriptFor

func SessionTranscriptFor(p Presentation) (mdoc.SessionTranscript, error)

SessionTranscriptFor builds the ISO 18013-5 SessionTranscript for one verified-to-be mso_mdoc Presentation by delegating to the go-mdoc constructors (OID4VP Annex B.2; ISO/IEC TS 18013-7 Annex B; Annex A for DCAPI):

  • request_uri flows: OID4VPHandover(clientID, nonce, jwkThumbprint, responseURI).
  • DCAPI flows (Origin set): OID4VPDCAPIHandover(origin, nonce, jwkThumbprint) — no client_id or response_uri in this variant.

jwkThumbprint (Presentation.JWKThumbprint) is the RFC 7638 thumbprint of the RP's OWN ephemeral response-encryption public key — computed by ProcessResponse from Session.EphemeralKeyPKCS8, never from anything wallet-supplied. The JWE apu value is NOT an input to either constructor here and is not read anywhere in the pipeline (a correction of an 2026-07-06: an earlier draft assumed apu/mdocGeneratedNonce filled this slot; the go-mdoc constructors' actual, EU-reference-verified shape takes jwkThumbprint instead).

FLAG (carried from go-mdoc's OID4VPHandover/OID4VPDCAPIHandover doc comments): this handover shape is corroborated against a production EU reference verifier, not yet byte-for-byte confirmed against the OpenID4VP 1.0 Annex B.2 primary spec text (not vendored under references/ at the time of writing) — re-verify once that text is available.

eudi-verifier-core passes the result to mdoc.Verifier.Verify as VerifyInput.SessionTranscript. Fail closed: incomplete parameters are an error, never a zero transcript. Pure delegation — no CBOR/SessionTranscript construction of its own.

func TransactionDataHashes

func TransactionDataHashes(td [][]byte, alg string, policy crypto.Policy) ([]string, error)

TransactionDataHashes computes the expected transaction_data_hashes for a set of request entries: base64url( H( base64url(entry) ) ), where H is the digest bound to alg by the ECCG policy ([OID4VP §5] transaction_data; HAIP baseline ES256 ⇒ SHA-256). No hash literal here — the algorithm comes from the policy (no hardcoded algorithm literals).

Types

type Config

type Config struct {
	Keys           crypto.KeyProvider // operator signing key (WRPAC key)
	SigningKeyID   string
	WRPACChain     []*x509.Certificate // leaf first; goes into x5c (CIR 2024/2982 Art. 3)
	ClientDNSName  string              // must match a SAN dNSName of the leaf
	ClientIDPrefix string              // "" = x509_san_dns; anything else is rejected in v1

	Policy crypto.Policy    // nil = crypto.ECCG()
	Clock  func() time.Time // nil = time.Now
	Rand   io.Reader        // nil = crypto/rand.Reader

	RequestURIBase string // e.g. https://verifier.example.com/request — session id is appended (default request_uri builder; ignored when RequestURIFunc is set)
	// RequestURIFunc, when set, fully controls the request_uri embedded in
	// the wallet invocation ([OID4VP §5]: the spec only requires client_id +
	// request_uri + request_uri_method by reference, not any particular URL
	// shape) — the consumer owns its own routing and builds the exact URL
	// its bound route expects. When nil, RequestURIBase+"/"+id is used
	// (backward-compatible default). RequestURIBase may be empty when this
	// is set.
	RequestURIFunc    func(sessionID string) string
	UniversalLinkBase string // wallet universal-link endpoint, e.g. https://wallet.example.org/authorize

	SessionTTL      time.Duration // 0 = DefaultSessionTTL
	MaxResponseBody int           // 0 = DefaultMaxResponseBody

	ResponseEncryption ResponseEncryption
	VPFormats          VPFormats

	EnableTransactionData bool // phase-2 flag
}

Config assembles an Engine. Everything is explicit and validated in New; zero values that have safe defaults are documented per field.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is the OpenID4VP verifier protocol engine. It is stateless between calls: all per-verification state lives in Session.

func New

func New(ctx context.Context, cfg Config) (*Engine, error)

New validates cfg and derives the client identifier from the WRPAC leaf. Fail closed: any unknown algorithm/curve, prefix, or malformed base URL is a construction error (fail closed).

func (*Engine) AbsorbWalletMetadata

func (e *Engine) AbsorbWalletMetadata(s *Session, raw []byte) error

AbsorbWalletMetadata is the wallet-metadata absorption hook ([OID4VP §5] request_uri_method). v1 pins request_uri_method=get, so no metadata arrives on the request_uri fetch yet; services call this when the future post method (or a DCAPI capability hint) delivers one. The document is validated as a JSON object, size-capped, and stored verbatim on the session for policy use — never parsed further here, never logged (treat as untrusted).

func (*Engine) ClientID

func (e *Engine) ClientID() string

ClientID returns the full prefixed client identifier, e.g. "x509_san_dns:verifier.example.com" ([OID4VP §5]).

func (*Engine) ConsumeResponseCode

func (e *Engine) ConsumeResponseCode(s *Session, code ResponseCode) error

ConsumeResponseCode redeems a response_code: constant-time comparison against the code minted FOR THIS SESSION, single-use. This is the [OID4VP §12.1] session-fixation defense — an attacker who fixated their own session id on a victim cannot fetch the victim's result: their code is bound to their session. The caller persists s (SessionStore.Save) so the used-marker sticks.

func (*Engine) DCAPIRequest

func (e *Engine) DCAPIRequest(ctx context.Context, s *Session) ([]byte, error)

DCAPIRequest renders the SIGNED dc_api.jwt request member for navigator.credentials.get (OID4VP Annex A): a JAR-typed JWT with the WRPAC x5c, expected_origins (REQUIRED for signed requests), and no response_uri/state — the browser returns the response and the origin is validated instead.

func (*Engine) DCAPIUnsignedRequest

func (e *Engine) DCAPIUnsignedRequest(s *Session) ([]byte, error)

DCAPIUnsignedRequest renders the UNSIGNED dc_api variant (Annex A): the request parameters as a plain JSON object — no client_id (the calling origin is the identity). The unsigned variant still uses response_mode dc_api.jwt because HAIP makes response encryption mandatory.

func (*Engine) ErrorResponse

func (e *Engine) ErrorResponse(err error) (int, []byte)

ErrorResponse serializes an engine error for the WALLET boundary in the OpenID4VP Error Response format ({"error":..,"error_description":..}), NOT problem+json — the protocol wins on the wallet boundary. status is a plain int so this library imports no HTTP package. Services map the SAME sentinels to err:domain:reason problem codes for their own logging/metrics.

Unknown or internal errors collapse to 500 server_error: fail closed, leak nothing.

func (*Engine) NewSession

func (e *Engine) NewSession(ctx context.Context, spec RequestSpec) (*Session, WalletInvocation, error)

NewSession validates spec, generates the session secrets (id, nonce, state — ≥128-bit from the injected rand; [OID4VP §5, §12.1]) and the per-session ephemeral response-encryption key, and returns the wallet invocation. The caller persists the session (SessionStore.Save).

func (*Engine) ProcessDCAPIResponse

func (e *Engine) ProcessDCAPIResponse(ctx context.Context, s *Session, origin string, data []byte) ([]Presentation, error)

ProcessDCAPIResponse handles the browser-returned dc_api.jwt response (OID4VP Annex A): validate the calling origin against expected_origins, then decrypt and parse like direct_post.jwt — but with no state member (the browser context provides correlation; binding is nonce-based plus origin validation) and the DCAPI handover. Fail closed: an origin absent from expected_origins is rejected with ErrOriginNotExpected before any decryption — the DCAPI analog of the [OID4VP §8.2] state binding. Precondition: s obtained via SessionStore.ConsumeOnce.

func (*Engine) ProcessResponse

func (e *Engine) ProcessResponse(ctx context.Context, s *Session, r RawResponse) ([]Presentation, ResponseCode, error)

ProcessResponse handles the [OID4VP §8.2] direct_post.jwt response for request_uri flows: form parse → JWE decrypt with the per-session ephemeral key → apv handling (Annex B.2) → vp_token object parse ([OID4VP §8.1]) → state binding → response_code mint ([OID4VP §8.2], same-device).

Precondition: s was obtained from SessionStore.ConsumeOnce (atomic one-time consumption; replays die at the store). The caller persists s afterwards (Save) to store the minted response_code.

func (*Engine) RedirectURI

func (e *Engine) RedirectURI(s *Session) (string, error)

RedirectURI renders the [OID4VP §8.3] same-device return: the response endpoint answers the wallet's POST with 200 {"redirect_uri": <this value>}, and the wallet navigates the user's browser there. The response_code in the query fences the result fetch to the browser session that actually completed the presentation ([OID4VP §8.2, §12.1]).

func (*Engine) RequestObjectJWT

func (e *Engine) RequestObjectJWT(ctx context.Context, s *Session) ([]byte, error)

RequestObjectJWT builds and signs the Request Object for GET request_uri (RFC 9101 JAR; [OID4VP §5]; [HAIP §5]). Single-use: the session is marked served and the caller MUST persist it (SessionStore.Save); a second call fails with ErrRequestURIConsumed.

func (*Engine) ValidateTransactionDataEcho

func (e *Engine) ValidateTransactionDataEcho(s *Session, echoedHashes []string, hashAlgName string) error

ValidateTransactionDataEcho compares the transaction_data_hashes echoed by the wallet (in a KB-JWT for dc+sd-jwt, or the device-signed payload for mso_mdoc — extracted by go-sdjwt/go-mdoc) against the hashes of the session's request entries ([OID4VP §5]). Set semantics: the wallet may reorder. present/absent/mismatch matrix:

  • flag off but session carries entries → ErrTransactionDataDisabled
  • entries requested, none echoed → ErrTransactionDataMissing
  • none requested, some echoed → ErrTransactionDataUnexpected
  • counts differ or any hash unmatched → ErrTransactionDataMismatch

type Flow

type Flow string

Flow selects the presentation flow of a session.

const (
	SameDevice  Flow = "same-device"  // [OID4VP §8.2/§8.3]: redirect_uri + response_code return
	CrossDevice Flow = "cross-device" // QR / polling; response endpoint returns no redirect
	DCAPI       Flow = "dcapi"        // OID4VP Annex A: browser Digital Credentials API
)

Flow values.

type MemStore

type MemStore struct {
	// contains filtered or unexported fields
}

MemStore is the in-memory reference SessionStore: single-process, for tests and development. Sessions are stored as JSON snapshots, which (a) gives Load copy semantics identical to a networked store and (b) proves every Session is serializable exactly as a persistent (Valkey) store needs.

func NewMemStore

func NewMemStore(clock func() time.Time) *MemStore

NewMemStore returns an empty MemStore. clock nil defaults to time.Now.

func (*MemStore) ConsumeOnce

func (m *MemStore) ConsumeOnce(_ context.Context, id string) (*Session, error)

ConsumeOnce atomically hands the session to exactly one caller ([OID4VP §8.2] one-time response consumption; [OID4VP §12.1] replay defense). The Consumed marker is sticky: it survives later Save calls, so a replayed wallet POST fails even after the service persisted post-processing state.

func (*MemStore) Load

func (m *MemStore) Load(_ context.Context, id string) (*Session, error)

Load returns an independent copy of the stored session. Expired sessions are evicted and reported as not found (store contract; the Engine also checks ExpiresAt itself — fail closed).

func (*MemStore) Save

func (m *MemStore) Save(_ context.Context, s *Session) error

Save stores a JSON snapshot of s.

type Presentation

type Presentation struct {
	QueryCredID string // DCQL credential query id (vp_token key, [OID4VP §8.1])
	Format      string // dcql.FormatSDJWT | dcql.FormatMdoc (from the session's query)
	Payload     []byte // dc+sd-jwt: presentation string verbatim; mso_mdoc: base64url-decoded DeviceResponse

	Nonce, ClientID, ResponseURI string
	Origin                       string // DCAPI only (Annex A)

	// JWKThumbprint is the RFC 7638 thumbprint of the RP's OWN ephemeral
	// response-encryption public key (the same key advertised in
	// client_metadata) — computed by ProcessResponse from
	// Session.EphemeralKeyPKCS8 via crypto.JWKThumbprint, never from
	// anything wallet-supplied. The JWE apu header is not read at all:
	// JWKThumbprint is
	// the mdoc SessionTranscript handover's sole key-binding input, set
	// only for mso_mdoc presentations.
	JWKThumbprint string
}

Presentation is one entry of the vp_token object ([OID4VP §8.1]), paired with the binding parameters downstream verification needs: nonce and client_id for KB-JWT (go-sdjwt), and the OID4VPHandover / OID4VPDCAPIHandover inputs for mdoc (go-mdoc, Annex B.2 / Annex A).

type RawResponse

type RawResponse struct {
	Body []byte
}

RawResponse is the wallet's POST body to the response endpoint ([OID4VP §8.2] direct_post.jwt: application/x-www-form-urlencoded with response=<JWE>). The service passes it verbatim, size-unchecked — the engine owns the cap.

type RequestSpec

type RequestSpec struct {
	Query           dcql.Query
	Flow            Flow // SameDevice | CrossDevice | DCAPI
	ResponseURI     string
	ReturnURI       string                 // same-device only ([OID4VP §8.3])
	Registration    rpcert.RegistrationRef // always (ARF RPRC_19a)
	WRPRC           []byte                 // optional
	TransactionData [][]byte               // phase 2
	ExpectedOrigins []string               // DCAPI signed requests (Annex A)
}

RequestSpec describes one verification request (the target interface). ReturnURI is the same-device [OID4VP §8.3] redirect target for the same-device flow.

type ResponseCode

type ResponseCode string

ResponseCode is the single-use [OID4VP §8.2] response_code minted for same-device sessions and redeemed via ConsumeResponseCode ([OID4VP §8.3/§12.1]).

type ResponseEncryption

type ResponseEncryption struct {
	Curve     string   // ephemeral key curve, e.g. the HAIP baseline P-256
	Alg       string   // JWE key agreement advertised on the ephemeral JWK
	EncValues []string // encrypted_response_enc_values_supported ([OID4VP §8.2])
}

ResponseEncryption configures the per-session ephemeral response encryption advertised in client_metadata ([OID4VP §8.2] direct_post.jwt; [HAIP §5]: encryption mandatory). Values are supplied by the service's configuration and validated against crypto.Policy — this library hardcodes no algorithm strings.

type Session

type Session struct {
	ID       string `json:"id"`
	Flow     Flow   `json:"flow"`
	ClientID string `json:"client_id"` // full prefixed form, e.g. "x509_san_dns:verifier.example.com"

	Nonce string `json:"nonce"` // [OID4VP §5]: ≥128-bit, crypto/rand, base64url
	State string `json:"state"` // response binding ([OID4VP §8.2])

	ResponseURI string `json:"response_uri"`         // [OID4VP §8.2] direct_post.jwt endpoint
	ReturnURI   string `json:"return_uri,omitempty"` // same-device [OID4VP §8.3] redirect target (see README corrections)

	Query           dcql.Query             `json:"query"`                      // [OID4VP §6]
	Registration    rpcert.RegistrationRef `json:"registration"`               // ARF RPRC_19a — always present
	WRPRC           []byte                 `json:"wrprc,omitempty"`            // optional registration certificate
	TransactionData [][]byte               `json:"transaction_data,omitempty"` // phase 2
	ExpectedOrigins []string               `json:"expected_origins,omitempty"` // DCAPI (Annex A)

	EphemeralKeyPKCS8 []byte `json:"ephemeral_key_pkcs8"` // per-session response-encryption private key, PKCS#8 DER

	CreatedAt time.Time `json:"created_at"`
	ExpiresAt time.Time `json:"expires_at"`

	RequestObjectServed bool   `json:"request_object_served"`     // single-use request_uri
	WalletMetadata      []byte `json:"wallet_metadata,omitempty"` // absorbed hook payload
	Consumed            bool   `json:"consumed"`                  // sticky one-time marker (ConsumeOnce)
	ResponseCode        string `json:"response_code,omitempty"`   // minted [OID4VP §8.2], redeemed [OID4VP §8.3]
	ResponseCodeUsed    bool   `json:"response_code_used,omitempty"`
}

Session is the per-verification protocol state. It is a plain JSON-serializable record so SessionStore implementations (a Valkey-backed store) can persist it verbatim. Fields are exported for storage, not for mutation: services treat a Session as opaque between Engine calls.

The response-encryption key is per-session ephemeral (HAIP-aligned): it lives only inside the session record and dies with it.

type SessionStore

type SessionStore interface {
	Save(ctx context.Context, s *Session) error
	Load(ctx context.Context, id string) (*Session, error)
	ConsumeOnce(ctx context.Context, id string) (*Session, error) // atomic: response endpoint
}

SessionStore persists sessions. The Valkey implementation lives in services; it MUST pass storetest.Run unchanged.

Contract (verified by storetest.Run):

  • Save then Load returns an equal, independent copy (mutating a loaded session does not affect the stored one).
  • Load/ConsumeOnce of an unknown OR expired id returns ErrSessionNotFound (expiry may be storage eviction, e.g. Valkey TTL; the Engine additionally enforces ExpiresAt itself, fail closed).
  • ConsumeOnce is atomic: for one id, exactly one caller ever receives the session (returned with Consumed=true); every other and every later call gets ErrSessionConsumed — even after subsequent Save calls of the same session (the consumed marker is sticky). This is the [OID4VP §12.1] replay defense for the response endpoint ([OID4VP §8.2]).

type VPFormats

type VPFormats struct {
	SDJWTAlgValues          []string // dc+sd-jwt sd-jwt_alg_values
	KBJWTAlgValues          []string // dc+sd-jwt kb-jwt_alg_values
	MdocIssuerAuthAlgValues []int64  // mso_mdoc issuerauth_alg_values (COSE labels)
	MdocDeviceAuthAlgValues []int64  // mso_mdoc deviceauth_alg_values (COSE labels)
}

VPFormats configures client_metadata vp_formats_supported ([OID4VP §5]; Annex B.2/B.3). Same rule: values from config, validated by policy.

type WalletError

type WalletError struct {
	Code        string
	Description string
}

WalletError is an OID4VP error response sent BY the wallet (e.g. the user declined: error=access_denied). It is not an engine failure; the service records the outcome and acknowledges the wallet. Code and Description are wallet-supplied, length-capped, and must be treated as untrusted text (never logged raw next to attribute data).

func (*WalletError) Error

func (e *WalletError) Error() string

type WalletInvocation

type WalletInvocation struct {
	SchemeURI     string // openid4vp://?client_id=...&request_uri=...&request_uri_method=get
	UniversalLink string // UniversalLinkBase + same query
	QRPayload     string // string to encode into the cross-device QR
	DCAPI         []byte // Annex A request member JSON (populated for Flow == DCAPI)
}

WalletInvocation carries the flow-specific way to put the request in front of a wallet: custom-scheme URI, https universal link and QR payload for request_uri flows, or the DCAPI request member.

Directories

Path Synopsis
Package storetest exports the SessionStore contract suite.
Package storetest exports the SessionStore contract suite.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL