@gramota/holder
Headless wallet — credential store + import/present/refill operations.
Install: pnpm add @gramota/holder
Source: github.com/gramota-org/gramota/tree/main/packages/holder
Classes
Holder
Defined in: @gramota/holder/dist/holder.d.ts:116
Constructors
Constructor
new Holder(config: HolderConfig): Holder;
Defined in: @gramota/holder/dist/holder.d.ts:129
Parameters
config
Returns
Properties
credentials
readonly credentials: CredentialsApi;
Defined in: @gramota/holder/dist/holder.d.ts:126
Credential CRUD. holder.credentials.{receive, list, get, remove}(...).
offers
readonly offers: OffersApi;
Defined in: @gramota/holder/dist/holder.d.ts:128
OID4VCI offers. holder.offers.{parse, accept, authorize, claim}(...).
Accessors
publicKey
Get Signature
get publicKey(): JsonWebKey;
Defined in: @gramota/holder/dist/holder.d.ts:133
Public key — useful to share with issuers so they can bind credentials.
Returns
JsonWebKey
Methods
present()
present(options: PresentOptions): Promise<string>;
Defined in: @gramota/holder/dist/holder.d.ts:131
Build a selective-disclosure presentation against a stored credential.
Parameters
options
Returns
Promise<string>
respond()
respond(requestUrl: string, options?: RespondOptions): Promise<RespondResult>;
Defined in: @gramota/holder/dist/holder.d.ts:145
Respond to an OID4VP Authorization Request URL.
The holder:
- Parses the URL.
- Runs DIF Presentation Exchange against stored credentials.
- Builds the presentation with selective disclosure.
- Builds the OID4VP authorization response form body.
Returns the body string ready to POST to response_uri, plus metadata.
Parameters
requestUrl
string
options?
Returns
Promise<RespondResult>
InMemoryCredentialStore
Defined in: @gramota/holder/dist/store/memory.d.ts:4
Default in-process credential store. Loses data on process exit; use a persistent implementation for production.
Implements
Constructors
Constructor
new InMemoryCredentialStore(): InMemoryCredentialStore;
Returns
Methods
add()
add(credential: StoredCredential): Promise<void>;
Defined in: @gramota/holder/dist/store/memory.d.ts:6
Parameters
credential
Returns
Promise<void>
Implementation of
get()
get(id: string): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/store/memory.d.ts:7
Parameters
id
string
Returns
Promise<StoredCredential>
Implementation of
list()
list(query?: CredentialQuery): Promise<readonly StoredCredential[]>;
Defined in: @gramota/holder/dist/store/memory.d.ts:8
Parameters
query?
Returns
Promise<readonly StoredCredential[]>
Implementation of
remove()
remove(id: string): Promise<boolean>;
Defined in: @gramota/holder/dist/store/memory.d.ts:9
Parameters
id
string
Returns
Promise<boolean>
Implementation of
HolderError
Defined in: @gramota/holder/dist/types.d.ts:87
Extends
GramotaError
Constructors
Constructor
new HolderError(
code: HolderErrorCode,
message: string,
options?: {
cause?: unknown;
}): HolderError;
Defined in: @gramota/holder/dist/types.d.ts:89
Parameters
code
message
string
options?
cause?
unknown
Returns
Overrides
GramotaError.constructor
Properties
cause?
readonly optional cause?: unknown;
Defined in: .pnpm/@gramota+core@0.2.1/node_modules/@gramota/core/dist/error.d.ts:44
Optional original error that caused this one. Always set when the
Gramota package is wrapping a thrown exception from a dependency
(Web Crypto, JOSE, fetch). Survives JSON.stringify(err) only via
the cause property — Node 16.9+ logs it natively.
Inherited from
GramotaError.cause
code
readonly code: HolderErrorCode;
Defined in: @gramota/holder/dist/types.d.ts:88
Stable string that identifies the failure mode. Subclasses narrow the type; at runtime it's always a string. Use for branching, logs, and metrics labels — never serialize GramotaError.message for that purpose, message strings drift across versions.
Overrides
GramotaError.code
name
name: string;
Defined in: .pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1076
Inherited from
GramotaError.name
message
message: string;
Defined in: .pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1077
Inherited from
GramotaError.message
stack?
optional stack?: string;
Defined in: .pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1078
Inherited from
GramotaError.stack
Interfaces
OffersApi
Defined in: @gramota/holder/dist/holder.d.ts:6
Stripe-style sub-API for OID4VCI credential offers. holder.offers.X(...).
Methods
parse()
parse(url: string): CredentialOffer;
Defined in: @gramota/holder/dist/holder.d.ts:9
Parse a credential offer URL with no network I/O — preview an offer before deciding to accept it.
Parameters
url
string
Returns
CredentialOffer
accept()
accept(url: string, options: AcceptOptions): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/holder.d.ts:15
Accept a credential offer end-to-end via the pre-authorized code flow:
parse → fetch metadata → token → proof JWT → credential request →
validate → store. Returns the StoredCredential, same shape as
holder.credentials.receive. Throws if the offer doesn't include a
pre-authorized_code grant — use authorize + claim for auth-code.
Parameters
url
string
options
Returns
Promise<StoredCredential>
authorize()
authorize(url: string, options: AuthorizeOptions): Promise<AuthorizeResult>;
Defined in: @gramota/holder/dist/holder.d.ts:23
Step 1 of the OID4VCI auth-code flow. Returns the URL the wallet must
navigate the user to, plus PKCE+state secrets to keep until step 2.
The Holder caches flow context (metadata, offer, redirect_uri,
client_id) keyed by state, so step 2 only needs the callback +
verifier + state.
Parameters
url
string
options
Returns
Promise<AuthorizeResult>
claim()
claim(options: ClaimOptions): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/holder.d.ts:27
Step 2: exchange the issuer's redirect-callback for a credential,
validate it against trustedIssuers, and store it. Looks up the
pending flow by state (same value passed to/from authorize).
Parameters
options
Returns
Promise<StoredCredential>
AcceptOptions
Defined in: @gramota/holder/dist/holder.d.ts:31
Options for holder.offers.accept(). Extends OID4VCI's accept options
with trustedIssuers (same semantics as credentials.receive).
Extends
AcceptOfferOptions
Properties
trustedIssuers
trustedIssuers: readonly JsonWebKey[];
Defined in: @gramota/holder/dist/holder.d.ts:34
Trusted issuer JWKs the received credential's signature must verify against. The credential is rejected if it does not.
txCode?
optional txCode?: string;
Defined in: .pnpm/@gramota+oid4vci@0.3.0/node_modules/@gramota/oid4vci/dist/client.d.ts:69
Transaction code (PIN) — supplied when the offer's tx_code requires it.
Inherited from
AcceptOfferOptions.txCode
credentialConfigurationId?
optional credentialConfigurationId?: string;
Defined in: .pnpm/@gramota+oid4vci@0.3.0/node_modules/@gramota/oid4vci/dist/client.d.ts:71
Override which credential_configuration_id to request. Default: first.
Inherited from
AcceptOfferOptions.credentialConfigurationId
proofIat?
optional proofIat?: number;
Defined in: .pnpm/@gramota+oid4vci@0.3.0/node_modules/@gramota/oid4vci/dist/client.d.ts:73
Override iat in the proof JWT — for tests.
Inherited from
AcceptOfferOptions.proofIat
fetcher?
optional fetcher?: Fetcher;
Defined in: .pnpm/@gramota+oid4vci@0.3.0/node_modules/@gramota/oid4vci/dist/client.d.ts:75
Override fetcher per-call.
Inherited from
AcceptOfferOptions.fetcher
AuthorizeOptions
Defined in: @gramota/holder/dist/holder.d.ts:37
Options for holder.offers.authorize().
Properties
redirectUri
redirectUri: string;
Defined in: @gramota/holder/dist/holder.d.ts:40
Where the issuer should redirect the user after consent. Must match a redirect URI registered with / accepted by the issuer.
clientId?
optional clientId?: string;
Defined in: @gramota/holder/dist/holder.d.ts:43
OAuth client_id. Defaults to redirectUri (a common public-client
pattern when the wallet has no separate registered identifier).
credentialConfigurationId?
optional credentialConfigurationId?: string;
Defined in: @gramota/holder/dist/holder.d.ts:45
Override which credential to request. Default: first id from the offer.
scope?
optional scope?: string;
Defined in: @gramota/holder/dist/holder.d.ts:47
Optional OAuth scope.
codeVerifier?
optional codeVerifier?: string;
Defined in: @gramota/holder/dist/holder.d.ts:49
Optional pre-existing PKCE verifier — for tests. Default: random.
state?
optional state?: string;
Defined in: @gramota/holder/dist/holder.d.ts:51
Optional pre-existing CSRF state — for tests. Default: random.
fetcher?
optional fetcher?: Fetcher;
Defined in: @gramota/holder/dist/holder.d.ts:53
Optional fetcher override.
AuthorizeResult
Defined in: @gramota/holder/dist/holder.d.ts:56
Result of holder.offers.authorize().
Properties
authorizationUrl
authorizationUrl: string;
Defined in: @gramota/holder/dist/holder.d.ts:58
Open this URL in the user's browser.
codeVerifier
codeVerifier: string;
Defined in: @gramota/holder/dist/holder.d.ts:60
Persist with the user's session — passed to claim.
state
state: string;
Defined in: @gramota/holder/dist/holder.d.ts:63
Persist and verify against ?state= on the callback. Doubles as
the lookup key for the pending flow inside the Holder.
ClaimOptions
Defined in: @gramota/holder/dist/holder.d.ts:66
Options for holder.offers.claim().
Properties
callbackUrl
callbackUrl: string;
Defined in: @gramota/holder/dist/holder.d.ts:68
The full callback URL the issuer redirected to (with ?code=&state=).
codeVerifier
codeVerifier: string;
Defined in: @gramota/holder/dist/holder.d.ts:70
From authorize's result.
state
state: string;
Defined in: @gramota/holder/dist/holder.d.ts:72
From authorize's result. Used as lookup key for the pending flow.
trustedIssuers
trustedIssuers: readonly JsonWebKey[];
Defined in: @gramota/holder/dist/holder.d.ts:74
Trusted issuer JWKs the received credential must verify against.
fetcher?
optional fetcher?: Fetcher;
Defined in: @gramota/holder/dist/holder.d.ts:76
Optional fetcher override.
proofIat?
optional proofIat?: number;
Defined in: @gramota/holder/dist/holder.d.ts:78
Override iat in the proof JWT — for tests.
RespondOptions
Defined in: @gramota/holder/dist/holder.d.ts:81
Options for holder.respondTo().
Properties
now?
optional now?: () => number;
Defined in: @gramota/holder/dist/holder.d.ts:83
Override "now" — for tests.
Returns
number
pickCredential?
optional pickCredential?: (candidates: readonly {
credential: StoredCredential;
disclose: readonly string[];
}[]) => {
credential: StoredCredential;
disclose: readonly string[];
};
Defined in: @gramota/holder/dist/holder.d.ts:86
When the verifier supplies multiple compatible credentials and you want to control which one is presented, pass a picker. Default: first match.
Parameters
candidates
readonly {
credential: StoredCredential;
disclose: readonly string[];
}[]
Returns
{
credential: StoredCredential;
disclose: readonly string[];
}
credential
credential: StoredCredential;
disclose
disclose: readonly string[];
RespondResult
Defined in: @gramota/holder/dist/holder.d.ts:95
Result of holder.respondTo().
Properties
body
body: string;
Defined in: @gramota/holder/dist/holder.d.ts:97
Form-encoded body to POST to the verifier's response_uri.
credential
credential: StoredCredential;
Defined in: @gramota/holder/dist/holder.d.ts:99
The matched credential (id + token + parsed).
disclosed
disclosed: readonly string[];
Defined in: @gramota/holder/dist/holder.d.ts:101
What was disclosed.
request
request: AuthorizationRequest;
Defined in: @gramota/holder/dist/holder.d.ts:103
The original parsed request, for caller logging.
CredentialsApi
Defined in: @gramota/holder/dist/holder.d.ts:106
Stripe-style sub-API for credential CRUD. holder.credentials.X(...).
Methods
receive()
receive(token: string, options: ReceiveOptions): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/holder.d.ts:108
Validate and store an issued SD-JWT-VC.
Parameters
token
string
options
Returns
Promise<StoredCredential>
get()
get(id: string): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/holder.d.ts:110
Get one stored credential by id.
Parameters
id
string
Returns
Promise<StoredCredential>
list()
list(query?: CredentialQuery): Promise<readonly StoredCredential[]>;
Defined in: @gramota/holder/dist/holder.d.ts:112
List stored credentials, optionally filtered.
Parameters
query?
Returns
Promise<readonly StoredCredential[]>
remove()
remove(id: string): Promise<boolean>;
Defined in: @gramota/holder/dist/holder.d.ts:114
Remove a credential. Returns true if it existed.
Parameters
id
string
Returns
Promise<boolean>
StoredCredential
Defined in: @gramota/holder/dist/types.d.ts:7
A credential the holder has received and validated.
Properties
id
id: string;
Defined in: @gramota/holder/dist/types.d.ts:8
token
token: string;
Defined in: @gramota/holder/dist/types.d.ts:10
The original compact-serialised SD-JWT-VC issuance token.
parsed
parsed: ParsedSdJwt;
Defined in: @gramota/holder/dist/types.d.ts:12
Pre-parsed view; pre-computed for faster queries.
issuer
issuer: string;
Defined in: @gramota/holder/dist/types.d.ts:14
Issuer identifier, copied out of iss for indexed access.
receivedAt
receivedAt: number;
Defined in: @gramota/holder/dist/types.d.ts:16
Unix seconds of when the holder accepted this credential.
CredentialQuery
Defined in: @gramota/holder/dist/types.d.ts:19
Optional filter when listing stored credentials.
Properties
issuer?
optional issuer?: string;
Defined in: @gramota/holder/dist/types.d.ts:20
withClaim?
optional withClaim?: string;
Defined in: @gramota/holder/dist/types.d.ts:22
Match credentials that contain a given selectively-disclosable claim.
CredentialStore
Defined in: @gramota/holder/dist/types.d.ts:33
Persistence boundary (Strategy + Repository pattern).
Implementations are interchangeable — Holder depends only on this
interface (Dependency Inversion). Default: InMemoryCredentialStore.
Future implementations: FileCredentialStore, EncryptedCredentialStore,
IndexedDBCredentialStore (browser).
Methods
add()
add(credential: StoredCredential): Promise<void>;
Defined in: @gramota/holder/dist/types.d.ts:34
Parameters
credential
Returns
Promise<void>
get()
get(id: string): Promise<StoredCredential>;
Defined in: @gramota/holder/dist/types.d.ts:35
Parameters
id
string
Returns
Promise<StoredCredential>
list()
list(query?: CredentialQuery): Promise<readonly StoredCredential[]>;
Defined in: @gramota/holder/dist/types.d.ts:36
Parameters
query?
Returns
Promise<readonly StoredCredential[]>
remove()
remove(id: string): Promise<boolean>;
Defined in: @gramota/holder/dist/types.d.ts:37
Parameters
id
string
Returns
Promise<boolean>
ReceiveOptions
Defined in: @gramota/holder/dist/types.d.ts:68
Properties
trustedIssuers
trustedIssuers: readonly JsonWebKey[];
Defined in: @gramota/holder/dist/types.d.ts:71
Public JWKs of issuers the holder trusts. The credential's signature must verify against at least one.
PresentOptions
Defined in: @gramota/holder/dist/types.d.ts:73
Properties
credentialId
credentialId: string;
Defined in: @gramota/holder/dist/types.d.ts:74
disclose
disclose: readonly string[];
Defined in: @gramota/holder/dist/types.d.ts:77
Names of object claims to selectively disclose. All must be available
in the credential. To disclose nothing, pass [].
audience
audience: string;
Defined in: @gramota/holder/dist/types.d.ts:79
Verifier identifier — bound into the KB-JWT's aud claim.
nonce
nonce: string;
Defined in: @gramota/holder/dist/types.d.ts:81
Verifier challenge — bound into the KB-JWT's nonce claim.
now?
optional now?: () => number;
Defined in: @gramota/holder/dist/types.d.ts:83
Override "now" — for tests.
Returns
number
Type Aliases
CredentialId
type CredentialId = string;
Defined in: @gramota/holder/dist/types.d.ts:5
Identifier of a stored credential. UUID v4, generated at receive time.
HolderConfig
type HolderConfig = HolderSignerInput & {
store?: CredentialStore;
};
Defined in: @gramota/holder/dist/types.d.ts:64
Configuration for a Holder instance.
Type Declaration
store?
optional store?: CredentialStore;
Storage backend. Default: in-memory (lost on process exit).
HolderErrorCode
type HolderErrorCode =
| "holder.invalid_input"
| "holder.malformed_token"
| "holder.no_trusted_issuers"
| "holder.issuer_signature_invalid"
| "holder.disclosure_forged"
| "holder.cnf_missing"
| "holder.cnf_mismatch"
| "holder.credential_not_found"
| "holder.disclosure_unavailable"
| "holder.pd_unsatisfiable"
| "holder.pd_required"
| "holder.multi_credential_unsupported"
| "holder.unknown_flow";
Defined in: @gramota/holder/dist/types.d.ts:86
Stable codes for HolderError.