From fed1d2959a7a41674e941b0a023a1eebea51486f Mon Sep 17 00:00:00 2001 From: Blair Currey <12960453+BlairCurrey@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:48:02 -0500 Subject: [PATCH 1/2] feat: new types for directed identity, improved grant --- open-payments-specifications | 2 +- packages/open-payments/src/index.ts | 7 ++- .../openapi/generated/auth-server-types.ts | 43 ++++++++++++++++++- .../generated/resource-server-types.ts | 4 +- packages/open-payments/src/types.ts | 19 +++++--- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/open-payments-specifications b/open-payments-specifications index c1de330..70a3697 160000 --- a/open-payments-specifications +++ b/open-payments-specifications @@ -1 +1 @@ -Subproject commit c1de33071c874f1c481d65f2220d791073a1cb6d +Subproject commit 70a36970f132dd483e691e9d3190741abfdc41fb diff --git a/packages/open-payments/src/index.ts b/packages/open-payments/src/index.ts index c0c979c..eb91e51 100644 --- a/packages/open-payments/src/index.ts +++ b/packages/open-payments/src/index.ts @@ -12,8 +12,12 @@ export { OutgoingPaymentGrantSpentAmounts, PendingGrant, Grant, + GrantWithAccessToken, + GrantWithSubject, isPendingGrant, isFinalizedGrant, + isFinalizedGrantWithAccessToken, + isFinalizedGrantWithSubject, JWK, JWKS, PaginationArgs, @@ -22,7 +26,8 @@ export { AccessAction, AccessToken, AccessItem, - Subject + Subject, + Client } from './types' export { diff --git a/packages/open-payments/src/openapi/generated/auth-server-types.ts b/packages/open-payments/src/openapi/generated/auth-server-types.ts index 7477f96..837b32e 100644 --- a/packages/open-payments/src/openapi/generated/auth-server-types.ts +++ b/packages/open-payments/src/openapi/generated/auth-server-types.ts @@ -167,15 +167,31 @@ export interface components { }; /** * client - * @description Wallet address of the client instance that is making this request. + * @description Client identification for grant requests. * * When sending a non-continuation request to the AS, the client instance MUST identify itself by including the client field of the request and by signing the request. * + * Can be either: + * - A wallet address string (backwards compatible format) + * - An object with either `jwk` (for directed identity) or `walletAddress` (mutually exclusive) + * + * When using a wallet address string or the `walletAddress` property: * A JSON Web Key Set document, including the public key that the client instance will use to protect this request and any continuation requests at the AS and any user-facing information about the client instance used in interactions, MUST be available at the wallet address + `/jwks.json` url. * + * When using the `jwk` property (directed identity approach): + * The client instance provides its public key directly in the request, eliminating the need for the AS to fetch it from a wallet address. This approach enhances privacy by not requiring the client to expose a persistent wallet address identifier. The `jwk` property can only be used for non-interactive grant requests (i.e.: incoming payments). + * * If sending a grant initiation request that requires RO interaction, the wallet address MUST serve necessary client display information. */ - client: string; + client: string | { + /** + * Format: uri + * @description Wallet address of the client instance that is making this request. + */ + walletAddress: string; + } | { + jwk: components["schemas"]["json-web-key"]; + }; /** * continue * @description If the AS determines that the request can be continued with additional requests, it responds with the continue field. @@ -307,6 +323,29 @@ export interface components { format: "uri"; }[]; }; + /** + * Ed25519 Public Key + * @description A JWK representation of an Ed25519 Public Key + */ + "json-web-key": { + kid: string; + /** + * @description The cryptographic algorithm family used with the key. The only allowed value is `EdDSA`. + * @enum {string} + */ + alg: "EdDSA"; + /** @enum {string} */ + use?: "sig"; + /** @enum {string} */ + kty: "OKP"; + /** + * @description The cryptographic curve used with the key. This parameter identifies the elliptic curve (for EC keys) or the Edwards curve (for OKP keys). The only allowed value is `Ed25519`. + * @enum {string} + */ + crv: "Ed25519"; + /** @description The base64 url-encoded public key. */ + x: string; + }; }; responses: never; parameters: never; diff --git a/packages/open-payments/src/openapi/generated/resource-server-types.ts b/packages/open-payments/src/openapi/generated/resource-server-types.ts index 144e548..d269a4e 100644 --- a/packages/open-payments/src/openapi/generated/resource-server-types.ts +++ b/packages/open-payments/src/openapi/generated/resource-server-types.ts @@ -894,8 +894,8 @@ export interface operations { }; content: { "application/json": { - spentReceiveAmount?: components["schemas"]["amount"]; - spentDebitAmount?: components["schemas"]["amount"]; + spentReceiveAmount: components["schemas"]["amount"] | null; + spentDebitAmount: components["schemas"]["amount"] | null; }; }; }; diff --git a/packages/open-payments/src/types.ts b/packages/open-payments/src/types.ts index 0331267..371061d 100644 --- a/packages/open-payments/src/types.ts +++ b/packages/open-payments/src/types.ts @@ -85,14 +85,18 @@ export const getASPath =
(path: P): string =>
path as string
export type Subject = ASComponents['schemas']['subject']
+export type Client =
+ | string
+ | { walletAddress: string; jwk?: never }
+ | { jwk: JWK; walletAddress?: never }
export type NonInteractiveGrantRequest = {
access_token: ASOperations['post-request']['requestBody']['content']['application/json']['access_token']
- client: ASOperations['post-request']['requestBody']['content']['application/json']['client']
+ client: Client
}
type BaseGrantRequest = {
- client: ASOperations['post-request']['requestBody']['content']['application/json']['client']
+ client: Client
interact?: ASOperations['post-request']['requestBody']['content']['application/json']['interact']
}
@@ -113,6 +117,12 @@ export type Grant = {
continue: ASComponents['schemas']['continue']
subject?: Subject
}
+export type GrantWithAccessToken = Grant & {
+ access_token: NonNullable