iso-ucan 0.0.1
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/dist/src/capability.d.ts +49 -0
- package/dist/src/capability.d.ts.map +1 -0
- package/dist/src/client.d.ts +47 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/delegation.d.ts +61 -0
- package/dist/src/delegation.d.ts.map +1 -0
- package/dist/src/envelope.d.ts +39 -0
- package/dist/src/envelope.d.ts.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/invocation.d.ts +46 -0
- package/dist/src/invocation.d.ts.map +1 -0
- package/dist/src/policy.d.ts +10 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/server.d.ts +5 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/store.d.ts +49 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/types.d.ts +187 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +136 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/varsig.d.ts +24 -0
- package/dist/src/varsig.d.ts.map +1 -0
- package/package.json +140 -0
- package/readme.md +81 -0
- package/src/capability.js +77 -0
- package/src/client.js +52 -0
- package/src/delegation.js +183 -0
- package/src/envelope.js +88 -0
- package/src/index.js +1 -0
- package/src/invocation.js +227 -0
- package/src/policy.js +272 -0
- package/src/server.ts +24 -0
- package/src/store.js +187 -0
- package/src/types/envelope.ts +131 -0
- package/src/types/policy.ts +100 -0
- package/src/types/varsig.ts +22 -0
- package/src/types.ts +243 -0
- package/src/utils.js +375 -0
- package/src/varsig.js +157 -0
package/src/store.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { parse as didParse } from 'iso-did'
|
|
2
|
+
import { KV } from 'iso-kv'
|
|
3
|
+
import merge from 'it-merge'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @import {Delegation} from './delegation.js'
|
|
7
|
+
* @import {Driver} from 'iso-kv'
|
|
8
|
+
* @import {CID} from 'multiformats'
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const POWERLINE = '$pwrl'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Store
|
|
15
|
+
*/
|
|
16
|
+
export class Store {
|
|
17
|
+
/** @type {Driver} */
|
|
18
|
+
driver
|
|
19
|
+
|
|
20
|
+
/** @type {KV} */
|
|
21
|
+
kv
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Driver} driver
|
|
25
|
+
*/
|
|
26
|
+
constructor(driver) {
|
|
27
|
+
this.driver = driver
|
|
28
|
+
|
|
29
|
+
this.kv = new KV({
|
|
30
|
+
driver,
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Set a delegation in the store by CID and index it by cmd and aud
|
|
36
|
+
*
|
|
37
|
+
* @param {Delegation} delegation
|
|
38
|
+
*/
|
|
39
|
+
async #set(delegation) {
|
|
40
|
+
const options = {
|
|
41
|
+
expiration: delegation.envelope.payload.exp,
|
|
42
|
+
}
|
|
43
|
+
const cid = delegation.cid.toString()
|
|
44
|
+
|
|
45
|
+
// Index by CID
|
|
46
|
+
await this.kv.set([cid], delegation, options)
|
|
47
|
+
|
|
48
|
+
// Index by subject and audience
|
|
49
|
+
/** @type {string | null} */
|
|
50
|
+
let sub = delegation.sub ? delegation.sub : null
|
|
51
|
+
if (sub === null) {
|
|
52
|
+
sub = POWERLINE
|
|
53
|
+
}
|
|
54
|
+
await this.kv.set([sub, delegation.aud, cid], cid, options)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {Delegation[]} delegations
|
|
59
|
+
*/
|
|
60
|
+
async add(delegations) {
|
|
61
|
+
for (const delegation of delegations) {
|
|
62
|
+
await this.#set(delegation)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get a delegation by cid
|
|
68
|
+
*
|
|
69
|
+
* @param {string} cid
|
|
70
|
+
*/
|
|
71
|
+
get(cid) {
|
|
72
|
+
return /** @type {typeof this.kv.get<Delegation>} */ (this.kv.get)([cid])
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Resolve a proof by CID
|
|
77
|
+
*
|
|
78
|
+
* @param {CID} cid
|
|
79
|
+
*/
|
|
80
|
+
async resolveProof(cid) {
|
|
81
|
+
const delegation = await this.get(cid.toString())
|
|
82
|
+
if (!delegation) {
|
|
83
|
+
throw new Error(`Delegation not found: ${cid.toString()}`)
|
|
84
|
+
}
|
|
85
|
+
return delegation
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* List proofs by sub and aud
|
|
90
|
+
*
|
|
91
|
+
* @param {import('./types.js').StoreProofsOptions} options
|
|
92
|
+
*/
|
|
93
|
+
async *proofs(options) {
|
|
94
|
+
/**@type {string | null} */
|
|
95
|
+
let sub = options.sub ? options.sub.toString() : null
|
|
96
|
+
/**@type {string | undefined} */
|
|
97
|
+
let aud = options.aud ? options.aud.toString() : undefined
|
|
98
|
+
|
|
99
|
+
if (!aud && !sub) {
|
|
100
|
+
throw new Error('No audience or subject provided')
|
|
101
|
+
}
|
|
102
|
+
if (!aud && sub) {
|
|
103
|
+
aud = sub
|
|
104
|
+
}
|
|
105
|
+
if (sub === null) {
|
|
106
|
+
sub = POWERLINE
|
|
107
|
+
}
|
|
108
|
+
if (!aud) {
|
|
109
|
+
throw new Error('No audience provided')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for await (const element of this.kv.list({
|
|
113
|
+
prefix: [sub, aud],
|
|
114
|
+
})) {
|
|
115
|
+
const value = await this.get(element.value)
|
|
116
|
+
|
|
117
|
+
if (value) {
|
|
118
|
+
yield value
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Resolve a single chain of proofs ending with a root (subject === issuer).
|
|
125
|
+
* Returns the first such chain found (depth-first).
|
|
126
|
+
*
|
|
127
|
+
* @param {import('./types.js').StoreProofsOptions} options
|
|
128
|
+
* @returns {Promise<Delegation[]>}
|
|
129
|
+
*/
|
|
130
|
+
async chain({ aud, sub, cmd }) {
|
|
131
|
+
// console.log('🚀 ~ aud', aud, 'sub', sub, 'cmd', cmd)
|
|
132
|
+
const parents = parentCmds(cmd)
|
|
133
|
+
|
|
134
|
+
const sources = merge(
|
|
135
|
+
this.proofs({ sub, aud, cmd }),
|
|
136
|
+
this.proofs({ sub: null, aud, cmd })
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
for await (const proof of sources) {
|
|
140
|
+
if (!parents.includes(proof.cmd)) continue
|
|
141
|
+
|
|
142
|
+
// If root, return this proof as the end of the path
|
|
143
|
+
if (proof.sub === didParse(proof.iss).did) {
|
|
144
|
+
// console.log('🚀 ~ found root:', proof.iss, proof.sub, proof.cmd)
|
|
145
|
+
return [proof]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Otherwise, go deeper and prepend this proof if a path is found
|
|
149
|
+
// console.log('🚀 ~ trying deeper:', proof.iss, proof.sub, proof.cmd)
|
|
150
|
+
const nextPath = await this.chain({
|
|
151
|
+
aud: didParse(proof.iss).did,
|
|
152
|
+
sub: proof.sub ? proof.sub : sub,
|
|
153
|
+
cmd: proof.cmd,
|
|
154
|
+
})
|
|
155
|
+
if (nextPath?.length) {
|
|
156
|
+
return [proof, ...nextPath]
|
|
157
|
+
}
|
|
158
|
+
// console.log('🚀 ~ no path found')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// No path found
|
|
162
|
+
return []
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Returns all parent commands for a given command string.
|
|
168
|
+
*
|
|
169
|
+
* @param {string} cmd
|
|
170
|
+
* @returns {string[]}
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts twoslash
|
|
173
|
+
* import { parentCmds } from 'iso-ucan/store'
|
|
174
|
+
* parentCmds('/foo/bar/baz') // ["/", "/foo", "/foo/bar", "/foo/bar/baz"]
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
function parentCmds(cmd) {
|
|
178
|
+
if (!cmd || cmd === '/') return ['/']
|
|
179
|
+
const parts = cmd.split('/').filter(Boolean)
|
|
180
|
+
const result = ['/']
|
|
181
|
+
let current = ''
|
|
182
|
+
for (const part of parts) {
|
|
183
|
+
current += `/${part}`
|
|
184
|
+
result.push(current)
|
|
185
|
+
}
|
|
186
|
+
return result
|
|
187
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { DID, DIDURL } from 'iso-did/types'
|
|
2
|
+
import type { ISigner } from 'iso-signatures/types'
|
|
3
|
+
import type { CID } from 'multiformats'
|
|
4
|
+
import type { Policy } from './policy'
|
|
5
|
+
import type { VarsigAlgorithm, VarsigEncoding } from './varsig'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Envelope types
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type PayloadSpec = 'dlg' | 'inv'
|
|
12
|
+
export type PayloadTag = `ucan/${PayloadSpec}@${string}`
|
|
13
|
+
export interface PayloadBase {
|
|
14
|
+
/**
|
|
15
|
+
* Issuer DID (sender)
|
|
16
|
+
*/
|
|
17
|
+
iss: DIDURL
|
|
18
|
+
/**
|
|
19
|
+
* Audience DID (receiver)
|
|
20
|
+
*/
|
|
21
|
+
aud?: DID
|
|
22
|
+
/**
|
|
23
|
+
* Principal that the chain is about (the [Subject])
|
|
24
|
+
*/
|
|
25
|
+
sub?: DID | null
|
|
26
|
+
/**
|
|
27
|
+
* The Command to eventually invoke
|
|
28
|
+
* @see https://github.com/ucan-wg/spec#command
|
|
29
|
+
*/
|
|
30
|
+
cmd: string
|
|
31
|
+
/**
|
|
32
|
+
* The nonce of the UCAN
|
|
33
|
+
* @see https://github.com/ucan-wg/spec#nonce
|
|
34
|
+
*/
|
|
35
|
+
nonce: Uint8Array
|
|
36
|
+
/**
|
|
37
|
+
* Meta (asserted, signed data) — is not delegated authority
|
|
38
|
+
*/
|
|
39
|
+
meta?: Record<string, unknown>
|
|
40
|
+
/**
|
|
41
|
+
* Expiration UTC Unix Timestamp in seconds (valid until)
|
|
42
|
+
*/
|
|
43
|
+
exp: number | null
|
|
44
|
+
/**
|
|
45
|
+
* "Not before" UTC Unix Timestamp in seconds (valid from)
|
|
46
|
+
*/
|
|
47
|
+
nbf?: number
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @see https://github.com/ucan-wg/invocation#invocation-payload
|
|
52
|
+
*/
|
|
53
|
+
export interface InvocationPayload extends PayloadBase {
|
|
54
|
+
sub: DID
|
|
55
|
+
/**
|
|
56
|
+
* Optional if equal to subject
|
|
57
|
+
*/
|
|
58
|
+
aud?: DID
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Any [Arguments] that MUST be present in the Invocation
|
|
62
|
+
*/
|
|
63
|
+
args: Record<string, unknown>
|
|
64
|
+
/**
|
|
65
|
+
* Delegations that prove the chain of authority
|
|
66
|
+
*/
|
|
67
|
+
prf: CID[]
|
|
68
|
+
/**
|
|
69
|
+
* Issued at time
|
|
70
|
+
*/
|
|
71
|
+
iat?: number
|
|
72
|
+
/**
|
|
73
|
+
* An OPTIONAL CID of the Receipt that enqueued the Task
|
|
74
|
+
*/
|
|
75
|
+
cause?: CID
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface DelegationPayload<Args = unknown> extends PayloadBase {
|
|
79
|
+
aud: DID
|
|
80
|
+
/**
|
|
81
|
+
* Subject can be null here for Powerline
|
|
82
|
+
* @see https://github.com/ucan-wg/delegation/#powerline
|
|
83
|
+
*/
|
|
84
|
+
sub: DID | null
|
|
85
|
+
pol: Policy<Args>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type Payload<Args = unknown> =
|
|
89
|
+
| InvocationPayload
|
|
90
|
+
| DelegationPayload<Args>
|
|
91
|
+
export type SignaturePayload<Args = unknown> = {
|
|
92
|
+
h: Uint8Array
|
|
93
|
+
[payloadTag: PayloadTag]: Payload<Args>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type Envelope<Args = unknown> = [Uint8Array, SignaturePayload<Args>]
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @see https://github.com/ucan-wg/spec#envelope
|
|
100
|
+
*/
|
|
101
|
+
export type EnvelopeEncodeOptions = {
|
|
102
|
+
signature: Uint8Array
|
|
103
|
+
signaturePayload: SignaturePayload
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface EnvelopeSignOptions {
|
|
107
|
+
/**
|
|
108
|
+
* @default '1.0.0'
|
|
109
|
+
*/
|
|
110
|
+
version?: string
|
|
111
|
+
/**
|
|
112
|
+
* @default 'DAG-CBOR'
|
|
113
|
+
*/
|
|
114
|
+
enc?: VarsigEncoding
|
|
115
|
+
spec: PayloadSpec
|
|
116
|
+
payload: Payload
|
|
117
|
+
signer: ISigner
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface EnvelopeDecodeOptions {
|
|
121
|
+
envelope: Uint8Array
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type DecodedEnvelope<Spec extends PayloadSpec> = {
|
|
125
|
+
alg: VarsigAlgorithm
|
|
126
|
+
enc: VarsigEncoding
|
|
127
|
+
signature: Uint8Array
|
|
128
|
+
payload: Spec extends 'dlg' ? DelegationPayload : InvocationPayload
|
|
129
|
+
spec: Spec
|
|
130
|
+
version: string
|
|
131
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy types
|
|
3
|
+
* @see https://github.com/ucan-wg/delegation/#policy
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Type-safe selector utilities
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Extracts all possible paths from a data structure as string literals
|
|
12
|
+
*/
|
|
13
|
+
type PathsToStringProps<T> = T extends
|
|
14
|
+
| string
|
|
15
|
+
| number
|
|
16
|
+
| boolean
|
|
17
|
+
| null
|
|
18
|
+
| undefined
|
|
19
|
+
? never
|
|
20
|
+
: T extends Array<infer U>
|
|
21
|
+
?
|
|
22
|
+
| `[]`
|
|
23
|
+
| `[${number}]`
|
|
24
|
+
| `[${number}:${number}]`
|
|
25
|
+
| `[${number}:]`
|
|
26
|
+
| `[:${number}]`
|
|
27
|
+
| `[:]`
|
|
28
|
+
| PathsToStringProps<U>
|
|
29
|
+
: T extends object
|
|
30
|
+
? {
|
|
31
|
+
[K in keyof T & (string | number)]: K extends string
|
|
32
|
+
? `.${K}` | `.${K}?` | `.${K}${PathsToStringProps<T[K]>}`
|
|
33
|
+
: `[${K}]` | `[${K}]?` | `[${K}]${PathsToStringProps<T[K]>}`
|
|
34
|
+
}[keyof T & (string | number)]
|
|
35
|
+
: never
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Flattens nested path strings into a union of all possible selectors
|
|
39
|
+
*/
|
|
40
|
+
type FlattenPaths<T> = T extends string
|
|
41
|
+
? T
|
|
42
|
+
: T extends object
|
|
43
|
+
? {
|
|
44
|
+
[K in keyof T]: T[K] extends string
|
|
45
|
+
? T[K]
|
|
46
|
+
: T[K] extends object
|
|
47
|
+
? FlattenPaths<T[K]>
|
|
48
|
+
: never
|
|
49
|
+
}[keyof T]
|
|
50
|
+
: never
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Type-safe selector that only allows valid paths for the given data structure
|
|
54
|
+
*/
|
|
55
|
+
export type Selector<Args = unknown> = Args extends unknown
|
|
56
|
+
? FlattenPaths<PathsToStringProps<Args>> | '.'
|
|
57
|
+
: string
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Extracts the type of the value at a given selector path (minimal version)
|
|
61
|
+
*/
|
|
62
|
+
type SelectorValue<T, S extends string> = S extends `.${infer K}`
|
|
63
|
+
? K extends keyof T
|
|
64
|
+
? T[K]
|
|
65
|
+
: never
|
|
66
|
+
: S extends `[${infer I}]`
|
|
67
|
+
? T extends Array<infer U>
|
|
68
|
+
? U
|
|
69
|
+
: never
|
|
70
|
+
: never
|
|
71
|
+
|
|
72
|
+
/** Connectives */
|
|
73
|
+
export type EqualityOp = '==' | '!='
|
|
74
|
+
export type Equality<Args = unknown> = [EqualityOp, Selector<Args>, unknown]
|
|
75
|
+
export type InequalityOp = '<' | '<=' | '>' | '>='
|
|
76
|
+
export type Inequality<Args = unknown> = [InequalityOp, Selector<Args>, number]
|
|
77
|
+
|
|
78
|
+
export type NegateOp = 'not'
|
|
79
|
+
export type Negate<Args = unknown> = [NegateOp, Statement<Args>]
|
|
80
|
+
|
|
81
|
+
export type ConnectiveOp = 'and' | 'or'
|
|
82
|
+
export type Connective<Args = unknown> = [ConnectiveOp, Statement<Args>[]]
|
|
83
|
+
|
|
84
|
+
export type QuantifierOp = 'all' | 'any'
|
|
85
|
+
export type Quantifier<
|
|
86
|
+
Args = unknown,
|
|
87
|
+
Sel extends Selector<Args> = Selector<Args>,
|
|
88
|
+
> = [QuantifierOp, Sel, Statement<SelectorValue<Args, Sel>>]
|
|
89
|
+
export type LikeOp = 'like'
|
|
90
|
+
export type Like<Args = unknown> = [LikeOp, Selector<Args>, string]
|
|
91
|
+
|
|
92
|
+
export type Statement<Args = unknown> =
|
|
93
|
+
| Equality<Args>
|
|
94
|
+
| Inequality<Args>
|
|
95
|
+
| Negate<Args>
|
|
96
|
+
| Connective<Args>
|
|
97
|
+
| Quantifier<Args>
|
|
98
|
+
| Like<Args>
|
|
99
|
+
|
|
100
|
+
export type Policy<Args = unknown> = Statement<Args>[]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SignatureType } from 'iso-signatures/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Varsig types
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Supported encoding types for data to be signed or verified
|
|
9
|
+
*/
|
|
10
|
+
export type VarsigEncoding = 'RAW' | 'DAG-CBOR'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Supported signature types
|
|
14
|
+
*/
|
|
15
|
+
export type VarsigAlgorithm = SignatureType
|
|
16
|
+
|
|
17
|
+
export interface VarsigOptions {
|
|
18
|
+
enc: VarsigEncoding
|
|
19
|
+
alg: VarsigAlgorithm
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type DecodeOutput = VarsigOptions
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
2
|
+
import type { Resolver as _DidResolver } from 'iso-did'
|
|
3
|
+
import type { DID, DIDURLObject, VerifiableDID } from 'iso-did/types'
|
|
4
|
+
import type { ISigner } from 'iso-signatures/types'
|
|
5
|
+
import type { Resolver } from 'iso-signatures/verifiers/resolver.js'
|
|
6
|
+
import type { CID } from 'multiformats'
|
|
7
|
+
import type { Capability } from './capability'
|
|
8
|
+
import type { Delegation } from './delegation'
|
|
9
|
+
import type { Invocation } from './invocation'
|
|
10
|
+
import type { Store } from './store'
|
|
11
|
+
import type { Policy } from './types/policy'
|
|
12
|
+
|
|
13
|
+
export type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
14
|
+
export type { DID, DIDURL, DIDURLObject } from 'iso-did/types'
|
|
15
|
+
export * from './types/envelope'
|
|
16
|
+
export * from './types/policy'
|
|
17
|
+
export * from './types/varsig'
|
|
18
|
+
|
|
19
|
+
export type ResolveProof = (proof: CID) => Promise<Delegation>
|
|
20
|
+
export type IsRevoked = (cid: CID) => Promise<boolean>
|
|
21
|
+
export type VerifierResolver = Resolver
|
|
22
|
+
export type DidResolver = _DidResolver
|
|
23
|
+
|
|
24
|
+
export type CborPrimitive =
|
|
25
|
+
| string
|
|
26
|
+
| number
|
|
27
|
+
| boolean
|
|
28
|
+
| null
|
|
29
|
+
| bigint
|
|
30
|
+
| Uint8Array
|
|
31
|
+
| ArrayBuffer
|
|
32
|
+
export type CborArray = CborValue[] | readonly CborValue[]
|
|
33
|
+
export type CborObject =
|
|
34
|
+
| { [Key in string]: CborValue }
|
|
35
|
+
| { [Key in string]?: CborValue | undefined }
|
|
36
|
+
|
|
37
|
+
export type CborValue = CborPrimitive | CborArray | CborObject
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Delegation
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
export interface DelegationOptions<Args = unknown> {
|
|
44
|
+
iss: ISigner
|
|
45
|
+
aud: DID
|
|
46
|
+
sub: DID | null
|
|
47
|
+
pol: Policy<Args>
|
|
48
|
+
/**
|
|
49
|
+
* Expiration time in seconds or null for no expiration
|
|
50
|
+
*/
|
|
51
|
+
exp?: number | null
|
|
52
|
+
/**
|
|
53
|
+
* Time to live in seconds, expiration thats precedence over ttl
|
|
54
|
+
* @default 300
|
|
55
|
+
*/
|
|
56
|
+
ttl?: number
|
|
57
|
+
/**
|
|
58
|
+
* Not before time in seconds
|
|
59
|
+
* Delegation is not valid before this time
|
|
60
|
+
*/
|
|
61
|
+
nbf?: number
|
|
62
|
+
nonce?: Uint8Array
|
|
63
|
+
cmd: string
|
|
64
|
+
meta?: CborObject
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface DelegationFromOptions {
|
|
68
|
+
bytes: Uint8Array
|
|
69
|
+
isRevoked?: IsRevoked
|
|
70
|
+
didResolver?: DidResolver
|
|
71
|
+
verifierResolver: VerifierResolver
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface DelegationValidateOptions {
|
|
75
|
+
isRevoked?: IsRevoked
|
|
76
|
+
didResolver?: DidResolver
|
|
77
|
+
verifierResolver: VerifierResolver
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type CapabilityDelegateOptions<Args = unknown> = Omit<
|
|
81
|
+
DelegationOptions<Args>,
|
|
82
|
+
'cmd'
|
|
83
|
+
>
|
|
84
|
+
/**
|
|
85
|
+
* Invocation
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Invocation options
|
|
90
|
+
*/
|
|
91
|
+
export interface InvocationOptions {
|
|
92
|
+
iss: ISigner
|
|
93
|
+
aud?: DID
|
|
94
|
+
sub: DID
|
|
95
|
+
cmd: string
|
|
96
|
+
args: CborObject
|
|
97
|
+
/**
|
|
98
|
+
* Proofs of the chain of authority
|
|
99
|
+
*/
|
|
100
|
+
prf: Delegation[]
|
|
101
|
+
/**
|
|
102
|
+
* Expiration time in seconds or null for no expiration
|
|
103
|
+
*/
|
|
104
|
+
exp?: number | null
|
|
105
|
+
/**
|
|
106
|
+
* Time to live in seconds, expiration thats precedence over ttl
|
|
107
|
+
* @default 300
|
|
108
|
+
*/
|
|
109
|
+
ttl?: number
|
|
110
|
+
/**
|
|
111
|
+
* Issued at time in seconds
|
|
112
|
+
*/
|
|
113
|
+
iat?: number
|
|
114
|
+
nbf?: number
|
|
115
|
+
nonce?: Uint8Array
|
|
116
|
+
cause?: CID
|
|
117
|
+
meta?: CborObject
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface InvocationFromOptions {
|
|
121
|
+
bytes: Uint8Array
|
|
122
|
+
audience: VerifiableDID
|
|
123
|
+
didResolver?: DidResolver
|
|
124
|
+
verifierResolver: VerifierResolver
|
|
125
|
+
isRevoked?: IsRevoked
|
|
126
|
+
resolveProof: ResolveProof
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface CapabilityInvokeOptions<Schema extends StandardSchemaV1>
|
|
130
|
+
extends Omit<InvocationOptions, 'cmd' | 'args' | 'prf'> {
|
|
131
|
+
args: StandardSchemaV1.InferOutput<Schema>
|
|
132
|
+
store: Store
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Store types
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Resolve proofs options
|
|
141
|
+
*/
|
|
142
|
+
export interface StoreProofsOptions {
|
|
143
|
+
aud?: DID
|
|
144
|
+
sub: DID | null
|
|
145
|
+
cmd: string
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Server types
|
|
150
|
+
*/
|
|
151
|
+
export type Promisable<T> = T | PromiseLike<T>
|
|
152
|
+
|
|
153
|
+
export interface HandlerOptions<Schema extends StandardSchemaV1> {
|
|
154
|
+
args: StandardSchemaV1.InferOutput<Schema>
|
|
155
|
+
store: Store
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export type Handler<Schema extends StandardSchemaV1, Output> = (
|
|
159
|
+
options: HandlerOptions<Schema>
|
|
160
|
+
) => Promisable<Output>
|
|
161
|
+
|
|
162
|
+
export interface RouteOptions<
|
|
163
|
+
Cap extends Capability<StandardSchemaV1>,
|
|
164
|
+
Output,
|
|
165
|
+
> {
|
|
166
|
+
capability: Cap
|
|
167
|
+
handler: Handler<Cap['schema'], Output>
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type RouteOutput<Cap extends Capability<StandardSchemaV1>, Output> = {
|
|
171
|
+
cap: Cap
|
|
172
|
+
fn: (options: RouteHandlerOptions) => Promisable<Output>
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Infer the protocol from a router
|
|
177
|
+
*/
|
|
178
|
+
export type InferProtocol<
|
|
179
|
+
Routes extends Record<
|
|
180
|
+
string,
|
|
181
|
+
RouteOutput<Capability<StandardSchemaV1>, unknown>
|
|
182
|
+
>,
|
|
183
|
+
> = {
|
|
184
|
+
[K in keyof Routes]: Routes[K] extends RouteOutput<infer Cap, infer Output>
|
|
185
|
+
? {
|
|
186
|
+
cmd: Cap['cmd'] extends K ? Cap['cmd'] : never
|
|
187
|
+
in: StandardSchemaV1.InferOutput<Cap['schema']>
|
|
188
|
+
out: Output
|
|
189
|
+
}
|
|
190
|
+
: never
|
|
191
|
+
}[keyof Routes]
|
|
192
|
+
|
|
193
|
+
export type Protocol<
|
|
194
|
+
Cap extends Capability<StandardSchemaV1> = Capability<StandardSchemaV1>,
|
|
195
|
+
> = {
|
|
196
|
+
cmd: Cap['cmd']
|
|
197
|
+
in: StandardSchemaV1.InferOutput<Cap['schema']>
|
|
198
|
+
out: unknown
|
|
199
|
+
}[]
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Creates a router type that validates:
|
|
203
|
+
* 1. Router keys match capability commands
|
|
204
|
+
* 2. Router values are RouteOutput types that match the capability
|
|
205
|
+
*/
|
|
206
|
+
export type Router<Caps extends readonly Capability<StandardSchemaV1>[]> = {
|
|
207
|
+
[K in Caps[number]['cmd']]: Caps extends readonly (infer Cap)[]
|
|
208
|
+
? Cap extends Capability<StandardSchemaV1>
|
|
209
|
+
? Cap['cmd'] extends K
|
|
210
|
+
? RouteOutput<Cap, unknown>
|
|
211
|
+
: never
|
|
212
|
+
: never
|
|
213
|
+
: never
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface RouteHandlerOptions {
|
|
217
|
+
request: Request
|
|
218
|
+
issuer: ISigner
|
|
219
|
+
invocation: Invocation
|
|
220
|
+
store: Store
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Client type that provides type-safe request methods based on router inference
|
|
225
|
+
*/
|
|
226
|
+
export type RouterClient<
|
|
227
|
+
Router extends InferProtocol<
|
|
228
|
+
Record<string, RouteOutput<Capability<StandardSchemaV1>, unknown>>
|
|
229
|
+
>,
|
|
230
|
+
> = {
|
|
231
|
+
request<Cmd extends Router['cmd']>(
|
|
232
|
+
cmd: Cmd,
|
|
233
|
+
args: Extract<Router, { cmd: Cmd }>['in']
|
|
234
|
+
): Promise<Extract<Router, { cmd: Cmd }>['out']>
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export type ClientOptions = {
|
|
238
|
+
url: string
|
|
239
|
+
issuer: ISigner
|
|
240
|
+
audience: DIDURLObject
|
|
241
|
+
store: Store
|
|
242
|
+
capabilities: Capability<StandardSchemaV1, string>[]
|
|
243
|
+
}
|