accounts 0.15.3 → 0.16.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 +31 -0
- package/dist/cli/adapter.d.ts +2 -2
- package/dist/cli/adapter.d.ts.map +1 -1
- package/dist/cli/adapter.js +84 -5
- package/dist/cli/adapter.js.map +1 -1
- package/dist/core/AccessKey.js +1 -1
- package/dist/core/AccessKey.js.map +1 -1
- package/dist/core/Client.d.ts +1 -1
- package/dist/core/Client.d.ts.map +1 -1
- package/dist/core/Client.js +30 -10
- package/dist/core/Client.js.map +1 -1
- package/dist/react/privy.d.ts.map +1 -1
- package/dist/react/privy.js +7 -5
- package/dist/react/privy.js.map +1 -1
- package/dist/server/CliAuth.d.ts +718 -33
- package/dist/server/CliAuth.d.ts.map +1 -1
- package/dist/server/CliAuth.js +340 -47
- package/dist/server/CliAuth.js.map +1 -1
- package/dist/server/internal/handlers/codeAuth.d.ts.map +1 -1
- package/dist/server/internal/handlers/codeAuth.js +2 -2
- package/dist/server/internal/handlers/codeAuth.js.map +1 -1
- package/package.json +2 -2
- package/src/cli/Provider.localnet.test.ts +170 -5
- package/src/cli/adapter.ts +96 -6
- package/src/core/AccessKey.test.ts +36 -0
- package/src/core/AccessKey.ts +1 -1
- package/src/core/Client.test.ts +35 -19
- package/src/core/Client.ts +36 -11
- package/src/core/Provider.test.ts +16 -0
- package/src/react/privy.ts +9 -5
- package/src/server/CliAuth.test-d.ts +40 -5
- package/src/server/CliAuth.test.ts +535 -23
- package/src/server/CliAuth.ts +425 -66
- package/src/server/internal/handlers/codeAuth.ts +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CliAuth.d.ts","sourceRoot":"","sources":["../../src/server/CliAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,GAAG,EAAa,MAAM,IAAI,CAAA;AAC3D,OAAO,EAA6C,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACvF,OAAO,EAAsB,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"CliAuth.d.ts","sourceRoot":"","sources":["../../src/server/CliAuth.ts"],"names":[],"mappings":"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"}
|
package/dist/server/CliAuth.js
CHANGED
|
@@ -2,8 +2,10 @@ import { Address, Base64, Bytes, Hex, PublicKey } from 'ox';
|
|
|
2
2
|
import { KeyAuthorization as TempoKeyAuthorization, SignatureEnvelope } from 'ox/tempo';
|
|
3
3
|
import { createClient, http } from 'viem';
|
|
4
4
|
import { verifyHash } from 'viem/actions';
|
|
5
|
+
import { Actions } from 'viem/tempo';
|
|
5
6
|
import { tempo } from 'viem/tempo/chains';
|
|
6
7
|
import * as z from 'zod/mini';
|
|
8
|
+
import * as AccessKey from '../core/AccessKey.js';
|
|
7
9
|
import * as u from '../core/zod/utils.js';
|
|
8
10
|
const maxLimits = 10;
|
|
9
11
|
const limit = z.object({ token: u.address(), limit: u.bigint() });
|
|
@@ -19,9 +21,9 @@ const showDeposit = z.optional(z.union([
|
|
|
19
21
|
]));
|
|
20
22
|
const defaultTtlMs = 10 * 60 * 1_000;
|
|
21
23
|
const alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
|
|
22
|
-
/** Supported access
|
|
24
|
+
/** Supported access key types for CLI bootstrap. */
|
|
23
25
|
export const keyType = z.union([z.literal('secp256k1'), z.literal('p256'), z.literal('webAuthn')]);
|
|
24
|
-
/** Signed key authorization returned by the device
|
|
26
|
+
/** Signed key authorization returned by the device code flow. */
|
|
25
27
|
export const keyAuthorization = z.object({
|
|
26
28
|
address: u.address(),
|
|
27
29
|
chainId: u.bigint(),
|
|
@@ -31,8 +33,8 @@ export const keyAuthorization = z.object({
|
|
|
31
33
|
limits: z.optional(limits),
|
|
32
34
|
signature: z.custom(),
|
|
33
35
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const authorizeAccessKeyCreateRequest = z.object({
|
|
37
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
36
38
|
account: z.optional(u.address()),
|
|
37
39
|
chainId: z.optional(u.bigint()),
|
|
38
40
|
codeChallenge: z.string(),
|
|
@@ -42,6 +44,20 @@ export const createRequest = z.object({
|
|
|
42
44
|
pubKey: u.hex(),
|
|
43
45
|
showDeposit,
|
|
44
46
|
});
|
|
47
|
+
const updateAccessKeyCreateRequest = z.object({
|
|
48
|
+
action: z.literal('updateAccessKey'),
|
|
49
|
+
accessKeyAddress: u.address(),
|
|
50
|
+
account: u.address(),
|
|
51
|
+
chainId: z.optional(u.bigint()),
|
|
52
|
+
codeChallenge: z.string(),
|
|
53
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
54
|
+
limits: z.readonly(z.array(limit).check(z.minLength(1), z.maxLength(maxLimits))),
|
|
55
|
+
});
|
|
56
|
+
/** CLI auth device code creation request body. */
|
|
57
|
+
export const createRequest = u.oneOf([
|
|
58
|
+
authorizeAccessKeyCreateRequest,
|
|
59
|
+
updateAccessKeyCreateRequest,
|
|
60
|
+
]);
|
|
45
61
|
/** Response body for `POST /cli-auth/device-code`. */
|
|
46
62
|
export const createResponse = z.object({
|
|
47
63
|
code: z.string(),
|
|
@@ -60,36 +76,65 @@ export const pollResponse = u.oneOf([
|
|
|
60
76
|
accountAddress: u.address(),
|
|
61
77
|
keyAuthorization: keyAuthorization,
|
|
62
78
|
}),
|
|
79
|
+
z.object({
|
|
80
|
+
action: z.literal('updateAccessKey'),
|
|
81
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
82
|
+
status: z.literal('authorized'),
|
|
83
|
+
}),
|
|
63
84
|
z.object({
|
|
64
85
|
status: z.literal('expired'),
|
|
65
86
|
}),
|
|
66
87
|
]);
|
|
67
88
|
/** Response body for `GET /auth/pkce/pending/:code`. */
|
|
68
|
-
export const pendingResponse =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
export const pendingResponse = u.oneOf([
|
|
90
|
+
z.object({
|
|
91
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
92
|
+
accessKeyAddress: u.address(),
|
|
93
|
+
account: z.optional(u.address()),
|
|
94
|
+
chainId: u.bigint(),
|
|
95
|
+
code: z.string(),
|
|
96
|
+
expiry: z.number(),
|
|
97
|
+
keyType,
|
|
98
|
+
limits: z.optional(limits),
|
|
99
|
+
pubKey: u.hex(),
|
|
100
|
+
showDeposit,
|
|
101
|
+
status: z.literal('pending'),
|
|
102
|
+
}),
|
|
103
|
+
z.object({
|
|
104
|
+
action: z.literal('updateAccessKey'),
|
|
105
|
+
accessKeyAddress: u.address(),
|
|
106
|
+
account: u.address(),
|
|
107
|
+
chainId: u.bigint(),
|
|
108
|
+
code: z.string(),
|
|
109
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
110
|
+
limits: z.readonly(z.array(limit).check(z.minLength(1), z.maxLength(maxLimits))),
|
|
111
|
+
status: z.literal('pending'),
|
|
112
|
+
}),
|
|
113
|
+
]);
|
|
80
114
|
/** Request body for `POST /auth/pkce`. */
|
|
81
|
-
export const authorizeRequest =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
export const authorizeRequest = u.oneOf([
|
|
116
|
+
z.object({
|
|
117
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
118
|
+
accountAddress: u.address(),
|
|
119
|
+
code: z.string(),
|
|
120
|
+
keyAuthorization: keyAuthorization,
|
|
121
|
+
}),
|
|
122
|
+
z.object({
|
|
123
|
+
action: z.literal('updateAccessKey'),
|
|
124
|
+
accountAddress: u.address(),
|
|
125
|
+
chainId: u.bigint(),
|
|
126
|
+
code: z.string(),
|
|
127
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
128
|
+
}),
|
|
129
|
+
]);
|
|
86
130
|
/** Response body for `POST /cli-auth/authorize`. */
|
|
87
131
|
export const authorizeResponse = z.object({
|
|
88
132
|
status: z.literal('authorized'),
|
|
89
133
|
});
|
|
90
|
-
/** Stored device
|
|
134
|
+
/** Stored device code entry schema. */
|
|
91
135
|
export const entry = u.oneOf([
|
|
92
136
|
z.object({
|
|
137
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
93
138
|
account: z.optional(u.address()),
|
|
94
139
|
chainId: u.bigint(),
|
|
95
140
|
code: z.string(),
|
|
@@ -104,6 +149,7 @@ export const entry = u.oneOf([
|
|
|
104
149
|
status: z.literal('pending'),
|
|
105
150
|
}),
|
|
106
151
|
z.object({
|
|
152
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
107
153
|
account: z.optional(u.address()),
|
|
108
154
|
accountAddress: u.address(),
|
|
109
155
|
authorizedAt: z.number(),
|
|
@@ -121,6 +167,7 @@ export const entry = u.oneOf([
|
|
|
121
167
|
status: z.literal('authorized'),
|
|
122
168
|
}),
|
|
123
169
|
z.object({
|
|
170
|
+
action: z.optional(z.literal('authorizeAccessKey')),
|
|
124
171
|
account: z.optional(u.address()),
|
|
125
172
|
accountAddress: u.address(),
|
|
126
173
|
authorizedAt: z.number(),
|
|
@@ -138,8 +185,52 @@ export const entry = u.oneOf([
|
|
|
138
185
|
showDeposit,
|
|
139
186
|
status: z.literal('consumed'),
|
|
140
187
|
}),
|
|
188
|
+
z.object({
|
|
189
|
+
action: z.literal('updateAccessKey'),
|
|
190
|
+
accessKeyAddress: u.address(),
|
|
191
|
+
account: u.address(),
|
|
192
|
+
chainId: u.bigint(),
|
|
193
|
+
code: z.string(),
|
|
194
|
+
codeChallenge: z.string(),
|
|
195
|
+
createdAt: z.number(),
|
|
196
|
+
expiresAt: z.number(),
|
|
197
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
198
|
+
limits: z.readonly(z.array(limit).check(z.minLength(1), z.maxLength(maxLimits))),
|
|
199
|
+
status: z.literal('pending'),
|
|
200
|
+
}),
|
|
201
|
+
z.object({
|
|
202
|
+
action: z.literal('updateAccessKey'),
|
|
203
|
+
accessKeyAddress: u.address(),
|
|
204
|
+
account: u.address(),
|
|
205
|
+
accountAddress: u.address(),
|
|
206
|
+
authorizedAt: z.number(),
|
|
207
|
+
chainId: u.bigint(),
|
|
208
|
+
code: z.string(),
|
|
209
|
+
codeChallenge: z.string(),
|
|
210
|
+
createdAt: z.number(),
|
|
211
|
+
expiresAt: z.number(),
|
|
212
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
213
|
+
limits: z.readonly(z.array(limit).check(z.minLength(1), z.maxLength(maxLimits))),
|
|
214
|
+
status: z.literal('authorized'),
|
|
215
|
+
}),
|
|
216
|
+
z.object({
|
|
217
|
+
action: z.literal('updateAccessKey'),
|
|
218
|
+
accessKeyAddress: u.address(),
|
|
219
|
+
account: u.address(),
|
|
220
|
+
accountAddress: u.address(),
|
|
221
|
+
authorizedAt: z.number(),
|
|
222
|
+
chainId: u.bigint(),
|
|
223
|
+
code: z.string(),
|
|
224
|
+
codeChallenge: z.string(),
|
|
225
|
+
consumedAt: z.number(),
|
|
226
|
+
createdAt: z.number(),
|
|
227
|
+
expiresAt: z.number(),
|
|
228
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
229
|
+
limits: z.readonly(z.array(limit).check(z.minLength(1), z.maxLength(maxLimits))),
|
|
230
|
+
status: z.literal('consumed'),
|
|
231
|
+
}),
|
|
141
232
|
]);
|
|
142
|
-
/** Error thrown when pending device
|
|
233
|
+
/** Error thrown when pending device code lookup cannot return a pending request. */
|
|
143
234
|
export class PendingError extends Error {
|
|
144
235
|
/** HTTP status returned by handler surfaces. */
|
|
145
236
|
status;
|
|
@@ -149,10 +240,10 @@ export class PendingError extends Error {
|
|
|
149
240
|
this.status = status;
|
|
150
241
|
}
|
|
151
242
|
}
|
|
152
|
-
/** Built-in device
|
|
243
|
+
/** Built-in device code store helpers. */
|
|
153
244
|
export const Store = {
|
|
154
245
|
/**
|
|
155
|
-
* Creates an in-memory device
|
|
246
|
+
* Creates an in-memory device code store.
|
|
156
247
|
*
|
|
157
248
|
* Useful for tests and single-process servers.
|
|
158
249
|
*/
|
|
@@ -161,7 +252,7 @@ export const Store = {
|
|
|
161
252
|
return {
|
|
162
253
|
async authorize(options) {
|
|
163
254
|
const current = entries.get(options.code);
|
|
164
|
-
if (!current || current.status !== 'pending')
|
|
255
|
+
if (!current || current.status !== 'pending' || current.action === 'updateAccessKey')
|
|
165
256
|
return undefined;
|
|
166
257
|
const next = {
|
|
167
258
|
...current,
|
|
@@ -193,10 +284,24 @@ export const Store = {
|
|
|
193
284
|
async get(code) {
|
|
194
285
|
return entries.get(code);
|
|
195
286
|
},
|
|
287
|
+
async update(options) {
|
|
288
|
+
const current = entries.get(options.code);
|
|
289
|
+
if (!current || current.status !== 'pending' || current.action !== 'updateAccessKey')
|
|
290
|
+
return undefined;
|
|
291
|
+
const next = {
|
|
292
|
+
...current,
|
|
293
|
+
accountAddress: options.accountAddress,
|
|
294
|
+
authorizedAt: Date.now(),
|
|
295
|
+
...(options.keyAuthorization ? { keyAuthorization: options.keyAuthorization } : {}),
|
|
296
|
+
status: 'authorized',
|
|
297
|
+
};
|
|
298
|
+
entries.set(options.code, next);
|
|
299
|
+
return next;
|
|
300
|
+
},
|
|
196
301
|
};
|
|
197
302
|
},
|
|
198
303
|
/**
|
|
199
|
-
* Creates a key-value backed device
|
|
304
|
+
* Creates a key-value backed device code store.
|
|
200
305
|
*
|
|
201
306
|
* Stored values are encoded through the shared entry schema so they remain
|
|
202
307
|
* JSON-safe across KV implementations.
|
|
@@ -209,7 +314,7 @@ export const Store = {
|
|
|
209
314
|
return {
|
|
210
315
|
async authorize(options) {
|
|
211
316
|
const current = await this.get(options.code);
|
|
212
|
-
if (!current || current.status !== 'pending')
|
|
317
|
+
if (!current || current.status !== 'pending' || current.action === 'updateAccessKey')
|
|
213
318
|
return undefined;
|
|
214
319
|
const next = {
|
|
215
320
|
...current,
|
|
@@ -244,6 +349,20 @@ export const Store = {
|
|
|
244
349
|
return undefined;
|
|
245
350
|
return z.decode(entry, value);
|
|
246
351
|
},
|
|
352
|
+
async update(options) {
|
|
353
|
+
const current = await this.get(options.code);
|
|
354
|
+
if (!current || current.status !== 'pending' || current.action !== 'updateAccessKey')
|
|
355
|
+
return undefined;
|
|
356
|
+
const next = {
|
|
357
|
+
...current,
|
|
358
|
+
accountAddress: options.accountAddress,
|
|
359
|
+
authorizedAt: Date.now(),
|
|
360
|
+
...(options.keyAuthorization ? { keyAuthorization: options.keyAuthorization } : {}),
|
|
361
|
+
status: 'authorized',
|
|
362
|
+
};
|
|
363
|
+
await kv.set(toKey(options.code), z.encode(entry, next));
|
|
364
|
+
return next;
|
|
365
|
+
},
|
|
247
366
|
};
|
|
248
367
|
},
|
|
249
368
|
};
|
|
@@ -252,6 +371,9 @@ export const Policy = {
|
|
|
252
371
|
/** Creates an allow-all policy with a default 24-hour expiry when omitted. */
|
|
253
372
|
allow() {
|
|
254
373
|
return {
|
|
374
|
+
update({ limits }) {
|
|
375
|
+
return { limits };
|
|
376
|
+
},
|
|
255
377
|
validate({ expiry, limits }) {
|
|
256
378
|
return {
|
|
257
379
|
expiry: expiry ?? Math.floor(Date.now() / 1000) + 60 * 60 * 24,
|
|
@@ -339,16 +461,79 @@ export function from(options = {}) {
|
|
|
339
461
|
if (current.account &&
|
|
340
462
|
current.account.toLowerCase() !== options.request.accountAddress.toLowerCase())
|
|
341
463
|
throw new Error('Account does not match requested account.');
|
|
464
|
+
if (current.action === 'updateAccessKey') {
|
|
465
|
+
if (options.request.action !== 'updateAccessKey')
|
|
466
|
+
throw new Error('Device code action does not match the completion request.');
|
|
467
|
+
if (options.request.chainId !== current.chainId)
|
|
468
|
+
throw new Error('Access key update chain does not match the device code request.');
|
|
469
|
+
const client = options.client ?? cache.get(current.chainId);
|
|
470
|
+
let replacement;
|
|
471
|
+
if (current.keyAuthorization) {
|
|
472
|
+
const metadata = await Actions.accessKey
|
|
473
|
+
.getMetadata(client, {
|
|
474
|
+
account: options.request.accountAddress,
|
|
475
|
+
accessKey: current.accessKeyAddress,
|
|
476
|
+
})
|
|
477
|
+
.catch((error) => {
|
|
478
|
+
if (AccessKey.isUnavailableError(error))
|
|
479
|
+
return undefined;
|
|
480
|
+
throw error;
|
|
481
|
+
});
|
|
482
|
+
if (metadata?.address.toLowerCase() === current.accessKeyAddress.toLowerCase())
|
|
483
|
+
throw new Error('Access key was published while the update was pending.');
|
|
484
|
+
if (!options.request.keyAuthorization)
|
|
485
|
+
throw new Error('Pending access key update requires a replacement key authorization.');
|
|
486
|
+
const previous = normalizeKeyAuthorization(current.keyAuthorization);
|
|
487
|
+
const next = await verifyKeyAuthorizationSignature({
|
|
488
|
+
account: options.request.accountAddress,
|
|
489
|
+
client,
|
|
490
|
+
keyAuthorization: options.request.keyAuthorization,
|
|
491
|
+
});
|
|
492
|
+
if (next.address.toLowerCase() !== current.accessKeyAddress.toLowerCase() ||
|
|
493
|
+
next.keyId.toLowerCase() !== current.accessKeyAddress.toLowerCase())
|
|
494
|
+
throw new Error('Replacement key authorization does not match the access key request.');
|
|
495
|
+
if (next.chainId !== current.chainId)
|
|
496
|
+
throw new Error('Replacement key authorization chain does not match the device code request.');
|
|
497
|
+
if (next.keyType !== previous.keyType || next.expiry !== previous.expiry)
|
|
498
|
+
throw new Error('Replacement key authorization changed immutable access key fields.');
|
|
499
|
+
if (!sameLimits(next.limits, current.limits))
|
|
500
|
+
throw new Error('Replacement key authorization limits do not match the device code request.');
|
|
501
|
+
replacement = toStoredKeyAuthorization(options.request.keyAuthorization, next);
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
if (options.request.keyAuthorization)
|
|
505
|
+
throw new Error('Published access key update cannot return a key authorization.');
|
|
506
|
+
for (const limit of current.limits) {
|
|
507
|
+
const result = await Actions.accessKey.getRemainingLimit(client, {
|
|
508
|
+
account: options.request.accountAddress,
|
|
509
|
+
accessKey: current.accessKeyAddress,
|
|
510
|
+
token: limit.token,
|
|
511
|
+
});
|
|
512
|
+
if (result.remaining !== limit.limit)
|
|
513
|
+
throw new Error('Access key spending limits do not match the device code request.');
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const authorized = await store.update({
|
|
517
|
+
accountAddress: options.request.accountAddress,
|
|
518
|
+
code,
|
|
519
|
+
...(replacement ? { keyAuthorization: replacement } : {}),
|
|
520
|
+
});
|
|
521
|
+
if (!authorized)
|
|
522
|
+
throw new Error('Unable to complete access key update.');
|
|
523
|
+
return { status: 'authorized' };
|
|
524
|
+
}
|
|
525
|
+
if (options.request.action === 'updateAccessKey')
|
|
526
|
+
throw new Error('Device code action does not match the completion request.');
|
|
342
527
|
const expected = expectedKeyAuthorization(current);
|
|
343
528
|
const actual = normalizeKeyAuthorization(options.request.keyAuthorization);
|
|
344
529
|
if (actual.keyId.toLowerCase() !== expected.address.toLowerCase())
|
|
345
|
-
throw new Error('Key authorization key does not match the device
|
|
530
|
+
throw new Error('Key authorization key does not match the device code request.');
|
|
346
531
|
if (actual.address.toLowerCase() !== expected.address.toLowerCase())
|
|
347
|
-
throw new Error('Key authorization address does not match the device
|
|
532
|
+
throw new Error('Key authorization address does not match the device code request.');
|
|
348
533
|
if (actual.keyType !== expected.type)
|
|
349
|
-
throw new Error('Key authorization key type does not match the device
|
|
534
|
+
throw new Error('Key authorization key type does not match the device code request.');
|
|
350
535
|
if (actual.chainId !== expected.chainId)
|
|
351
|
-
throw new Error('Key authorization chain does not match the device
|
|
536
|
+
throw new Error('Key authorization chain does not match the device code request.');
|
|
352
537
|
const signed = TempoKeyAuthorization.from({
|
|
353
538
|
address: actual.address,
|
|
354
539
|
chainId: actual.chainId,
|
|
@@ -386,17 +571,7 @@ export function from(options = {}) {
|
|
|
386
571
|
},
|
|
387
572
|
async createDeviceCode(options) {
|
|
388
573
|
const nextChainId = options.request.chainId ?? chainId ?? cache.defaultChainId;
|
|
389
|
-
const
|
|
390
|
-
const keyType = options.request.keyType ?? 'secp256k1';
|
|
391
|
-
PublicKey.assert(PublicKey.from(pubKey));
|
|
392
|
-
const approved = await policy.validate({
|
|
393
|
-
...(account ? { account } : {}),
|
|
394
|
-
chainId: typeof nextChainId === 'bigint' ? nextChainId : BigInt(nextChainId),
|
|
395
|
-
expiry: options.request.expiry,
|
|
396
|
-
keyType,
|
|
397
|
-
...(options.request.limits ? { limits: options.request.limits } : {}),
|
|
398
|
-
pubKey,
|
|
399
|
-
});
|
|
574
|
+
const chainId_resolved = typeof nextChainId === 'bigint' ? nextChainId : BigInt(nextChainId);
|
|
400
575
|
let code;
|
|
401
576
|
for (let i = 0; i < 10; i++) {
|
|
402
577
|
const candidate = createCode(random);
|
|
@@ -408,9 +583,65 @@ export function from(options = {}) {
|
|
|
408
583
|
if (!code)
|
|
409
584
|
throw new Error('Unable to allocate device code.');
|
|
410
585
|
const createdAt = now();
|
|
586
|
+
if (options.request.action === 'updateAccessKey') {
|
|
587
|
+
if (!policy.update)
|
|
588
|
+
throw new Error('Access key updates are not supported by this policy.');
|
|
589
|
+
const approved = await policy.update({
|
|
590
|
+
accessKeyAddress: options.request.accessKeyAddress,
|
|
591
|
+
account: options.request.account,
|
|
592
|
+
chainId: chainId_resolved,
|
|
593
|
+
limits: options.request.limits,
|
|
594
|
+
});
|
|
595
|
+
const tokens = new Set();
|
|
596
|
+
for (const limit of approved.limits) {
|
|
597
|
+
const token = limit.token.toLowerCase();
|
|
598
|
+
if (tokens.has(token))
|
|
599
|
+
throw new Error('Access key update limits must use unique tokens.');
|
|
600
|
+
tokens.add(token);
|
|
601
|
+
}
|
|
602
|
+
let pendingKeyAuthorization;
|
|
603
|
+
if (options.request.keyAuthorization) {
|
|
604
|
+
const actual = await verifyKeyAuthorizationSignature({
|
|
605
|
+
account: options.request.account,
|
|
606
|
+
client: options.client ?? cache.get(chainId_resolved),
|
|
607
|
+
keyAuthorization: options.request.keyAuthorization,
|
|
608
|
+
});
|
|
609
|
+
if (actual.address.toLowerCase() !== options.request.accessKeyAddress.toLowerCase() ||
|
|
610
|
+
actual.keyId.toLowerCase() !== options.request.accessKeyAddress.toLowerCase())
|
|
611
|
+
throw new Error('Pending key authorization does not match the access key request.');
|
|
612
|
+
if (actual.chainId !== chainId_resolved)
|
|
613
|
+
throw new Error('Pending key authorization chain does not match the device code request.');
|
|
614
|
+
pendingKeyAuthorization = toStoredKeyAuthorization(options.request.keyAuthorization, actual);
|
|
615
|
+
}
|
|
616
|
+
await store.create({
|
|
617
|
+
action: 'updateAccessKey',
|
|
618
|
+
accessKeyAddress: options.request.accessKeyAddress,
|
|
619
|
+
account: options.request.account,
|
|
620
|
+
chainId: chainId_resolved,
|
|
621
|
+
code,
|
|
622
|
+
codeChallenge: options.request.codeChallenge,
|
|
623
|
+
createdAt,
|
|
624
|
+
expiresAt: createdAt + ttlMs,
|
|
625
|
+
...(pendingKeyAuthorization ? { keyAuthorization: pendingKeyAuthorization } : {}),
|
|
626
|
+
limits: approved.limits,
|
|
627
|
+
status: 'pending',
|
|
628
|
+
});
|
|
629
|
+
return { code };
|
|
630
|
+
}
|
|
631
|
+
const { account, codeChallenge, pubKey } = options.request;
|
|
632
|
+
const keyType = options.request.keyType ?? 'secp256k1';
|
|
633
|
+
PublicKey.assert(PublicKey.from(pubKey));
|
|
634
|
+
const approved = await policy.validate({
|
|
635
|
+
...(account ? { account } : {}),
|
|
636
|
+
chainId: chainId_resolved,
|
|
637
|
+
expiry: options.request.expiry,
|
|
638
|
+
keyType,
|
|
639
|
+
...(options.request.limits ? { limits: options.request.limits } : {}),
|
|
640
|
+
pubKey,
|
|
641
|
+
});
|
|
411
642
|
await store.create({
|
|
412
643
|
...(account ? { account } : {}),
|
|
413
|
-
chainId:
|
|
644
|
+
chainId: chainId_resolved,
|
|
414
645
|
code,
|
|
415
646
|
codeChallenge,
|
|
416
647
|
createdAt,
|
|
@@ -437,6 +668,17 @@ export function from(options = {}) {
|
|
|
437
668
|
}
|
|
438
669
|
if (current.status !== 'pending')
|
|
439
670
|
throw new PendingError('Device code already completed.', 400);
|
|
671
|
+
if (current.action === 'updateAccessKey')
|
|
672
|
+
return {
|
|
673
|
+
action: current.action,
|
|
674
|
+
accessKeyAddress: current.accessKeyAddress,
|
|
675
|
+
account: current.account,
|
|
676
|
+
chainId: current.chainId,
|
|
677
|
+
code: current.code,
|
|
678
|
+
...(current.keyAuthorization ? { keyAuthorization: current.keyAuthorization } : {}),
|
|
679
|
+
limits: current.limits,
|
|
680
|
+
status: current.status,
|
|
681
|
+
};
|
|
440
682
|
return {
|
|
441
683
|
accessKeyAddress: Address.fromPublicKey(PublicKey.from(current.pubKey)),
|
|
442
684
|
...(current.account ? { account: current.account } : {}),
|
|
@@ -470,6 +712,12 @@ export function from(options = {}) {
|
|
|
470
712
|
const authorized = await store.consume(normalized);
|
|
471
713
|
if (!authorized)
|
|
472
714
|
return { status: 'expired' };
|
|
715
|
+
if (authorized.action === 'updateAccessKey')
|
|
716
|
+
return {
|
|
717
|
+
action: authorized.action,
|
|
718
|
+
...(authorized.keyAuthorization ? { keyAuthorization: authorized.keyAuthorization } : {}),
|
|
719
|
+
status: 'authorized',
|
|
720
|
+
};
|
|
473
721
|
return {
|
|
474
722
|
accountAddress: authorized.accountAddress,
|
|
475
723
|
keyAuthorization: authorized.keyAuthorization,
|
|
@@ -502,14 +750,17 @@ export function from(options = {}) {
|
|
|
502
750
|
* ```
|
|
503
751
|
*/
|
|
504
752
|
export async function createDeviceCode(options) {
|
|
505
|
-
const { request, ...rest } = options;
|
|
506
|
-
return from(rest).createDeviceCode({
|
|
753
|
+
const { client, request, ...rest } = options;
|
|
754
|
+
return from(rest).createDeviceCode({
|
|
755
|
+
...(client ? { client } : {}),
|
|
756
|
+
request,
|
|
757
|
+
});
|
|
507
758
|
}
|
|
508
759
|
/**
|
|
509
760
|
* Looks up a pending device code for browser approval UIs.
|
|
510
761
|
*
|
|
511
762
|
* @param {pending.Options} options - Shared defaults plus the pending lookup parameters.
|
|
512
|
-
* @returns {Promise<pending.ReturnType>} Pending device
|
|
763
|
+
* @returns {Promise<pending.ReturnType>} Pending device code payload.
|
|
513
764
|
*
|
|
514
765
|
* @example
|
|
515
766
|
* ```ts
|
|
@@ -657,6 +908,48 @@ function normalizeKeyAuthorization(value) {
|
|
|
657
908
|
};
|
|
658
909
|
}
|
|
659
910
|
/** @internal */
|
|
911
|
+
async function verifyKeyAuthorizationSignature(options) {
|
|
912
|
+
const actual = normalizeKeyAuthorization(options.keyAuthorization);
|
|
913
|
+
const unsigned = TempoKeyAuthorization.from({
|
|
914
|
+
address: actual.address,
|
|
915
|
+
chainId: actual.chainId,
|
|
916
|
+
expiry: actual.expiry,
|
|
917
|
+
...(actual.limits ? { limits: actual.limits } : {}),
|
|
918
|
+
type: actual.keyType,
|
|
919
|
+
});
|
|
920
|
+
const valid = await verifyHash(options.client, {
|
|
921
|
+
address: options.account,
|
|
922
|
+
hash: TempoKeyAuthorization.getSignPayload(unsigned),
|
|
923
|
+
signature: SignatureEnvelope.serialize(SignatureEnvelope.fromRpc(actual.signature), {
|
|
924
|
+
magic: actual.signature.type === 'webAuthn',
|
|
925
|
+
}),
|
|
926
|
+
});
|
|
927
|
+
if (!valid)
|
|
928
|
+
throw new Error('Key authorization signature is invalid.');
|
|
929
|
+
return actual;
|
|
930
|
+
}
|
|
931
|
+
/** @internal */
|
|
932
|
+
function toStoredKeyAuthorization(value, normalized = normalizeKeyAuthorization(value)) {
|
|
933
|
+
return {
|
|
934
|
+
address: value.address,
|
|
935
|
+
chainId: value.chainId,
|
|
936
|
+
expiry: normalized.expiry,
|
|
937
|
+
keyId: value.keyId,
|
|
938
|
+
keyType: value.keyType,
|
|
939
|
+
...(normalized.limits ? { limits: normalized.limits } : {}),
|
|
940
|
+
signature: value.signature,
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
/** @internal */
|
|
944
|
+
function sameLimits(actual, expected) {
|
|
945
|
+
if (!actual || actual.length !== expected.length)
|
|
946
|
+
return false;
|
|
947
|
+
const normalize = (items) => items.map((item) => `${item.token.toLowerCase()}:${item.limit}`).sort();
|
|
948
|
+
const actualNormalized = normalize(actual);
|
|
949
|
+
const expectedNormalized = normalize(expected);
|
|
950
|
+
return actualNormalized.every((value, index) => value === expectedNormalized[index]);
|
|
951
|
+
}
|
|
952
|
+
/** @internal */
|
|
660
953
|
async function verifyCodeChallenge(codeVerifier, codeChallenge) {
|
|
661
954
|
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
|
|
662
955
|
return Base64.fromBytes(new Uint8Array(hash), { pad: false, url: true }) === codeChallenge;
|