tempo.ts 0.7.5 → 0.8.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.
Files changed (147) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/chains.d.ts +6 -20
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/chains.js +14 -15
  5. package/dist/chains.js.map +1 -1
  6. package/dist/ox/KeyAuthorization.d.ts +356 -0
  7. package/dist/ox/KeyAuthorization.d.ts.map +1 -0
  8. package/dist/ox/KeyAuthorization.js +360 -0
  9. package/dist/ox/KeyAuthorization.js.map +1 -0
  10. package/dist/ox/SignatureEnvelope.d.ts +21 -6
  11. package/dist/ox/SignatureEnvelope.d.ts.map +1 -1
  12. package/dist/ox/SignatureEnvelope.js +43 -3
  13. package/dist/ox/SignatureEnvelope.js.map +1 -1
  14. package/dist/ox/Transaction.d.ts +5 -1
  15. package/dist/ox/Transaction.d.ts.map +1 -1
  16. package/dist/ox/Transaction.js +5 -0
  17. package/dist/ox/Transaction.js.map +1 -1
  18. package/dist/ox/TransactionEnvelopeAA.d.ts +9 -0
  19. package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -1
  20. package/dist/ox/TransactionEnvelopeAA.js +17 -4
  21. package/dist/ox/TransactionEnvelopeAA.js.map +1 -1
  22. package/dist/ox/TransactionRequest.d.ts +7 -1
  23. package/dist/ox/TransactionRequest.d.ts.map +1 -1
  24. package/dist/ox/TransactionRequest.js +12 -0
  25. package/dist/ox/TransactionRequest.js.map +1 -1
  26. package/dist/ox/index.d.ts +1 -0
  27. package/dist/ox/index.d.ts.map +1 -1
  28. package/dist/ox/index.js +1 -0
  29. package/dist/ox/index.js.map +1 -1
  30. package/dist/prool/Instance.js +1 -1
  31. package/dist/prool/Instance.js.map +1 -1
  32. package/{src/prool/internal → dist/prool}/chain.json +4 -2
  33. package/dist/viem/Abis.d.ts +319 -6
  34. package/dist/viem/Abis.d.ts.map +1 -1
  35. package/dist/viem/Abis.js +199 -7
  36. package/dist/viem/Abis.js.map +1 -1
  37. package/dist/viem/Account.d.ts +103 -14
  38. package/dist/viem/Account.d.ts.map +1 -1
  39. package/dist/viem/Account.js +177 -23
  40. package/dist/viem/Account.js.map +1 -1
  41. package/dist/viem/Actions/account.d.ts.map +1 -1
  42. package/dist/viem/Actions/account.js +4 -5
  43. package/dist/viem/Actions/account.js.map +1 -1
  44. package/dist/viem/Actions/amm.d.ts +84 -32
  45. package/dist/viem/Actions/amm.d.ts.map +1 -1
  46. package/dist/viem/Actions/amm.js +12 -32
  47. package/dist/viem/Actions/amm.js.map +1 -1
  48. package/dist/viem/Actions/dex.d.ts +156 -4
  49. package/dist/viem/Actions/dex.d.ts.map +1 -1
  50. package/dist/viem/Actions/fee.d.ts +4 -0
  51. package/dist/viem/Actions/fee.d.ts.map +1 -1
  52. package/dist/viem/Actions/reward.d.ts +78 -0
  53. package/dist/viem/Actions/reward.d.ts.map +1 -1
  54. package/dist/viem/Actions/token.d.ts +585 -0
  55. package/dist/viem/Actions/token.d.ts.map +1 -1
  56. package/dist/viem/Actions/token.js +2 -2
  57. package/dist/viem/Actions/token.js.map +1 -1
  58. package/dist/viem/Addresses.d.ts +1 -1
  59. package/dist/viem/Addresses.d.ts.map +1 -1
  60. package/dist/viem/Addresses.js +1 -1
  61. package/dist/viem/Addresses.js.map +1 -1
  62. package/dist/viem/Chain.d.ts +35 -0
  63. package/dist/viem/Chain.d.ts.map +1 -1
  64. package/dist/viem/Chain.js +37 -0
  65. package/dist/viem/Chain.js.map +1 -1
  66. package/dist/viem/Decorator.d.ts +193 -16
  67. package/dist/viem/Decorator.d.ts.map +1 -1
  68. package/dist/viem/Decorator.js +7 -0
  69. package/dist/viem/Decorator.js.map +1 -1
  70. package/dist/viem/Formatters.d.ts.map +1 -1
  71. package/dist/viem/Formatters.js +8 -7
  72. package/dist/viem/Formatters.js.map +1 -1
  73. package/dist/viem/Storage.d.ts +1 -0
  74. package/dist/viem/Storage.d.ts.map +1 -1
  75. package/dist/viem/Storage.js +21 -0
  76. package/dist/viem/Storage.js.map +1 -1
  77. package/dist/viem/TokenIds.d.ts +1 -1
  78. package/dist/viem/TokenIds.d.ts.map +1 -1
  79. package/dist/viem/TokenIds.js +1 -1
  80. package/dist/viem/TokenIds.js.map +1 -1
  81. package/dist/viem/Transaction.d.ts +9 -1
  82. package/dist/viem/Transaction.d.ts.map +1 -1
  83. package/dist/viem/Transaction.js +2 -1
  84. package/dist/viem/Transaction.js.map +1 -1
  85. package/dist/viem/WebAuthnP256.d.ts +4 -1
  86. package/dist/viem/WebAuthnP256.d.ts.map +1 -1
  87. package/dist/viem/WebAuthnP256.js +3 -1
  88. package/dist/viem/WebAuthnP256.js.map +1 -1
  89. package/dist/wagmi/Actions/amm.d.ts +6 -16
  90. package/dist/wagmi/Actions/amm.d.ts.map +1 -1
  91. package/dist/wagmi/Actions/amm.js +6 -16
  92. package/dist/wagmi/Actions/amm.js.map +1 -1
  93. package/dist/wagmi/Connector.d.ts +25 -8
  94. package/dist/wagmi/Connector.d.ts.map +1 -1
  95. package/dist/wagmi/Connector.js +120 -27
  96. package/dist/wagmi/Connector.js.map +1 -1
  97. package/dist/wagmi/Hooks/amm.d.ts +6 -16
  98. package/dist/wagmi/Hooks/amm.d.ts.map +1 -1
  99. package/dist/wagmi/Hooks/amm.js +6 -16
  100. package/dist/wagmi/Hooks/amm.js.map +1 -1
  101. package/package.json +3 -2
  102. package/src/chains.ts +14 -15
  103. package/src/ox/KeyAuthorization.test.ts +1332 -0
  104. package/src/ox/KeyAuthorization.ts +542 -0
  105. package/src/ox/SignatureEnvelope.test.ts +624 -0
  106. package/src/ox/SignatureEnvelope.ts +89 -9
  107. package/src/ox/Transaction.test.ts +214 -0
  108. package/src/ox/Transaction.ts +13 -1
  109. package/src/ox/TransactionEnvelopeAA.test.ts +164 -4
  110. package/src/ox/TransactionEnvelopeAA.ts +36 -3
  111. package/src/ox/TransactionRequest.ts +22 -1
  112. package/src/ox/e2e.test.ts +612 -5
  113. package/src/ox/index.ts +1 -0
  114. package/src/prool/Instance.ts +1 -1
  115. package/src/prool/chain.json +238 -0
  116. package/src/server/Handler.test.ts +20 -36
  117. package/src/viem/Abis.ts +200 -7
  118. package/src/viem/Account.test.ts +444 -0
  119. package/src/viem/Account.ts +355 -42
  120. package/src/viem/Actions/account.ts +3 -5
  121. package/src/viem/Actions/amm.test.ts +220 -1
  122. package/src/viem/Actions/amm.ts +12 -32
  123. package/src/viem/Actions/token.test.ts +8 -8
  124. package/src/viem/Actions/token.ts +2 -2
  125. package/src/viem/Addresses.ts +1 -1
  126. package/src/viem/Chain.test.ts +168 -0
  127. package/src/viem/Chain.ts +37 -1
  128. package/src/viem/Decorator.ts +214 -16
  129. package/src/viem/Formatters.ts +8 -7
  130. package/src/viem/Storage.ts +22 -0
  131. package/src/viem/TokenIds.ts +1 -1
  132. package/src/viem/Transaction.ts +14 -2
  133. package/src/viem/WebAuthnP256.ts +8 -2
  134. package/src/viem/e2e.test.ts +299 -96
  135. package/src/wagmi/Actions/amm.test.ts +93 -2
  136. package/src/wagmi/Actions/amm.ts +6 -16
  137. package/src/wagmi/Connector.test.ts +1 -1
  138. package/src/wagmi/Connector.ts +184 -54
  139. package/src/wagmi/Hooks/amm.test.ts +335 -0
  140. package/src/wagmi/Hooks/amm.ts +6 -16
  141. package/src/wagmi/Hooks/fee.test.ts +10 -4
  142. package/src/wagmi/Hooks/token.test.ts +0 -488
  143. package/dist/viem/internal/account.d.ts +0 -21
  144. package/dist/viem/internal/account.d.ts.map +0 -1
  145. package/dist/viem/internal/account.js +0 -61
  146. package/dist/viem/internal/account.js.map +0 -1
  147. package/src/viem/internal/account.ts +0 -89
@@ -1,15 +1,57 @@
1
- import { WebCryptoP256 } from 'ox'
2
1
  import * as Address from 'ox/Address'
3
- import type * as Hex from 'ox/Hex'
2
+ import * as Hex from 'ox/Hex'
4
3
  import * as P256 from 'ox/P256'
5
4
  import * as PublicKey from 'ox/PublicKey'
6
5
  import * as Secp256k1 from 'ox/Secp256k1'
7
6
  import * as Signature from 'ox/Signature'
8
7
  import * as WebAuthnP256 from 'ox/WebAuthnP256'
8
+ import * as WebCryptoP256 from 'ox/WebCryptoP256'
9
+ import type { LocalAccount, RequiredBy, Account as viem_Account } from 'viem'
10
+ import {
11
+ hashAuthorization,
12
+ hashMessage,
13
+ hashTypedData,
14
+ keccak256,
15
+ parseAccount,
16
+ } from 'viem/utils'
17
+ import type { OneOf } from '../internal/types.js'
18
+ import * as KeyAuthorization from '../ox/KeyAuthorization.js'
9
19
  import * as SignatureEnvelope from '../ox/SignatureEnvelope.js'
10
- import * as internal from './internal/account.js'
20
+ import * as Storage from './Storage.js'
21
+ import * as Transaction from './Transaction.js'
11
22
 
12
- export type { Account } from './internal/account.js'
23
+ type StorageSchema = {
24
+ pendingKeyAuthorization?: KeyAuthorization.Signed | undefined
25
+ }
26
+
27
+ export type Account_base<source extends string = string> = RequiredBy<
28
+ LocalAccount<source>,
29
+ 'sign' | 'signAuthorization'
30
+ > & {
31
+ /** Key type. */
32
+ keyType: SignatureEnvelope.Type
33
+ /** Account storage. */
34
+ storage: Storage.Storage<StorageSchema>
35
+ }
36
+
37
+ export type RootAccount = Account_base<'root'> & {
38
+ /** Assign key authorization to the next transaction. */
39
+ assignKeyAuthorization: (
40
+ keyAuthorization: KeyAuthorization.Signed,
41
+ ) => Promise<void>
42
+ /** Sign key authorization. */
43
+ signKeyAuthorization: (
44
+ key: Pick<AccessKeyAccount, 'accessKeyAddress' | 'keyType'>,
45
+ parameters?: Pick<KeyAuthorization.KeyAuthorization, 'expiry' | 'limits'>,
46
+ ) => Promise<KeyAuthorization.Signed>
47
+ }
48
+
49
+ export type AccessKeyAccount = Account_base<'accessKey'> & {
50
+ /** Access key ID. */
51
+ accessKeyAddress: Address.Address
52
+ }
53
+
54
+ export type Account = OneOf<RootAccount | AccessKeyAccount>
13
55
 
14
56
  /**
15
57
  * Instantiates an Account from a headless WebAuthn credential (P256 private key).
@@ -24,17 +66,19 @@ export type { Account } from './internal/account.js'
24
66
  * @param privateKey P256 private key.
25
67
  * @returns Account.
26
68
  */
27
- export function fromHeadlessWebAuthn(
69
+ export function fromHeadlessWebAuthn<
70
+ const options extends fromHeadlessWebAuthn.Options,
71
+ >(
28
72
  privateKey: Hex.Hex,
29
- options: fromHeadlessWebAuthn.Options,
30
- ): fromP256.ReturnValue {
31
- const { rpId, origin } = options
73
+ options: options | fromHeadlessWebAuthn.Options,
74
+ ): fromHeadlessWebAuthn.ReturnValue<options> {
75
+ const { access, rpId, origin, storage } = options
32
76
 
33
77
  const publicKey = P256.getPublicKey({ privateKey })
34
- const address = Address.fromPublicKey(publicKey)
35
78
 
36
- return internal.toPrivateKeyAccount({
37
- address,
79
+ return from({
80
+ access,
81
+ keyType: 'webAuthn',
38
82
  publicKey,
39
83
  async sign({ hash }) {
40
84
  const { metadata, payload } = WebAuthnP256.getSignPayload({
@@ -55,20 +99,22 @@ export function fromHeadlessWebAuthn(
55
99
  type: 'webAuthn',
56
100
  })
57
101
  },
58
- source: 'webAuthn',
59
- })
102
+ storage,
103
+ }) as never
60
104
  }
61
105
 
62
106
  export declare namespace fromHeadlessWebAuthn {
63
107
  export type Options = Omit<
64
108
  WebAuthnP256.getSignPayload.Options,
65
109
  'challenge' | 'rpId' | 'origin'
66
- > & {
67
- rpId: string
68
- origin: string
69
- }
110
+ > &
111
+ Pick<from.Parameters, 'access' | 'storage'> & {
112
+ rpId: string
113
+ origin: string
114
+ }
70
115
 
71
- export type ReturnValue = internal.toPrivateKeyAccount.ReturnValue
116
+ export type ReturnValue<options extends Options = Options> =
117
+ from.ReturnValue<options>
72
118
  }
73
119
 
74
120
  /**
@@ -84,12 +130,16 @@ export declare namespace fromHeadlessWebAuthn {
84
130
  * @param privateKey P256 private key.
85
131
  * @returns Account.
86
132
  */
87
- export function fromP256(privateKey: Hex.Hex): fromP256.ReturnValue {
133
+ export function fromP256<const options extends fromP256.Options>(
134
+ privateKey: Hex.Hex,
135
+ options: options | fromP256.Options = {},
136
+ ): fromP256.ReturnValue<options> {
137
+ const { access, storage } = options
88
138
  const publicKey = P256.getPublicKey({ privateKey })
89
- const address = Address.fromPublicKey(publicKey)
90
139
 
91
- return internal.toPrivateKeyAccount({
92
- address,
140
+ return from({
141
+ access,
142
+ keyType: 'p256',
93
143
  publicKey,
94
144
  async sign({ hash }) {
95
145
  const signature = P256.sign({ payload: hash, privateKey })
@@ -99,12 +149,15 @@ export function fromP256(privateKey: Hex.Hex): fromP256.ReturnValue {
99
149
  type: 'p256',
100
150
  })
101
151
  },
102
- source: 'p256',
103
- })
152
+ storage,
153
+ }) as never
104
154
  }
105
155
 
106
156
  export declare namespace fromP256 {
107
- export type ReturnValue = internal.toPrivateKeyAccount.ReturnValue
157
+ export type Options = Pick<from.Parameters, 'access' | 'storage'>
158
+
159
+ export type ReturnValue<options extends Options = Options> =
160
+ from.ReturnValue<options>
108
161
  }
109
162
 
110
163
  /**
@@ -121,22 +174,31 @@ export declare namespace fromP256 {
121
174
  * @returns Account.
122
175
  */
123
176
  // TODO: this function will be redundant when Viem migrates to Ox.
124
- export function fromSecp256k1(privateKey: Hex.Hex): fromSecp256k1.ReturnValue {
177
+ export function fromSecp256k1<const options extends fromSecp256k1.Options>(
178
+ privateKey: Hex.Hex,
179
+ options: options | fromSecp256k1.Options = {},
180
+ ): fromSecp256k1.ReturnValue<options> {
181
+ const { access, storage } = options
125
182
  const publicKey = Secp256k1.getPublicKey({ privateKey })
126
183
 
127
- return internal.toPrivateKeyAccount({
128
- address: Address.fromPublicKey(publicKey),
184
+ return from({
185
+ access,
186
+ keyType: 'secp256k1',
129
187
  publicKey,
130
188
  async sign(parameters) {
131
189
  const { hash } = parameters
132
190
  const signature = Secp256k1.sign({ payload: hash, privateKey })
133
191
  return Signature.toHex(signature)
134
192
  },
135
- })
193
+ storage,
194
+ }) as never
136
195
  }
137
196
 
138
197
  export declare namespace fromSecp256k1 {
139
- export type ReturnValue = internal.toPrivateKeyAccount.ReturnValue
198
+ export type Options = Pick<from.Parameters, 'access' | 'storage'>
199
+
200
+ export type ReturnValue<options extends Options = Options> =
201
+ from.ReturnValue<options>
140
202
  }
141
203
 
142
204
  /**
@@ -201,9 +263,10 @@ export function fromWebAuthnP256(
201
263
  options: fromWebAuthnP256.Options = {},
202
264
  ): fromWebAuthnP256.ReturnValue {
203
265
  const { id } = credential
266
+ const { storage } = options
204
267
  const publicKey = PublicKey.fromHex(credential.publicKey)
205
- return internal.toPrivateKeyAccount({
206
- address: Address.fromPublicKey(publicKey),
268
+ return from({
269
+ keyType: 'webAuthn',
207
270
  publicKey,
208
271
  async sign({ hash }) {
209
272
  const { metadata, signature } = await WebAuthnP256.sign({
@@ -218,7 +281,7 @@ export function fromWebAuthnP256(
218
281
  type: 'webAuthn',
219
282
  })
220
283
  },
221
- source: 'webAuthn',
284
+ storage,
222
285
  })
223
286
  }
224
287
 
@@ -231,9 +294,10 @@ export declare namespace fromWebAuthnP256 {
231
294
  export type Options = {
232
295
  getFn?: WebAuthnP256.sign.Options['getFn'] | undefined
233
296
  rpId?: WebAuthnP256.sign.Options['rpId'] | undefined
297
+ storage?: from.Parameters['storage'] | undefined
234
298
  }
235
299
 
236
- export type ReturnValue = internal.toPrivateKeyAccount.ReturnValue
300
+ export type ReturnValue = from.ReturnValue
237
301
  }
238
302
 
239
303
  /**
@@ -252,14 +316,18 @@ export declare namespace fromWebAuthnP256 {
252
316
  * @param keyPair WebCryptoP256 key pair.
253
317
  * @returns Account.
254
318
  */
255
- export function fromWebCryptoP256(
319
+ export function fromWebCryptoP256<
320
+ const options extends fromWebCryptoP256.Options,
321
+ >(
256
322
  keyPair: Awaited<ReturnType<typeof WebCryptoP256.createKeyPair>>,
257
- ): fromWebCryptoP256.ReturnValue {
323
+ options: options | fromWebCryptoP256.Options = {},
324
+ ): fromWebCryptoP256.ReturnValue<options> {
325
+ const { access, storage } = options
258
326
  const { publicKey, privateKey } = keyPair
259
- const address = Address.fromPublicKey(publicKey)
260
327
 
261
- return internal.toPrivateKeyAccount({
262
- address,
328
+ return from({
329
+ access,
330
+ keyType: 'p256',
263
331
  publicKey,
264
332
  async sign({ hash }) {
265
333
  const signature = await WebCryptoP256.sign({ payload: hash, privateKey })
@@ -270,10 +338,255 @@ export function fromWebCryptoP256(
270
338
  type: 'p256',
271
339
  })
272
340
  },
273
- source: 'p256',
274
- })
341
+ storage,
342
+ }) as never
275
343
  }
276
344
 
277
345
  export declare namespace fromWebCryptoP256 {
278
- export type ReturnValue = internal.toPrivateKeyAccount.ReturnValue
346
+ export type Options = Pick<from.Parameters, 'access' | 'storage'>
347
+
348
+ export type ReturnValue<options extends Options = Options> =
349
+ from.ReturnValue<options>
350
+ }
351
+
352
+ export async function signKeyAuthorization(
353
+ account: LocalAccount,
354
+ parameters: signKeyAuthorization.Parameters,
355
+ ): Promise<signKeyAuthorization.ReturnValue> {
356
+ const { key, expiry, limits } = parameters
357
+ const { accessKeyAddress, keyType: type } = key
358
+
359
+ const signature = await account.sign!({
360
+ hash: KeyAuthorization.getSignPayload({
361
+ address: accessKeyAddress,
362
+ expiry,
363
+ limits,
364
+ type,
365
+ }),
366
+ })
367
+ return KeyAuthorization.from({
368
+ address: accessKeyAddress,
369
+ expiry,
370
+ limits,
371
+ signature: SignatureEnvelope.from(signature),
372
+ type,
373
+ })
374
+ }
375
+
376
+ export declare namespace signKeyAuthorization {
377
+ type Parameters = Pick<
378
+ KeyAuthorization.KeyAuthorization,
379
+ 'expiry' | 'limits'
380
+ > & {
381
+ key: Pick<AccessKeyAccount, 'accessKeyAddress' | 'keyType'>
382
+ }
383
+
384
+ type ReturnValue = KeyAuthorization.Signed
385
+ }
386
+
387
+ /** @internal */
388
+ // biome-ignore lint/correctness/noUnusedVariables: _
389
+ function fromBase(parameters: fromBase.Parameters): Account_base {
390
+ const {
391
+ keyType = 'secp256k1',
392
+ parentAddress,
393
+ source = 'privateKey',
394
+ } = parameters
395
+
396
+ const address = parentAddress ?? Address.fromPublicKey(parameters.publicKey)
397
+ const publicKey = PublicKey.toHex(parameters.publicKey, {
398
+ includePrefix: false,
399
+ })
400
+
401
+ const storage = Storage.from<StorageSchema>(
402
+ parameters.storage ?? Storage.memory(),
403
+ { key: `tempo.ts:${address.toLowerCase()}` },
404
+ )
405
+
406
+ async function sign({ hash }: { hash: Hex.Hex }) {
407
+ const signature = await parameters.sign({ hash })
408
+ if (parentAddress)
409
+ return SignatureEnvelope.serialize(
410
+ SignatureEnvelope.from({
411
+ userAddress: parentAddress,
412
+ inner: SignatureEnvelope.from(signature),
413
+ type: 'keychain',
414
+ }),
415
+ )
416
+
417
+ return signature
418
+ }
419
+
420
+ return {
421
+ address: Address.checksum(address),
422
+ keyType,
423
+ sign,
424
+ async signAuthorization(parameters) {
425
+ const { chainId, nonce } = parameters
426
+ const address = parameters.contractAddress ?? parameters.address
427
+ const signature = await sign({
428
+ hash: hashAuthorization({ address, chainId, nonce }),
429
+ })
430
+ const envelope = SignatureEnvelope.from(signature)
431
+ if (envelope.type !== 'secp256k1')
432
+ throw new Error(
433
+ 'Unsupported signature type. Expected `secp256k1` but got `' +
434
+ envelope.type +
435
+ '`.',
436
+ )
437
+ const { r, s, yParity } = envelope.signature
438
+ return {
439
+ address,
440
+ chainId,
441
+ nonce,
442
+ r: Hex.fromNumber(r, { size: 32 }),
443
+ s: Hex.fromNumber(s, { size: 32 }),
444
+ yParity,
445
+ }
446
+ },
447
+ async signMessage(parameters) {
448
+ const { message } = parameters
449
+ const signature = await sign({ hash: hashMessage(message) })
450
+ const envelope = SignatureEnvelope.from(signature)
451
+ return SignatureEnvelope.serialize(envelope)
452
+ },
453
+ async signTransaction(transaction, options) {
454
+ const { serializer = Transaction.serialize } = options ?? {}
455
+
456
+ const keyAuthorization =
457
+ (await storage?.getItem('pendingKeyAuthorization')) ?? undefined
458
+ if (keyAuthorization && !(transaction as any).keyAuthorization) {
459
+ ;(transaction as any).keyAuthorization = keyAuthorization
460
+ await storage.removeItem('pendingKeyAuthorization')
461
+ }
462
+
463
+ const signature = await sign({
464
+ hash: keccak256(await serializer(transaction)),
465
+ })
466
+ const envelope = SignatureEnvelope.from(signature)
467
+ return await serializer(transaction, envelope as never)
468
+ },
469
+ async signTypedData(typedData) {
470
+ const signature = await sign({ hash: hashTypedData(typedData) })
471
+ const envelope = SignatureEnvelope.from(signature)
472
+ return SignatureEnvelope.serialize(envelope)
473
+ },
474
+ publicKey,
475
+ source,
476
+ storage,
477
+ type: 'local',
478
+ }
479
+ }
480
+
481
+ declare namespace fromBase {
482
+ export type Parameters = {
483
+ /** Parent address. */
484
+ parentAddress?: Address.Address | undefined
485
+ /** Public key. */
486
+ publicKey: PublicKey.PublicKey
487
+ /** Key type. */
488
+ keyType?: SignatureEnvelope.Type | undefined
489
+ /** Sign function. */
490
+ sign: NonNullable<LocalAccount['sign']>
491
+ /** Source. */
492
+ source?: string | undefined
493
+ /**
494
+ * Account storage.
495
+ * Used for access key management, and pending key authorizations.
496
+ * @default `Storage.memory()`
497
+ */
498
+ storage?: Storage.Storage | undefined
499
+ }
500
+
501
+ export type ReturnValue = Account_base
502
+ }
503
+
504
+ /** @internal */
505
+ // biome-ignore lint/correctness/noUnusedVariables: _
506
+ function fromRoot(parameters: fromRoot.Parameters): RootAccount {
507
+ const account = fromBase(parameters)
508
+ return {
509
+ ...account,
510
+ source: 'root',
511
+ async assignKeyAuthorization(keyAuthorization) {
512
+ account.storage.setItem('pendingKeyAuthorization', keyAuthorization)
513
+ },
514
+ async signKeyAuthorization(key, parameters = {}) {
515
+ const { expiry, limits } = parameters
516
+ const { accessKeyAddress, keyType: type } = key
517
+
518
+ const signature = await account.sign({
519
+ hash: KeyAuthorization.getSignPayload({
520
+ address: accessKeyAddress,
521
+ expiry,
522
+ limits,
523
+ type,
524
+ }),
525
+ })
526
+ const keyAuthorization = KeyAuthorization.from({
527
+ address: accessKeyAddress,
528
+ expiry,
529
+ limits,
530
+ signature: SignatureEnvelope.from(signature),
531
+ type,
532
+ })
533
+ return keyAuthorization
534
+ },
535
+ }
536
+ }
537
+
538
+ declare namespace fromRoot {
539
+ export type Parameters = fromBase.Parameters
540
+
541
+ export type ReturnValue = RootAccount
542
+ }
543
+
544
+ // biome-ignore lint/correctness/noUnusedVariables: _
545
+ function fromAccessKey(parameters: fromAccessKey.Parameters): AccessKeyAccount {
546
+ const { access } = parameters
547
+ const { address: parentAddress } = parseAccount(access)
548
+ const account = fromBase({ ...parameters, parentAddress })
549
+ return {
550
+ ...account,
551
+ accessKeyAddress: Address.fromPublicKey(parameters.publicKey),
552
+ source: 'accessKey',
553
+ }
554
+ }
555
+
556
+ declare namespace fromAccessKey {
557
+ export type Parameters = fromBase.Parameters & {
558
+ /**
559
+ * Parent account to access.
560
+ * If defined, this account will act as an "access key", and use
561
+ * the parent account's address as the keychain address.
562
+ */
563
+ access: viem_Account | Address.Address
564
+ }
565
+
566
+ export type ReturnValue = AccessKeyAccount
567
+ }
568
+
569
+ // biome-ignore lint/correctness/noUnusedVariables: _
570
+ function from<const parameters extends from.Parameters>(
571
+ parameters: parameters | from.Parameters,
572
+ ): from.ReturnValue<parameters> {
573
+ const { access } = parameters
574
+ if (access) return fromAccessKey(parameters) as never
575
+ return fromRoot(parameters) as never
576
+ }
577
+
578
+ declare namespace from {
579
+ export type Parameters = OneOf<fromRoot.Parameters | fromAccessKey.Parameters>
580
+
581
+ export type ReturnValue<
582
+ parameters extends {
583
+ access?: fromAccessKey.Parameters['access'] | undefined
584
+ } = {
585
+ access?: fromAccessKey.Parameters['access'] | undefined
586
+ },
587
+ > = parameters extends {
588
+ access: fromAccessKey.Parameters['access']
589
+ }
590
+ ? AccessKeyAccount
591
+ : RootAccount
279
592
  }
@@ -63,9 +63,8 @@ export async function verifyHash<chain extends Chain | undefined>(
63
63
 
64
64
  const [envelope, userAddress] = (() => {
65
65
  const envelope = SignatureEnvelope.from(signature)
66
- // TODO: add once we have key auth
67
- // if (envelope.type === 'keychain')
68
- // return [envelope.inner, envelope.userAddress]
66
+ if (envelope.type === 'keychain')
67
+ return [envelope.inner, envelope.userAddress]
69
68
  return [envelope, undefined]
70
69
  })()
71
70
 
@@ -83,8 +82,7 @@ export async function verifyHash<chain extends Chain | undefined>(
83
82
  publicKey: envelope.publicKey,
84
83
  signature: envelope.signature,
85
84
  })
86
- // TODO: add once we have key auth
87
- // if (envelope.type === 'keychain') throw new Error('not supported')
85
+ if (envelope.type === 'keychain') throw new Error('not supported')
88
86
 
89
87
  const address =
90
88
  parameters.address ??