accounts 0.4.4 → 0.4.6
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 +13 -0
- package/dist/cli/adapter.d.ts +0 -2
- package/dist/cli/adapter.d.ts.map +1 -1
- package/dist/cli/adapter.js +96 -72
- package/dist/cli/adapter.js.map +1 -1
- package/dist/core/Adapter.d.ts +6 -3
- package/dist/core/Adapter.d.ts.map +1 -1
- package/dist/core/Provider.d.ts.map +1 -1
- package/dist/core/Provider.js +14 -9
- package/dist/core/Provider.js.map +1 -1
- package/dist/core/Schema.d.ts +29 -23
- package/dist/core/Schema.d.ts.map +1 -1
- package/dist/core/adapters/dialog.d.ts.map +1 -1
- package/dist/core/adapters/dialog.js +15 -4
- package/dist/core/adapters/dialog.js.map +1 -1
- package/dist/core/adapters/local.d.ts.map +1 -1
- package/dist/core/adapters/local.js +4 -1
- package/dist/core/adapters/local.js.map +1 -1
- package/dist/core/zod/rpc.d.ts +17 -14
- package/dist/core/zod/rpc.d.ts.map +1 -1
- package/dist/core/zod/rpc.js +6 -2
- package/dist/core/zod/rpc.js.map +1 -1
- package/dist/server/CliAuth.d.ts +1 -0
- package/dist/server/CliAuth.d.ts.map +1 -1
- package/dist/server/CliAuth.js +3 -1
- package/dist/server/CliAuth.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/Provider.test.ts +173 -12
- package/src/cli/adapter.ts +112 -80
- package/src/core/Adapter.ts +6 -3
- package/src/core/Provider.browser.test.ts +8 -7
- package/src/core/Provider.connect.browser.test.ts +3 -3
- package/src/core/Provider.test.ts +24 -10
- package/src/core/Provider.ts +12 -7
- package/src/core/Schema.test-d.ts +5 -12
- package/src/core/adapters/dialog.ts +20 -4
- package/src/core/adapters/local.ts +5 -2
- package/src/core/zod/rpc.ts +7 -2
- package/src/server/CliAuth.ts +2 -1
package/src/cli/Provider.test.ts
CHANGED
|
@@ -11,17 +11,27 @@ import * as Provider from './Provider.js'
|
|
|
11
11
|
|
|
12
12
|
const root = accounts[0]!
|
|
13
13
|
const accessKey = accounts[1]!
|
|
14
|
+
const accessKey_2 = accounts[2]!
|
|
14
15
|
const expiry = Math.floor(Date.now() / 1000) + 3_600
|
|
16
|
+
const expiry_2 = expiry + 60
|
|
17
|
+
|
|
18
|
+
async function authorize(
|
|
19
|
+
code: string,
|
|
20
|
+
options: {
|
|
21
|
+
accessKey?: typeof accessKey | undefined
|
|
22
|
+
expiry?: number | undefined
|
|
23
|
+
} = {},
|
|
24
|
+
) {
|
|
25
|
+
const { accessKey: key = accessKey, expiry: expiry_ = expiry } = options
|
|
15
26
|
|
|
16
|
-
async function authorize(code: string) {
|
|
17
27
|
const signed = await root.signKeyAuthorization(
|
|
18
28
|
{
|
|
19
|
-
accessKeyAddress:
|
|
20
|
-
keyType:
|
|
29
|
+
accessKeyAddress: key.address,
|
|
30
|
+
keyType: key.keyType,
|
|
21
31
|
},
|
|
22
32
|
{
|
|
23
33
|
chainId: BigInt(chain.id),
|
|
24
|
-
expiry,
|
|
34
|
+
expiry: expiry_,
|
|
25
35
|
},
|
|
26
36
|
)
|
|
27
37
|
const keyAuthorization = KeyAuthorization.toRpc(signed)
|
|
@@ -36,15 +46,23 @@ async function authorize(code: string) {
|
|
|
36
46
|
})
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
function connectRequest(
|
|
49
|
+
function connectRequest(
|
|
50
|
+
options: {
|
|
51
|
+
accessKey?: typeof accessKey | undefined
|
|
52
|
+
expiry?: number | undefined
|
|
53
|
+
} = {},
|
|
54
|
+
) {
|
|
55
|
+
const { accessKey: key = accessKey, expiry: expiry_ = expiry } = options
|
|
56
|
+
|
|
40
57
|
return {
|
|
41
58
|
method: 'wallet_connect',
|
|
42
59
|
params: [
|
|
43
60
|
{
|
|
44
61
|
capabilities: {
|
|
45
62
|
authorizeAccessKey: {
|
|
46
|
-
expiry,
|
|
47
|
-
|
|
63
|
+
expiry: expiry_,
|
|
64
|
+
keyType: key.keyType,
|
|
65
|
+
publicKey: key.publicKey,
|
|
48
66
|
},
|
|
49
67
|
},
|
|
50
68
|
},
|
|
@@ -53,6 +71,8 @@ function connectRequest() {
|
|
|
53
71
|
}
|
|
54
72
|
|
|
55
73
|
function createHandler() {
|
|
74
|
+
let random = 0
|
|
75
|
+
|
|
56
76
|
return Handler.codeAuth({
|
|
57
77
|
path: '/cli-auth',
|
|
58
78
|
chainId: chain.id,
|
|
@@ -65,7 +85,11 @@ function createHandler() {
|
|
|
65
85
|
}
|
|
66
86
|
},
|
|
67
87
|
},
|
|
68
|
-
random: () =>
|
|
88
|
+
random: () => {
|
|
89
|
+
const out = new Uint8Array(Array.from({ length: 8 }, (_, i) => random + i))
|
|
90
|
+
random += 8
|
|
91
|
+
return out
|
|
92
|
+
},
|
|
69
93
|
})
|
|
70
94
|
}
|
|
71
95
|
|
|
@@ -77,6 +101,7 @@ describe('Provider.create', () => {
|
|
|
77
101
|
|
|
78
102
|
try {
|
|
79
103
|
const provider = Provider.create({
|
|
104
|
+
chains: [chain],
|
|
80
105
|
open: async (url) => {
|
|
81
106
|
opened.push(url)
|
|
82
107
|
const code = new URL(url).searchParams.get('code')!
|
|
@@ -139,6 +164,7 @@ describe('Provider.create', () => {
|
|
|
139
164
|
|
|
140
165
|
try {
|
|
141
166
|
const provider = Provider.create({
|
|
167
|
+
chains: [chain],
|
|
142
168
|
open() {
|
|
143
169
|
throw new Error('browser unavailable')
|
|
144
170
|
},
|
|
@@ -173,6 +199,7 @@ describe('Provider.create', () => {
|
|
|
173
199
|
|
|
174
200
|
try {
|
|
175
201
|
const provider = Provider.create({
|
|
202
|
+
chains: [chain],
|
|
176
203
|
open() {},
|
|
177
204
|
pollIntervalMs: 1,
|
|
178
205
|
host: `${server.url}/cli-auth`,
|
|
@@ -201,12 +228,146 @@ describe('Provider.create', () => {
|
|
|
201
228
|
}
|
|
202
229
|
})
|
|
203
230
|
|
|
204
|
-
test('behavior:
|
|
231
|
+
test('behavior: authorizes an access key while disconnected when publicKey is provided', async () => {
|
|
232
|
+
const handler = createHandler()
|
|
233
|
+
const server = await createServer(handler.listener)
|
|
234
|
+
const opened: string[] = []
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
const provider = Provider.create({
|
|
238
|
+
chains: [chain],
|
|
239
|
+
open: async (url) => {
|
|
240
|
+
opened.push(url)
|
|
241
|
+
const code = new URL(url).searchParams.get('code')!
|
|
242
|
+
try {
|
|
243
|
+
await fetch(`${server.url}/cli-auth`, {
|
|
244
|
+
body: JSON.stringify(
|
|
245
|
+
await authorize(code, { accessKey: accessKey_2, expiry: expiry_2 }),
|
|
246
|
+
),
|
|
247
|
+
headers: { 'content-type': 'application/json' },
|
|
248
|
+
method: 'POST',
|
|
249
|
+
})
|
|
250
|
+
} catch (error) {}
|
|
251
|
+
},
|
|
252
|
+
host: `${server.url}/cli-auth`,
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
const result = await provider.request({
|
|
256
|
+
method: 'wallet_authorizeAccessKey',
|
|
257
|
+
params: [
|
|
258
|
+
{ expiry: expiry_2, keyType: accessKey_2.keyType, publicKey: accessKey_2.publicKey },
|
|
259
|
+
],
|
|
260
|
+
})
|
|
261
|
+
const keyAuthorization = {
|
|
262
|
+
...result.keyAuthorization,
|
|
263
|
+
signature: {
|
|
264
|
+
type: result.keyAuthorization.signature.type,
|
|
265
|
+
},
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
expect({
|
|
269
|
+
keyAuthorization,
|
|
270
|
+
rootAddress: result.rootAddress,
|
|
271
|
+
opened: opened.map((url) => url.replace(server.url, 'http://service')),
|
|
272
|
+
}).toMatchInlineSnapshot(`
|
|
273
|
+
{
|
|
274
|
+
"keyAuthorization": {
|
|
275
|
+
"address": "${accessKey_2.address}",
|
|
276
|
+
"chainId": "${Hex.fromNumber(chain.id)}",
|
|
277
|
+
"expiry": "${Hex.fromNumber(expiry_2)}",
|
|
278
|
+
"keyId": "${accessKey_2.address}",
|
|
279
|
+
"keyType": "secp256k1",
|
|
280
|
+
"signature": {
|
|
281
|
+
"type": "secp256k1",
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
"opened": [
|
|
285
|
+
"http://service/cli-auth?code=ABCDEFGH",
|
|
286
|
+
],
|
|
287
|
+
"rootAddress": "${root.address}",
|
|
288
|
+
}
|
|
289
|
+
`)
|
|
290
|
+
} finally {
|
|
291
|
+
await server.closeAsync()
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
test('behavior: authorizes an access key for the active account', async () => {
|
|
296
|
+
const handler = createHandler()
|
|
297
|
+
const server = await createServer(handler.listener)
|
|
298
|
+
const opened: string[] = []
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
const approvals = [
|
|
302
|
+
(code: string) => authorize(code),
|
|
303
|
+
(code: string) => authorize(code, { accessKey: accessKey_2, expiry: expiry_2 }),
|
|
304
|
+
]
|
|
305
|
+
const provider = Provider.create({
|
|
306
|
+
chains: [chain],
|
|
307
|
+
open: async (url) => {
|
|
308
|
+
opened.push(url)
|
|
309
|
+
const approve = approvals.shift()
|
|
310
|
+
if (!approve) throw new Error('Unexpected device-code approval request.')
|
|
311
|
+
const code = new URL(url).searchParams.get('code')!
|
|
312
|
+
await fetch(`${server.url}/cli-auth`, {
|
|
313
|
+
body: JSON.stringify(await approve(code)),
|
|
314
|
+
headers: { 'content-type': 'application/json' },
|
|
315
|
+
method: 'POST',
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
host: `${server.url}/cli-auth`,
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
await provider.request(connectRequest())
|
|
322
|
+
|
|
323
|
+
const result = await provider.request({
|
|
324
|
+
method: 'wallet_authorizeAccessKey',
|
|
325
|
+
params: [
|
|
326
|
+
{ expiry: expiry_2, keyType: accessKey_2.keyType, publicKey: accessKey_2.publicKey },
|
|
327
|
+
],
|
|
328
|
+
})
|
|
329
|
+
const keyAuthorization = {
|
|
330
|
+
...result.keyAuthorization,
|
|
331
|
+
signature: {
|
|
332
|
+
type: result.keyAuthorization.signature.type,
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
expect({
|
|
337
|
+
keyAuthorization,
|
|
338
|
+
rootAddress: result.rootAddress,
|
|
339
|
+
opened: opened.map((url) => url.replace(server.url, 'http://service')),
|
|
340
|
+
}).toMatchInlineSnapshot(`
|
|
341
|
+
{
|
|
342
|
+
"keyAuthorization": {
|
|
343
|
+
"address": "${accessKey_2.address}",
|
|
344
|
+
"chainId": "${Hex.fromNumber(chain.id)}",
|
|
345
|
+
"expiry": "${Hex.fromNumber(expiry_2)}",
|
|
346
|
+
"keyId": "${accessKey_2.address}",
|
|
347
|
+
"keyType": "secp256k1",
|
|
348
|
+
"signature": {
|
|
349
|
+
"type": "secp256k1",
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
"opened": [
|
|
353
|
+
"http://service/cli-auth?code=ABCDEFGH",
|
|
354
|
+
"http://service/cli-auth?code=JKLMNPQR",
|
|
355
|
+
],
|
|
356
|
+
"rootAddress": "${root.address}",
|
|
357
|
+
}
|
|
358
|
+
`)
|
|
359
|
+
} finally {
|
|
360
|
+
await server.closeAsync()
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
test('behavior: rejects unsupported revokeAccessKey after bootstrap', async () => {
|
|
205
365
|
const handler = createHandler()
|
|
206
366
|
const server = await createServer(handler.listener)
|
|
207
367
|
|
|
208
368
|
try {
|
|
209
369
|
const provider = Provider.create({
|
|
370
|
+
chains: [chain],
|
|
210
371
|
open: async (url) => {
|
|
211
372
|
const code = new URL(url).searchParams.get('code')!
|
|
212
373
|
await fetch(`${server.url}/cli-auth`, {
|
|
@@ -222,11 +383,11 @@ describe('Provider.create', () => {
|
|
|
222
383
|
|
|
223
384
|
await expect(
|
|
224
385
|
provider.request({
|
|
225
|
-
method: '
|
|
226
|
-
params: [{
|
|
386
|
+
method: 'wallet_revokeAccessKey',
|
|
387
|
+
params: [{ accessKeyAddress: accessKey.address, address: root.address }],
|
|
227
388
|
}),
|
|
228
389
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
229
|
-
`[Provider.UnsupportedMethodError: \`
|
|
390
|
+
`[Provider.UnsupportedMethodError: \`wallet_revokeAccessKey\` not supported by CLI adapter.]`,
|
|
230
391
|
)
|
|
231
392
|
} finally {
|
|
232
393
|
await server.closeAsync()
|
package/src/cli/adapter.ts
CHANGED
|
@@ -8,76 +8,110 @@ import * as CliAuth from '../server/CliAuth.js'
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Creates a CLI bootstrap adapter backed by the device-code protocol.
|
|
11
|
-
*
|
|
12
|
-
* Only `wallet_connect` is supported in v1.
|
|
13
11
|
*/
|
|
14
12
|
export function cli(options: cli.Options): Adapter.Adapter {
|
|
15
13
|
const { name = 'Tempo CLI', rdns = 'xyz.tempo.cli' } = options
|
|
16
14
|
|
|
17
|
-
return Adapter.define({ name, rdns }, () =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
15
|
+
return Adapter.define({ name, rdns }, ({ store }) => {
|
|
16
|
+
async function authorize(request: {
|
|
17
|
+
account?: Adapter.authorizeAccessKey.ReturnType['rootAddress'] | undefined
|
|
18
|
+
authorizeAccessKey: Adapter.authorizeAccessKey.Parameters | undefined
|
|
19
|
+
method: 'wallet_authorizeAccessKey' | 'wallet_connect'
|
|
20
|
+
}) {
|
|
21
|
+
const {
|
|
22
|
+
host,
|
|
23
|
+
open = defaultOpen,
|
|
24
|
+
pollIntervalMs = 2_000,
|
|
25
|
+
timeoutMs = 5 * 60 * 1_000,
|
|
26
|
+
} = options
|
|
27
|
+
const { account, authorizeAccessKey, method } = request
|
|
28
|
+
|
|
29
|
+
if (!authorizeAccessKey?.publicKey)
|
|
30
|
+
throw new RpcResponse.InvalidParamsError({
|
|
31
|
+
message:
|
|
32
|
+
method === 'wallet_connect'
|
|
33
|
+
? '`wallet_connect` on the CLI adapter requires `capabilities.authorizeAccessKey.publicKey`.'
|
|
34
|
+
: '`wallet_authorizeAccessKey` on the CLI adapter requires `publicKey`.',
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const codeVerifier = createCodeVerifier()
|
|
38
|
+
const codeChallenge = createCodeChallenge(codeVerifier)
|
|
39
|
+
const created = await post({
|
|
40
|
+
body: {
|
|
41
|
+
...(account ? { account } : {}),
|
|
42
|
+
chainId: BigInt(store.getState().chainId),
|
|
43
|
+
codeChallenge,
|
|
44
|
+
...(typeof authorizeAccessKey.expiry !== 'undefined'
|
|
45
|
+
? { expiry: authorizeAccessKey.expiry }
|
|
46
|
+
: {}),
|
|
47
|
+
...(authorizeAccessKey.keyType ? { keyType: authorizeAccessKey.keyType } : {}),
|
|
48
|
+
...(authorizeAccessKey.limits ? { limits: authorizeAccessKey.limits } : {}),
|
|
49
|
+
pubKey: authorizeAccessKey.publicKey,
|
|
50
|
+
} satisfies z.output<typeof CliAuth.createRequest>,
|
|
51
|
+
request: CliAuth.createRequest,
|
|
52
|
+
response: CliAuth.createResponse,
|
|
53
|
+
url: getApiUrl(host, 'code'),
|
|
54
|
+
})
|
|
55
|
+
const url = getBrowserUrl(host, created.code)
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await open(url)
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new OpenError(url, created.code, error)
|
|
61
|
+
}
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
const startedAt = Date.now()
|
|
64
|
+
|
|
65
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
66
|
+
const result = await post({
|
|
42
67
|
body: {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
...(authorizeAccessKey.limits ? { limits: authorizeAccessKey.limits } : {}),
|
|
49
|
-
pubKey: authorizeAccessKey.publicKey,
|
|
50
|
-
} satisfies z.output<typeof CliAuth.createRequest>,
|
|
51
|
-
request: CliAuth.createRequest,
|
|
52
|
-
response: CliAuth.createResponse,
|
|
53
|
-
url: getApiUrl(host, 'code'),
|
|
68
|
+
codeVerifier,
|
|
69
|
+
} satisfies z.output<typeof CliAuth.pollRequest>,
|
|
70
|
+
request: CliAuth.pollRequest,
|
|
71
|
+
response: CliAuth.pollResponse,
|
|
72
|
+
url: getApiUrl(host, `poll/${created.code}`),
|
|
54
73
|
})
|
|
55
|
-
const url = getBrowserUrl(host, created.code)
|
|
56
74
|
|
|
57
|
-
|
|
58
|
-
await
|
|
59
|
-
|
|
60
|
-
throw new OpenError(url, created.code, error)
|
|
75
|
+
if (result.status === 'pending') {
|
|
76
|
+
await sleep(pollIntervalMs)
|
|
77
|
+
continue
|
|
61
78
|
}
|
|
79
|
+
if (result.status === 'expired')
|
|
80
|
+
throw new Error('Device code expired before authorization completed.')
|
|
81
|
+
|
|
82
|
+
return result
|
|
83
|
+
}
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
throw new TimeoutError(url, created.code)
|
|
86
|
+
}
|
|
64
87
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
return {
|
|
89
|
+
actions: {
|
|
90
|
+
async authorizeAccessKey(parameters) {
|
|
91
|
+
const { accounts, activeAccount } = store.getState()
|
|
92
|
+
const account = accounts[activeAccount]?.address
|
|
93
|
+
const result = await authorize({
|
|
94
|
+
...(account ? { account } : {}),
|
|
95
|
+
authorizeAccessKey: parameters,
|
|
96
|
+
method: 'wallet_authorizeAccessKey',
|
|
73
97
|
})
|
|
74
98
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
99
|
+
return {
|
|
100
|
+
keyAuthorization: z.encode(CliAuth.keyAuthorization, result.keyAuthorization),
|
|
101
|
+
rootAddress: result.accountAddress,
|
|
78
102
|
}
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
},
|
|
104
|
+
async createAccount(params, request) {
|
|
105
|
+
return this.loadAccounts(params, request)
|
|
106
|
+
},
|
|
107
|
+
async loadAccounts(parameters) {
|
|
108
|
+
if (parameters?.digest)
|
|
109
|
+
throw unsupported('`wallet_connect` digest signing not supported by CLI adapter.')
|
|
110
|
+
|
|
111
|
+
const result = await authorize({
|
|
112
|
+
authorizeAccessKey: parameters?.authorizeAccessKey,
|
|
113
|
+
method: 'wallet_connect',
|
|
114
|
+
})
|
|
81
115
|
|
|
82
116
|
return {
|
|
83
117
|
accounts: [
|
|
@@ -88,30 +122,28 @@ export function cli(options: cli.Options): Adapter.Adapter {
|
|
|
88
122
|
],
|
|
89
123
|
keyAuthorization: z.encode(CliAuth.keyAuthorization, result.keyAuthorization),
|
|
90
124
|
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
125
|
+
},
|
|
126
|
+
async revokeAccessKey() {
|
|
127
|
+
throw unsupported('`wallet_revokeAccessKey` not supported by CLI adapter.')
|
|
128
|
+
},
|
|
129
|
+
async sendTransaction() {
|
|
130
|
+
throw unsupported('`eth_sendTransaction` not supported by CLI adapter.')
|
|
131
|
+
},
|
|
132
|
+
async sendTransactionSync() {
|
|
133
|
+
throw unsupported('`eth_sendTransactionSync` not supported by CLI adapter.')
|
|
134
|
+
},
|
|
135
|
+
async signPersonalMessage() {
|
|
136
|
+
throw unsupported('`personal_sign` not supported by CLI adapter.')
|
|
137
|
+
},
|
|
138
|
+
async signTransaction() {
|
|
139
|
+
throw unsupported('`eth_signTransaction` not supported by CLI adapter.')
|
|
140
|
+
},
|
|
141
|
+
async signTypedData() {
|
|
142
|
+
throw unsupported('`eth_signTypedData_v4` not supported by CLI adapter.')
|
|
143
|
+
},
|
|
100
144
|
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
},
|
|
104
|
-
async signPersonalMessage() {
|
|
105
|
-
throw unsupported('`personal_sign` not supported by CLI adapter.')
|
|
106
|
-
},
|
|
107
|
-
async signTransaction() {
|
|
108
|
-
throw unsupported('`eth_signTransaction` not supported by CLI adapter.')
|
|
109
|
-
},
|
|
110
|
-
async signTypedData() {
|
|
111
|
-
throw unsupported('`eth_signTypedData_v4` not supported by CLI adapter.')
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
}))
|
|
145
|
+
}
|
|
146
|
+
})
|
|
115
147
|
}
|
|
116
148
|
|
|
117
149
|
export declare namespace cli {
|
|
@@ -133,7 +165,7 @@ export declare namespace cli {
|
|
|
133
165
|
|
|
134
166
|
class OpenError extends Error {
|
|
135
167
|
code: string
|
|
136
|
-
cause?: unknown | undefined
|
|
168
|
+
override cause?: unknown | undefined
|
|
137
169
|
url: string
|
|
138
170
|
|
|
139
171
|
constructor(url: string, code: string, cause?: unknown) {
|
package/src/core/Adapter.ts
CHANGED
|
@@ -145,7 +145,7 @@ export declare namespace createAccount {
|
|
|
145
145
|
type ReturnType = {
|
|
146
146
|
accounts: readonly Store.Account[]
|
|
147
147
|
/** Signed key authorization, if an access key was granted. */
|
|
148
|
-
keyAuthorization?:
|
|
148
|
+
keyAuthorization?: KeyAuthorization.Rpc | undefined
|
|
149
149
|
/** Signature over the digest, if one was provided. */
|
|
150
150
|
signature?: Hex | undefined
|
|
151
151
|
}
|
|
@@ -166,7 +166,7 @@ export declare namespace loadAccounts {
|
|
|
166
166
|
/** Loaded accounts. */
|
|
167
167
|
accounts: readonly Store.Account[]
|
|
168
168
|
/** Signed key authorization, if an access key was granted. */
|
|
169
|
-
keyAuthorization?:
|
|
169
|
+
keyAuthorization?: KeyAuthorization.Rpc | undefined
|
|
170
170
|
/** Signature over the digest, if one was provided. */
|
|
171
171
|
signature?: Hex | undefined
|
|
172
172
|
}
|
|
@@ -206,7 +206,10 @@ export declare namespace authorizeAccessKey {
|
|
|
206
206
|
signature?: Hex | undefined
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
type ReturnType =
|
|
209
|
+
type ReturnType = {
|
|
210
|
+
keyAuthorization: KeyAuthorization.Rpc
|
|
211
|
+
rootAddress: Address
|
|
212
|
+
}
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
export declare namespace revokeAccessKey {
|
|
@@ -521,13 +521,14 @@ describe('eth_signTypedData_v4', () => {
|
|
|
521
521
|
describe('wallet_authorizeAccessKey', () => {
|
|
522
522
|
test('default: grants an access key and returns its address', async () => {
|
|
523
523
|
const provider = getProvider({ chains: [chain] })
|
|
524
|
-
await connect(provider)
|
|
524
|
+
const rootAddress = await connect(provider)
|
|
525
525
|
|
|
526
526
|
const result = await provider.request({
|
|
527
527
|
method: 'wallet_authorizeAccessKey',
|
|
528
528
|
params: [{ expiry: Expiry.days(1) }],
|
|
529
529
|
})
|
|
530
|
-
expect(result.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
530
|
+
expect(result.keyAuthorization.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
531
|
+
expect(result.rootAddress).toBe(rootAddress)
|
|
531
532
|
})
|
|
532
533
|
|
|
533
534
|
test('behavior: granted access key is used for sendTransactionSync', async () => {
|
|
@@ -556,8 +557,8 @@ describe('wallet_authorizeAccessKey', () => {
|
|
|
556
557
|
method: 'wallet_authorizeAccessKey',
|
|
557
558
|
params: [{ expiry }],
|
|
558
559
|
})
|
|
559
|
-
expect(result.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
560
|
-
expect(result.expiry).toBe(Hex.fromNumber(expiry))
|
|
560
|
+
expect(result.keyAuthorization.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
561
|
+
expect(result.keyAuthorization.expiry).toBe(Hex.fromNumber(expiry))
|
|
561
562
|
})
|
|
562
563
|
|
|
563
564
|
test('behavior: with limits option', async () => {
|
|
@@ -574,7 +575,7 @@ describe('wallet_authorizeAccessKey', () => {
|
|
|
574
575
|
},
|
|
575
576
|
],
|
|
576
577
|
})
|
|
577
|
-
expect(result.limits).toMatchInlineSnapshot(`
|
|
578
|
+
expect(result.keyAuthorization.limits).toMatchInlineSnapshot(`
|
|
578
579
|
[
|
|
579
580
|
{
|
|
580
581
|
"limit": "0x4c4b40",
|
|
@@ -597,14 +598,14 @@ describe('wallet_revokeAccessKey', () => {
|
|
|
597
598
|
await connect(provider)
|
|
598
599
|
|
|
599
600
|
const connected = (await provider.request({ method: 'eth_accounts' }))[0]!
|
|
600
|
-
const {
|
|
601
|
+
const { keyAuthorization } = await provider.request({
|
|
601
602
|
method: 'wallet_authorizeAccessKey',
|
|
602
603
|
params: [{ expiry: Expiry.days(1) }],
|
|
603
604
|
})
|
|
604
605
|
|
|
605
606
|
await provider.request({
|
|
606
607
|
method: 'wallet_revokeAccessKey',
|
|
607
|
-
params: [{ address: connected, accessKeyAddress:
|
|
608
|
+
params: [{ address: connected, accessKeyAddress: keyAuthorization.keyId }],
|
|
608
609
|
})
|
|
609
610
|
|
|
610
611
|
await fundAccount(connected)
|
|
@@ -309,7 +309,7 @@ describe('wallet_authorizeAccessKey', () => {
|
|
|
309
309
|
await iframe.getByTestId('confirm').click()
|
|
310
310
|
},
|
|
311
311
|
)
|
|
312
|
-
expect(result.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
312
|
+
expect(result.keyAuthorization.address).toMatch(/^0x[0-9a-fA-F]{40}$/)
|
|
313
313
|
})
|
|
314
314
|
})
|
|
315
315
|
|
|
@@ -318,7 +318,7 @@ describe('wallet_revokeAccessKey', () => {
|
|
|
318
318
|
provider = getProvider()
|
|
319
319
|
const address = await connectViaIframe(provider)
|
|
320
320
|
|
|
321
|
-
const {
|
|
321
|
+
const { keyAuthorization } = await interact(
|
|
322
322
|
provider.request({
|
|
323
323
|
method: 'wallet_authorizeAccessKey',
|
|
324
324
|
params: [{ expiry: Expiry.days(1) }],
|
|
@@ -331,7 +331,7 @@ describe('wallet_revokeAccessKey', () => {
|
|
|
331
331
|
await interact(
|
|
332
332
|
provider.request({
|
|
333
333
|
method: 'wallet_revokeAccessKey',
|
|
334
|
-
params: [{ address, accessKeyAddress:
|
|
334
|
+
params: [{ address, accessKeyAddress: keyAuthorization.keyId }],
|
|
335
335
|
}),
|
|
336
336
|
async (iframe) => {
|
|
337
337
|
await iframe.getByTestId('confirm').click()
|