@interop/did-cli 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -6
- package/README.md +157 -17
- package/dist/commands/did/create.d.ts +22 -0
- package/dist/commands/did/create.d.ts.map +1 -1
- package/dist/commands/did/create.js +6 -27
- package/dist/commands/did/create.js.map +1 -1
- package/dist/commands/did/service.d.ts +19 -4
- package/dist/commands/did/service.d.ts.map +1 -1
- package/dist/commands/did/service.js +46 -45
- package/dist/commands/did/service.js.map +1 -1
- package/dist/commands/did/webvh-update.d.ts +72 -9
- package/dist/commands/did/webvh-update.d.ts.map +1 -1
- package/dist/commands/did/webvh-update.js +177 -61
- package/dist/commands/did/webvh-update.js.map +1 -1
- package/dist/commands/did.d.ts.map +1 -1
- package/dist/commands/did.js +10 -1
- package/dist/commands/did.js.map +1 -1
- package/dist/commands/key.d.ts.map +1 -1
- package/dist/commands/key.js +5 -8
- package/dist/commands/key.js.map +1 -1
- package/dist/commands/was/request-grant.d.ts +37 -0
- package/dist/commands/was/request-grant.d.ts.map +1 -0
- package/dist/commands/was/request-grant.js +248 -0
- package/dist/commands/was/request-grant.js.map +1 -0
- package/dist/commands/was/resource.d.ts +21 -7
- package/dist/commands/was/resource.d.ts.map +1 -1
- package/dist/commands/was/resource.js +40 -15
- package/dist/commands/was/resource.js.map +1 -1
- package/dist/commands/was/shared.d.ts +43 -3
- package/dist/commands/was/shared.d.ts.map +1 -1
- package/dist/commands/was/shared.js +82 -4
- package/dist/commands/was/shared.js.map +1 -1
- package/dist/commands/was/shell/completer.d.ts +24 -0
- package/dist/commands/was/shell/completer.d.ts.map +1 -0
- package/dist/commands/was/shell/completer.js +99 -0
- package/dist/commands/was/shell/completer.js.map +1 -0
- package/dist/commands/was/shell/dispatcher.d.ts +27 -0
- package/dist/commands/was/shell/dispatcher.d.ts.map +1 -0
- package/dist/commands/was/shell/dispatcher.js +227 -0
- package/dist/commands/was/shell/dispatcher.js.map +1 -0
- package/dist/commands/was/shell/session.d.ts +37 -0
- package/dist/commands/was/shell/session.d.ts.map +1 -0
- package/dist/commands/was/shell/session.js +67 -0
- package/dist/commands/was/shell/session.js.map +1 -0
- package/dist/commands/was/shell/tokenize.d.ts +19 -0
- package/dist/commands/was/shell/tokenize.d.ts.map +1 -0
- package/dist/commands/was/shell/tokenize.js +77 -0
- package/dist/commands/was/shell/tokenize.js.map +1 -0
- package/dist/commands/was/shell.d.ts +30 -0
- package/dist/commands/was/shell.d.ts.map +1 -0
- package/dist/commands/was/shell.js +170 -0
- package/dist/commands/was/shell.js.map +1 -0
- package/dist/commands/was/tree.d.ts +6 -1
- package/dist/commands/was/tree.d.ts.map +1 -1
- package/dist/commands/was/tree.js +12 -5
- package/dist/commands/was/tree.js.map +1 -1
- package/dist/commands/was.d.ts.map +1 -1
- package/dist/commands/was.js +31 -1
- package/dist/commands/was.js.map +1 -1
- package/dist/keys/seed.d.ts +21 -0
- package/dist/keys/seed.d.ts.map +1 -0
- package/dist/keys/seed.js +41 -0
- package/dist/keys/seed.js.map +1 -0
- package/dist/keys/webvh-signer.d.ts +18 -13
- package/dist/keys/webvh-signer.d.ts.map +1 -1
- package/dist/keys/webvh-signer.js +5 -20
- package/dist/keys/webvh-signer.js.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +57 -10
- package/dist/storage.js.map +1 -1
- package/dist/was/address.d.ts +24 -0
- package/dist/was/address.d.ts.map +1 -1
- package/dist/was/address.js +49 -3
- package/dist/was/address.js.map +1 -1
- package/dist/was/request-grant.d.ts +144 -0
- package/dist/was/request-grant.d.ts.map +1 -0
- package/dist/was/request-grant.js +249 -0
- package/dist/was/request-grant.js.map +1 -0
- package/package.json +22 -20
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { IVPRDetails } from '@interop/data-integrity-core/vpr';
|
|
2
|
+
import type { IZcap } from '@interop/data-integrity-core/zcap';
|
|
3
|
+
/**
|
|
4
|
+
* The wallet-defined descriptor for a world-readable collection under the
|
|
5
|
+
* user's own Space. Naming a descriptor rather than a URL is what lets the
|
|
6
|
+
* request be written before the Space exists: the wallet resolves it to one of
|
|
7
|
+
* its own collections at consent time.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PUBLIC_COLLECTION_TYPE = "https://w3id.org/byoe#public-collection";
|
|
10
|
+
/** The collection the request names when `--collection` is not given. */
|
|
11
|
+
export declare const DEFAULT_COLLECTION = "web";
|
|
12
|
+
/** The actions the request asks for when `--action` is not given. */
|
|
13
|
+
export declare const DEFAULT_ACTIONS: string[];
|
|
14
|
+
/**
|
|
15
|
+
* How long to wait for the user to approve before giving up: the server's
|
|
16
|
+
* exchange TTL, since past it the exchange is gone and no approval can arrive.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_TIMEOUT_MS: number;
|
|
19
|
+
/**
|
|
20
|
+
* The largest wait the poll's deadline accepts (a `setTimeout` delay, which is
|
|
21
|
+
* truncated to a signed 32-bit value and would otherwise fire at once).
|
|
22
|
+
* Anything past this is rejected as bad input rather than left to fail deep
|
|
23
|
+
* inside the poll.
|
|
24
|
+
*/
|
|
25
|
+
export declare const MAX_TIMEOUT_MS = 2147483647;
|
|
26
|
+
/**
|
|
27
|
+
* Raised when the exchange itself ran but produced no grant: the user declined,
|
|
28
|
+
* let it expire, or approved a request the wallet could not satisfy. These are
|
|
29
|
+
* operation failures rather than bad input, and the command reports them as
|
|
30
|
+
* such. Internal to this package; nothing dispatches on the name across a
|
|
31
|
+
* package boundary.
|
|
32
|
+
*/
|
|
33
|
+
export declare class GrantRequestError extends Error {
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The subset of `fetch` the exchange helpers use.
|
|
37
|
+
*/
|
|
38
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
39
|
+
/**
|
|
40
|
+
* Replaces the `fetch` the exchange helpers transport over (a test-only seam,
|
|
41
|
+
* mirroring `setWasClientFactory`). Call with no argument to restore the
|
|
42
|
+
* global `fetch`.
|
|
43
|
+
*
|
|
44
|
+
* @param [fetchImpl] {FetchLike}
|
|
45
|
+
* @returns {void}
|
|
46
|
+
*/
|
|
47
|
+
export declare function setExchangeFetch(fetchImpl?: FetchLike): void;
|
|
48
|
+
/**
|
|
49
|
+
* Builds the zcap-only VPR this command sends: one capability query naming the
|
|
50
|
+
* agent as the capability `controller` and a public-collection descriptor as
|
|
51
|
+
* the target, plus an optional root `agent` member naming what the agent
|
|
52
|
+
* calls itself, composed by wallet-core. There is deliberately no
|
|
53
|
+
* `DIDAuthentication` query and no `domain` -- the agent is asking for
|
|
54
|
+
* authority, not proving who it is to a verifier, and a CLI has no attested
|
|
55
|
+
* origin for a wallet to check a domain against (one sent anyway is enforced,
|
|
56
|
+
* and fails).
|
|
57
|
+
*
|
|
58
|
+
* @param options {object}
|
|
59
|
+
* @param options.controller {string} The agent's did:key (the grantee).
|
|
60
|
+
* @param [options.collection] {string} The collection name to request.
|
|
61
|
+
* @param [options.actions] {string[]} The actions to request.
|
|
62
|
+
* @param [options.reason] {string} Human-readable text shown at consent.
|
|
63
|
+
* @param [options.name] {string} The agent's self-declared display name,
|
|
64
|
+
* shown at consent as what it calls itself.
|
|
65
|
+
* @returns {IVPRDetails}
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildCapabilityRequest({ controller, collection, actions, reason, name }: {
|
|
68
|
+
controller: string;
|
|
69
|
+
collection?: string;
|
|
70
|
+
actions?: string[];
|
|
71
|
+
reason?: string;
|
|
72
|
+
name?: string;
|
|
73
|
+
}): IVPRDetails;
|
|
74
|
+
/**
|
|
75
|
+
* Resolves a wallet base URL to its external-request route, rejecting anything
|
|
76
|
+
* that is not an absolute http(s) URL. Kept separate from the link itself so a
|
|
77
|
+
* bad `--wallet` is caught before an exchange is opened for it.
|
|
78
|
+
*
|
|
79
|
+
* @param options {object}
|
|
80
|
+
* @param options.wallet {string} The wallet's base URL.
|
|
81
|
+
* @returns {URL}
|
|
82
|
+
*/
|
|
83
|
+
export declare function walletRequestRoute({ wallet }: {
|
|
84
|
+
wallet: string;
|
|
85
|
+
}): URL;
|
|
86
|
+
/**
|
|
87
|
+
* Builds the link that opens a wallet straight onto the approval page for an
|
|
88
|
+
* exchange, for the case where the user is already at a browser: the wallet's
|
|
89
|
+
* external-request route carrying the interaction URL as a percent-encoded
|
|
90
|
+
* `url` parameter. The interaction URL alone stays the fallback, since it is
|
|
91
|
+
* what a wallet on another device can be pointed at.
|
|
92
|
+
*
|
|
93
|
+
* @param options {object}
|
|
94
|
+
* @param options.route {URL} The wallet's external-request route.
|
|
95
|
+
* @param options.interactionUrl {string} The exchange's interaction URL.
|
|
96
|
+
* @returns {string}
|
|
97
|
+
*/
|
|
98
|
+
export declare function buildWalletDeepLink({ route, interactionUrl }: {
|
|
99
|
+
route: URL;
|
|
100
|
+
interactionUrl: string;
|
|
101
|
+
}): string;
|
|
102
|
+
/**
|
|
103
|
+
* Opens an ephemeral exchange on the WAS server carrying the request, and
|
|
104
|
+
* returns both the URL to poll and the interaction URL to hand the user.
|
|
105
|
+
*
|
|
106
|
+
* @param options {object}
|
|
107
|
+
* @param options.server {string} The WAS server base URL.
|
|
108
|
+
* @param options.request {IVPRDetails} The VPR to store on the exchange.
|
|
109
|
+
* @returns {Promise<{exchangeUrl: string, interactionUrl: string}>}
|
|
110
|
+
*/
|
|
111
|
+
export declare function openGrantExchange({ server, request }: {
|
|
112
|
+
server: string;
|
|
113
|
+
request: IVPRDetails;
|
|
114
|
+
}): Promise<{
|
|
115
|
+
exchangeUrl: string;
|
|
116
|
+
interactionUrl: string;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Pulls the delegated capabilities out of a completed exchange response. The
|
|
120
|
+
* wallet posts `{ verifiablePresentation }`, and the zcaps ride inside that
|
|
121
|
+
* presentation as its `zcap` member.
|
|
122
|
+
*
|
|
123
|
+
* @param response {unknown} The exchange's `response` member.
|
|
124
|
+
* @returns {IZcap[]}
|
|
125
|
+
*/
|
|
126
|
+
export declare function extractCapabilities(response: unknown): IZcap[];
|
|
127
|
+
/**
|
|
128
|
+
* Waits for the user's wallet to complete the exchange, and returns the
|
|
129
|
+
* capabilities it delegated. Gives up at `timeoutMs`, and distinguishes an
|
|
130
|
+
* exchange the server has already dropped from one still waiting on the user.
|
|
131
|
+
*
|
|
132
|
+
* @param options {object}
|
|
133
|
+
* @param options.exchangeUrl {string}
|
|
134
|
+
* @param [options.timeoutMs] {number}
|
|
135
|
+
* @param [options.intervalMs] {number} How often to poll.
|
|
136
|
+
* @returns {Promise<IZcap[]>}
|
|
137
|
+
*/
|
|
138
|
+
export declare function awaitGrantedCapabilities({ exchangeUrl, timeoutMs, intervalMs }: {
|
|
139
|
+
exchangeUrl: string;
|
|
140
|
+
timeoutMs?: number;
|
|
141
|
+
intervalMs?: number;
|
|
142
|
+
}): Promise<IZcap[]>;
|
|
143
|
+
export {};
|
|
144
|
+
//# sourceMappingURL=request-grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-grant.d.ts","sourceRoot":"","sources":["../../src/was/request-grant.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAEV,WAAW,EACZ,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAA;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,4CAA4C,CAAA;AAE/E,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,QAAQ,CAAA;AAEvC,qEAAqE;AACrE,eAAO,MAAM,eAAe,UAAiC,CAAA;AAS7D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAA4B,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,cAAc,aAAgB,CAAA;AAE3C;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C;;GAEG;AACH,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAIzE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAE5D;AAsBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,UAA+B,EAC/B,OAAyB,EACzB,MAAM,EACN,IAAI,EACL,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,WAAW,CAcd;AASD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAoBtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,cAAc,EACf,EAAE;IACD,KAAK,EAAE,GAAG,CAAA;IACV,cAAc,EAAE,MAAM,CAAA;CACvB,GAAG,MAAM,CAIT;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,MAAM,EACN,OAAO,EACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAM3D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,KAAK,EAAE,CA4B9D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,WAAW,EACX,SAA8B,EAC9B,UAAU,EACX,EAAE;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CA8BnB"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The requesting half of capability delegation (`was request-grant`), the
|
|
3
|
+
* inverse of `was grant`. Instead of signing a capability for someone else,
|
|
4
|
+
* this asks a user's wallet to sign one for us: it builds a zcap-only
|
|
5
|
+
* Verifiable Presentation Request (VPR), opens an ephemeral exchange on the
|
|
6
|
+
* WAS server to carry it, and waits for the wallet to post back a response
|
|
7
|
+
* presentation holding the delegated capabilities.
|
|
8
|
+
*
|
|
9
|
+
* Nothing here is signed. The exchange routes are unauthenticated by design --
|
|
10
|
+
* the exchange URL is itself the secret, and it travels point-to-point to the
|
|
11
|
+
* user (today as a printed interaction URL). Both the exchange transport and
|
|
12
|
+
* the zcap-only VPR composition come from `@interop/wallet-request`; what
|
|
13
|
+
* is owned here is the CLI's own request shape (the public-collection
|
|
14
|
+
* descriptor and the action normalization) and the response parsing.
|
|
15
|
+
*/
|
|
16
|
+
import { composeCapabilityRequest, createEphemeralExchange, pollEphemeralExchange, EPHEMERAL_EXCHANGE_TTL_MS } from '@interop/wallet-request';
|
|
17
|
+
/**
|
|
18
|
+
* The wallet-defined descriptor for a world-readable collection under the
|
|
19
|
+
* user's own Space. Naming a descriptor rather than a URL is what lets the
|
|
20
|
+
* request be written before the Space exists: the wallet resolves it to one of
|
|
21
|
+
* its own collections at consent time.
|
|
22
|
+
*/
|
|
23
|
+
export const PUBLIC_COLLECTION_TYPE = 'https://w3id.org/byoe#public-collection';
|
|
24
|
+
/** The collection the request names when `--collection` is not given. */
|
|
25
|
+
export const DEFAULT_COLLECTION = 'web';
|
|
26
|
+
/** The actions the request asks for when `--action` is not given. */
|
|
27
|
+
export const DEFAULT_ACTIONS = ['GET', 'HEAD', 'PUT', 'POST'];
|
|
28
|
+
/**
|
|
29
|
+
* The actions a capability request may name. A superset of the verbs
|
|
30
|
+
* `was grant` signs (it adds `HEAD`), because the wallet -- not this CLI -- is
|
|
31
|
+
* the authority on what it is willing to delegate.
|
|
32
|
+
*/
|
|
33
|
+
const REQUESTABLE_ACTIONS = ['GET', 'HEAD', 'PUT', 'POST', 'DELETE'];
|
|
34
|
+
/**
|
|
35
|
+
* How long to wait for the user to approve before giving up: the server's
|
|
36
|
+
* exchange TTL, since past it the exchange is gone and no approval can arrive.
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_TIMEOUT_MS = EPHEMERAL_EXCHANGE_TTL_MS;
|
|
39
|
+
/**
|
|
40
|
+
* The largest wait the poll's deadline accepts (a `setTimeout` delay, which is
|
|
41
|
+
* truncated to a signed 32-bit value and would otherwise fire at once).
|
|
42
|
+
* Anything past this is rejected as bad input rather than left to fail deep
|
|
43
|
+
* inside the poll.
|
|
44
|
+
*/
|
|
45
|
+
export const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
46
|
+
/**
|
|
47
|
+
* Raised when the exchange itself ran but produced no grant: the user declined,
|
|
48
|
+
* let it expire, or approved a request the wallet could not satisfy. These are
|
|
49
|
+
* operation failures rather than bad input, and the command reports them as
|
|
50
|
+
* such. Internal to this package; nothing dispatches on the name across a
|
|
51
|
+
* package boundary.
|
|
52
|
+
*/
|
|
53
|
+
export class GrantRequestError extends Error {
|
|
54
|
+
}
|
|
55
|
+
let exchangeFetch;
|
|
56
|
+
/**
|
|
57
|
+
* Replaces the `fetch` the exchange helpers transport over (a test-only seam,
|
|
58
|
+
* mirroring `setWasClientFactory`). Call with no argument to restore the
|
|
59
|
+
* global `fetch`.
|
|
60
|
+
*
|
|
61
|
+
* @param [fetchImpl] {FetchLike}
|
|
62
|
+
* @returns {void}
|
|
63
|
+
*/
|
|
64
|
+
export function setExchangeFetch(fetchImpl) {
|
|
65
|
+
exchangeFetch = fetchImpl;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Normalizes requested action verbs to their canonical uppercase form,
|
|
69
|
+
* rejecting anything that is not an HTTP verb a WAS server matches against.
|
|
70
|
+
*
|
|
71
|
+
* @param actions {string[]}
|
|
72
|
+
* @returns {string[]}
|
|
73
|
+
*/
|
|
74
|
+
function normalizeRequestedActions(actions) {
|
|
75
|
+
return actions.map(action => {
|
|
76
|
+
const verb = action.toUpperCase();
|
|
77
|
+
if (!REQUESTABLE_ACTIONS.includes(verb)) {
|
|
78
|
+
throw new Error(`Unknown action "${action}" (supported: ` +
|
|
79
|
+
`${REQUESTABLE_ACTIONS.join(', ')}).`);
|
|
80
|
+
}
|
|
81
|
+
return verb;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Builds the zcap-only VPR this command sends: one capability query naming the
|
|
86
|
+
* agent as the capability `controller` and a public-collection descriptor as
|
|
87
|
+
* the target, plus an optional root `agent` member naming what the agent
|
|
88
|
+
* calls itself, composed by wallet-core. There is deliberately no
|
|
89
|
+
* `DIDAuthentication` query and no `domain` -- the agent is asking for
|
|
90
|
+
* authority, not proving who it is to a verifier, and a CLI has no attested
|
|
91
|
+
* origin for a wallet to check a domain against (one sent anyway is enforced,
|
|
92
|
+
* and fails).
|
|
93
|
+
*
|
|
94
|
+
* @param options {object}
|
|
95
|
+
* @param options.controller {string} The agent's did:key (the grantee).
|
|
96
|
+
* @param [options.collection] {string} The collection name to request.
|
|
97
|
+
* @param [options.actions] {string[]} The actions to request.
|
|
98
|
+
* @param [options.reason] {string} Human-readable text shown at consent.
|
|
99
|
+
* @param [options.name] {string} The agent's self-declared display name,
|
|
100
|
+
* shown at consent as what it calls itself.
|
|
101
|
+
* @returns {IVPRDetails}
|
|
102
|
+
*/
|
|
103
|
+
export function buildCapabilityRequest({ controller, collection = DEFAULT_COLLECTION, actions = DEFAULT_ACTIONS, reason, name }) {
|
|
104
|
+
const capabilityQuery = {
|
|
105
|
+
...(reason !== undefined && { reason }),
|
|
106
|
+
allowedAction: normalizeRequestedActions(actions),
|
|
107
|
+
controller,
|
|
108
|
+
invocationTarget: {
|
|
109
|
+
type: PUBLIC_COLLECTION_TYPE,
|
|
110
|
+
name: collection
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
return composeCapabilityRequest({
|
|
114
|
+
capabilityQueries: [capabilityQuery],
|
|
115
|
+
...(name !== undefined && { agent: { name } })
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The wallet route an outside request is handed to. Requests arriving from
|
|
120
|
+
* outside the app land under `/external/`; `/wallet/*` stays CHAPI-handler
|
|
121
|
+
* only.
|
|
122
|
+
*/
|
|
123
|
+
const WALLET_REQUEST_PATH = 'external/request';
|
|
124
|
+
/**
|
|
125
|
+
* Resolves a wallet base URL to its external-request route, rejecting anything
|
|
126
|
+
* that is not an absolute http(s) URL. Kept separate from the link itself so a
|
|
127
|
+
* bad `--wallet` is caught before an exchange is opened for it.
|
|
128
|
+
*
|
|
129
|
+
* @param options {object}
|
|
130
|
+
* @param options.wallet {string} The wallet's base URL.
|
|
131
|
+
* @returns {URL}
|
|
132
|
+
*/
|
|
133
|
+
export function walletRequestRoute({ wallet }) {
|
|
134
|
+
let base;
|
|
135
|
+
try {
|
|
136
|
+
base = new URL(wallet);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
throw new Error(`Invalid wallet URL "${wallet}": expected an absolute http(s) URL.`, { cause: err });
|
|
140
|
+
}
|
|
141
|
+
if (base.protocol !== 'https:' && base.protocol !== 'http:') {
|
|
142
|
+
throw new Error(`Invalid wallet URL "${wallet}": expected an http(s) URL, got ` +
|
|
143
|
+
`"${base.protocol}".`);
|
|
144
|
+
}
|
|
145
|
+
// Resolve the route against the base path rather than the origin, so a
|
|
146
|
+
// wallet deployed under a sub-path keeps its prefix.
|
|
147
|
+
const path = base.pathname.endsWith('/') ? base.pathname : `${base.pathname}/`;
|
|
148
|
+
return new URL(`${path}${WALLET_REQUEST_PATH}`, base);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Builds the link that opens a wallet straight onto the approval page for an
|
|
152
|
+
* exchange, for the case where the user is already at a browser: the wallet's
|
|
153
|
+
* external-request route carrying the interaction URL as a percent-encoded
|
|
154
|
+
* `url` parameter. The interaction URL alone stays the fallback, since it is
|
|
155
|
+
* what a wallet on another device can be pointed at.
|
|
156
|
+
*
|
|
157
|
+
* @param options {object}
|
|
158
|
+
* @param options.route {URL} The wallet's external-request route.
|
|
159
|
+
* @param options.interactionUrl {string} The exchange's interaction URL.
|
|
160
|
+
* @returns {string}
|
|
161
|
+
*/
|
|
162
|
+
export function buildWalletDeepLink({ route, interactionUrl }) {
|
|
163
|
+
const link = new URL(route);
|
|
164
|
+
link.searchParams.set('url', interactionUrl);
|
|
165
|
+
return link.toString();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Opens an ephemeral exchange on the WAS server carrying the request, and
|
|
169
|
+
* returns both the URL to poll and the interaction URL to hand the user.
|
|
170
|
+
*
|
|
171
|
+
* @param options {object}
|
|
172
|
+
* @param options.server {string} The WAS server base URL.
|
|
173
|
+
* @param options.request {IVPRDetails} The VPR to store on the exchange.
|
|
174
|
+
* @returns {Promise<{exchangeUrl: string, interactionUrl: string}>}
|
|
175
|
+
*/
|
|
176
|
+
export async function openGrantExchange({ server, request }) {
|
|
177
|
+
return createEphemeralExchange({
|
|
178
|
+
serverUrl: server,
|
|
179
|
+
request,
|
|
180
|
+
...(exchangeFetch && { fetch: exchangeFetch })
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Pulls the delegated capabilities out of a completed exchange response. The
|
|
185
|
+
* wallet posts `{ verifiablePresentation }`, and the zcaps ride inside that
|
|
186
|
+
* presentation as its `zcap` member.
|
|
187
|
+
*
|
|
188
|
+
* @param response {unknown} The exchange's `response` member.
|
|
189
|
+
* @returns {IZcap[]}
|
|
190
|
+
*/
|
|
191
|
+
export function extractCapabilities(response) {
|
|
192
|
+
const presentation = response?.verifiablePresentation;
|
|
193
|
+
if (!presentation) {
|
|
194
|
+
throw new GrantRequestError('The wallet response contained no verifiablePresentation.');
|
|
195
|
+
}
|
|
196
|
+
const { zcap } = presentation;
|
|
197
|
+
const zcaps = zcap === undefined ? [] : Array.isArray(zcap) ? zcap : [zcap];
|
|
198
|
+
for (const capability of zcaps) {
|
|
199
|
+
if (typeof capability.id !== 'string' || capability.id === '') {
|
|
200
|
+
throw new GrantRequestError('The wallet returned a capability with no id, which cannot be filed ' +
|
|
201
|
+
'in the zcap store or named by a later --capability.');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (zcaps.length === 0) {
|
|
205
|
+
throw new GrantRequestError('The wallet returned a presentation with no capabilities: the request ' +
|
|
206
|
+
'was declined, or the collection could not be granted (a public ' +
|
|
207
|
+
'collection is only ever created public, never converted from an ' +
|
|
208
|
+
'existing private one).');
|
|
209
|
+
}
|
|
210
|
+
return zcaps;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Waits for the user's wallet to complete the exchange, and returns the
|
|
214
|
+
* capabilities it delegated. Gives up at `timeoutMs`, and distinguishes an
|
|
215
|
+
* exchange the server has already dropped from one still waiting on the user.
|
|
216
|
+
*
|
|
217
|
+
* @param options {object}
|
|
218
|
+
* @param options.exchangeUrl {string}
|
|
219
|
+
* @param [options.timeoutMs] {number}
|
|
220
|
+
* @param [options.intervalMs] {number} How often to poll.
|
|
221
|
+
* @returns {Promise<IZcap[]>}
|
|
222
|
+
*/
|
|
223
|
+
export async function awaitGrantedCapabilities({ exchangeUrl, timeoutMs = DEFAULT_TIMEOUT_MS, intervalMs }) {
|
|
224
|
+
let response;
|
|
225
|
+
try {
|
|
226
|
+
response = await pollEphemeralExchange({
|
|
227
|
+
exchangeUrl,
|
|
228
|
+
timeoutMs,
|
|
229
|
+
...(intervalMs !== undefined && { intervalMs }),
|
|
230
|
+
...(exchangeFetch && { fetch: exchangeFetch })
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
// The transport is injected and may resolve to a different copy of
|
|
235
|
+
// wallet-core, so the error name is the stable contract here.
|
|
236
|
+
if (err.name === 'EphemeralExchangeGoneError') {
|
|
237
|
+
throw new GrantRequestError('The request expired before it was approved (the server keeps an ' +
|
|
238
|
+
'exchange for ten minutes). Run the command again for a fresh link.', { cause: err });
|
|
239
|
+
}
|
|
240
|
+
if (err.name === 'EphemeralExchangeTimeoutError') {
|
|
241
|
+
throw new GrantRequestError(`Gave up waiting for approval after ${Math.round(timeoutMs / 1000)}s. ` +
|
|
242
|
+
'The request may still be approvable; raise --timeout, or run the ' +
|
|
243
|
+
'command again for a fresh link.', { cause: err });
|
|
244
|
+
}
|
|
245
|
+
throw err;
|
|
246
|
+
}
|
|
247
|
+
return extractCapabilities(response);
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=request-grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-grant.js","sourceRoot":"","sources":["../../src/was/request-grant.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/did-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "DID CLI tool for DIDs, Verifiable Credentials, key pairs, and zcaps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,25 +26,27 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@digitalcredentials/bnid": "^5.0.0",
|
|
28
28
|
"@digitalcredentials/issuer-registry-client": "^4.0.0",
|
|
29
|
-
"@interop/data-integrity-core": "^8.
|
|
30
|
-
"@interop/data-integrity-proof": "^3.4.
|
|
31
|
-
"@interop/did-io": "^4.
|
|
32
|
-
"@interop/did-method-key": "^7.
|
|
33
|
-
"@interop/did-method-webvh": "^
|
|
34
|
-
"@interop/did-web-resolver": "^6.
|
|
35
|
-
"@interop/ecdsa-multikey": "^2.
|
|
36
|
-
"@interop/ecdsa-signature": "2.0.
|
|
37
|
-
"@interop/ed25519-signature": "^7.
|
|
38
|
-
"@interop/ed25519-verification-key": "^8.0
|
|
39
|
-
"@interop/edv-client": "^17.
|
|
40
|
-
"@interop/ezcap": "^7.
|
|
41
|
-
"@interop/minimal-cipher": "^7.
|
|
42
|
-
"@interop/security-document-loader": "^
|
|
43
|
-
"@interop/vc": "^11.0.
|
|
44
|
-
"@interop/verifier-core": "^3.
|
|
45
|
-
"@interop/
|
|
46
|
-
"@interop/
|
|
47
|
-
"@interop/
|
|
29
|
+
"@interop/data-integrity-core": "^8.7.1",
|
|
30
|
+
"@interop/data-integrity-proof": "^3.4.5",
|
|
31
|
+
"@interop/did-io": "^4.1.1",
|
|
32
|
+
"@interop/did-method-key": "^7.4.2",
|
|
33
|
+
"@interop/did-method-webvh": "^5.9.0",
|
|
34
|
+
"@interop/did-web-resolver": "^6.3.3",
|
|
35
|
+
"@interop/ecdsa-multikey": "^2.4.0",
|
|
36
|
+
"@interop/ecdsa-signature": "2.0.7",
|
|
37
|
+
"@interop/ed25519-signature": "^7.2.2",
|
|
38
|
+
"@interop/ed25519-verification-key": "^8.2.0",
|
|
39
|
+
"@interop/edv-client": "^17.8.4",
|
|
40
|
+
"@interop/ezcap": "^7.4.8",
|
|
41
|
+
"@interop/minimal-cipher": "^7.10.2",
|
|
42
|
+
"@interop/security-document-loader": "^10.1.2",
|
|
43
|
+
"@interop/vc": "^11.0.9",
|
|
44
|
+
"@interop/verifier-core": "^3.5.8",
|
|
45
|
+
"@interop/wallet-core": "^0.75.0",
|
|
46
|
+
"@interop/wallet-request": "^0.3.1",
|
|
47
|
+
"@interop/was-client": "^0.60.0",
|
|
48
|
+
"@interop/x25519-key-agreement-key": "^5.4.0",
|
|
49
|
+
"@interop/zcap": "^11.2.0",
|
|
48
50
|
"@scure/base": "^2.2.0",
|
|
49
51
|
"commander": "^15.0.0"
|
|
50
52
|
},
|