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,8 +1,8 @@
1
- import { connect } from '@wagmi/core'
1
+ import { connect, getConnectorClient } from '@wagmi/core'
2
2
  import { parseUnits } from 'viem'
3
3
  import { describe, expect, test } from 'vitest'
4
4
  import { addresses } from '../../../test/config.js'
5
- import { accounts } from '../../../test/viem/config.js'
5
+ import { accounts, setupPoolWithLiquidity } from '../../../test/viem/config.js'
6
6
  import { config, queryClient } from '../../../test/wagmi/config.js'
7
7
  import * as ammActions from './amm.js'
8
8
  import * as tokenActions from './token.js'
@@ -115,3 +115,94 @@ describe('mintSync', () => {
115
115
  `)
116
116
  })
117
117
  })
118
+
119
+ describe.skip('burnSync', () => {
120
+ test('default', async () => {
121
+ await connect(config, {
122
+ connector: config.connectors[0]!,
123
+ })
124
+
125
+ const client = await getConnectorClient(config)
126
+ const { tokenAddress } = await setupPoolWithLiquidity(client)
127
+
128
+ const account2 = accounts[1]
129
+
130
+ // Get LP balance before burn
131
+ const lpBalanceBefore = await ammActions.getLiquidityBalance(config, {
132
+ userToken: tokenAddress,
133
+ validatorToken: addresses.alphaUsd,
134
+ address: account.address,
135
+ })
136
+
137
+ // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
138
+ await tokenActions.transferSync(config, {
139
+ to: account2.address,
140
+ amount: 600n,
141
+ token: tokenAddress,
142
+ feeToken: tokenAddress,
143
+ })
144
+
145
+ // Burn half of LP tokens
146
+ const { receipt: burnReceipt, ...burnResult } = await ammActions.burnSync(
147
+ config,
148
+ {
149
+ userToken: tokenAddress,
150
+ validatorToken: addresses.alphaUsd,
151
+ liquidity: lpBalanceBefore / 2n,
152
+ to: account.address,
153
+ },
154
+ )
155
+ expect(burnReceipt).toBeDefined()
156
+ expect(burnResult).toMatchInlineSnapshot(`
157
+ {
158
+ "amountUserToken": 337n,
159
+ "amountValidatorToken": 49998664n,
160
+ "liquidity": 24999500n,
161
+ "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
162
+ "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
163
+ "userToken": "0x20c0000000000000000000000000000000000005",
164
+ "validatorToken": "0x20C0000000000000000000000000000000000001",
165
+ }
166
+ `)
167
+ })
168
+ })
169
+
170
+ describe.skip('rebalanceSwapSync', () => {
171
+ test('default', async () => {
172
+ await connect(config, {
173
+ connector: config.connectors[0]!,
174
+ })
175
+
176
+ const client = await getConnectorClient(config)
177
+ const { tokenAddress } = await setupPoolWithLiquidity(client)
178
+
179
+ const account2 = accounts[1]
180
+
181
+ // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
182
+ await tokenActions.transferSync(config, {
183
+ to: account2.address,
184
+ amount: 600n,
185
+ token: tokenAddress,
186
+ feeToken: tokenAddress,
187
+ })
188
+
189
+ // Perform rebalance swap
190
+ const { receipt: swapReceipt, ...swapResult } =
191
+ await ammActions.rebalanceSwapSync(config, {
192
+ userToken: tokenAddress,
193
+ validatorToken: addresses.alphaUsd,
194
+ amountOut: 100n,
195
+ to: account2.address,
196
+ })
197
+ expect(swapReceipt).toBeDefined()
198
+ expect(swapResult).toMatchInlineSnapshot(`
199
+ {
200
+ "amountIn": 100n,
201
+ "amountOut": 100n,
202
+ "swapper": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
203
+ "userToken": "0x20C0000000000000000000000000000000000006",
204
+ "validatorToken": "0x20C0000000000000000000000000000000000001",
205
+ }
206
+ `)
207
+ })
208
+ })
@@ -322,14 +322,9 @@ export declare namespace rebalanceSwapSync {
322
322
  * })
323
323
  *
324
324
  * const hash = await Actions.amm.mint(config, {
325
- * userToken: {
326
- * address: '0x20c0...beef',
327
- * amount: 100n,
328
- * },
329
- * validatorToken: {
330
- * address: '0x20c0...babe',
331
- * amount: 100n,
332
- * },
325
+ * userTokenAddress: '0x20c0...beef',
326
+ * validatorTokenAddress: '0x20c0...babe',
327
+ * validatorTokenAmount: 100n,
333
328
  * to: '0xfeed...fede',
334
329
  * })
335
330
  * ```
@@ -382,14 +377,9 @@ export declare namespace mint {
382
377
  * })
383
378
  *
384
379
  * const result = await Actions.amm.mintSync(config, {
385
- * userToken: {
386
- * address: '0x20c0...beef',
387
- * amount: 100n,
388
- * },
389
- * validatorToken: {
390
- * address: '0x20c0...babe',
391
- * amount: 100n,
392
- * },
380
+ * userTokenAddress: '0x20c0...beef',
381
+ * validatorTokenAddress: '0x20c0...babe',
382
+ * validatorTokenAmount: 100n,
393
383
  * to: '0xfeed...fede',
394
384
  * })
395
385
  * ```
@@ -40,10 +40,10 @@ test('connect', async (context) => {
40
40
  expect(result.current.useAccount.status).toEqual('disconnected')
41
41
 
42
42
  result.current.useConnect.connect({
43
+ capabilities: { type: 'sign-up', label: 'Test Account' },
43
44
  connector: webAuthn({
44
45
  keyManager: KeyManager.localStorage(),
45
46
  }),
46
- capabilities: { createAccount: { label: 'Test Account' } },
47
47
  })
48
48
 
49
49
  await vi.waitFor(() =>
@@ -1,5 +1,6 @@
1
1
  import * as Address from 'ox/Address'
2
2
  import type * as Hex from 'ox/Hex'
3
+ import * as PublicKey from 'ox/PublicKey'
3
4
  import {
4
5
  createClient,
5
6
  type EIP1193Provider,
@@ -9,11 +10,16 @@ import {
9
10
  } from 'viem'
10
11
  import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
11
12
  import { ChainNotConfiguredError, createConnector } from 'wagmi'
13
+ import type { OneOf } from '../internal/types.js'
14
+ import * as KeyAuthorization from '../ox/KeyAuthorization.js'
15
+ import * as SignatureEnvelope from '../ox/SignatureEnvelope.js'
12
16
  import * as Account from '../viem/Account.js'
13
17
  import type * as tempo_Chain from '../viem/Chain.js'
14
18
  import { normalizeValue } from '../viem/internal/utils.js'
19
+ import * as Storage from '../viem/Storage.js'
15
20
  import { walletNamespaceCompat } from '../viem/Transport.js'
16
21
  import * as WebAuthnP256 from '../viem/WebAuthnP256.js'
22
+ import * as WebCryptoP256 from '../viem/WebCryptoP256.js'
17
23
  import type * as KeyManager from './KeyManager.js'
18
24
 
19
25
  type Chain = ReturnType<ReturnType<typeof tempo_Chain.define>>
@@ -35,9 +41,12 @@ export function dangerous_secp256k1(
35
41
  type Properties = {
36
42
  connect<withCapabilities extends boolean = false>(parameters: {
37
43
  capabilities?:
38
- | {
39
- createAccount?: boolean | undefined
40
- }
44
+ | OneOf<
45
+ | {
46
+ type: 'sign-up'
47
+ }
48
+ | {}
49
+ >
41
50
  | undefined
42
51
  chainId?: number | undefined
43
52
  isReconnecting?: boolean | undefined
@@ -75,7 +84,7 @@ export function dangerous_secp256k1(
75
84
  const address = await (async () => {
76
85
  if (
77
86
  'capabilities' in parameters &&
78
- parameters.capabilities?.createAccount
87
+ parameters.capabilities?.type === 'sign-up'
79
88
  ) {
80
89
  const privateKey = generatePrivateKey()
81
90
  const account = privateKeyToAccount(privateKey)
@@ -197,20 +206,28 @@ export declare namespace dangerous_secp256k1 {
197
206
  * @returns Connector.
198
207
  */
199
208
  export function webAuthn(options: webAuthn.Parameters) {
200
- let account: Account.Account | undefined
209
+ let account: Account.RootAccount | undefined
210
+ let accessKey: Account.AccessKeyAccount | undefined
211
+
212
+ const idbStorage = Storage.idb<{
213
+ [key: `accessKey:${string}`]: WebCryptoP256.createKeyPair.ReturnType
214
+ }>()
201
215
 
202
216
  type Properties = {
203
217
  connect<withCapabilities extends boolean = false>(parameters: {
204
218
  chainId?: number | undefined
205
219
  capabilities?:
206
- | {
207
- createAccount?:
208
- | boolean
209
- | {
210
- label?: string | undefined
211
- }
212
- | undefined
213
- }
220
+ | OneOf<
221
+ | {
222
+ label?: string | undefined
223
+ type: 'sign-up'
224
+ }
225
+ | {
226
+ selectAccount?: boolean | undefined
227
+ type: 'sign-in'
228
+ }
229
+ | {}
230
+ >
214
231
  | undefined
215
232
  isReconnecting?: boolean | undefined
216
233
  withCapabilities?: withCapabilities | boolean | undefined
@@ -234,50 +251,107 @@ export function webAuthn(options: webAuthn.Parameters) {
234
251
  account = Account.fromWebAuthnP256(credential)
235
252
  },
236
253
  async connect(parameters = {}) {
237
- account ??= await (async () => {
238
- let credential: WebAuthnP256.P256Credential | undefined
254
+ const { grantAccessKey = false } = options
255
+ const capabilities =
256
+ 'capabilities' in parameters ? (parameters.capabilities ?? {}) : {}
239
257
 
240
- if (
241
- 'capabilities' in parameters &&
242
- parameters.capabilities?.createAccount
243
- ) {
258
+ // We are going to need to find:
259
+ // - a WebAuthn `credential` to instantiate an account
260
+ // - optionally, a `keyPair` to use as the access key for the account
261
+ // - optionally, a signed `keyAuthorization` to provision the access key
262
+ const { credential, keyAuthorization, keyPair } = await (async () => {
263
+ // If the connection type is of "sign-up", we are going to create a new credential
264
+ // and provision an access key (if needed).
265
+ if (capabilities.type === 'sign-up') {
244
266
  // Create credential (sign up)
245
- const createOptions =
246
- typeof parameters.capabilities?.createAccount === 'boolean'
247
- ? {}
248
- : parameters.capabilities?.createAccount
249
267
  const createOptions_remote = await options.keyManager.getChallenge?.()
250
- credential = await WebAuthnP256.createCredential({
268
+ const label =
269
+ capabilities.label ??
270
+ options.createOptions?.label ??
271
+ new Date().toISOString()
272
+ const rpId =
273
+ createOptions_remote?.rp?.id ??
274
+ options.createOptions?.rpId ??
275
+ options.rpId
276
+ const credential = await WebAuthnP256.createCredential({
251
277
  ...(options.createOptions ?? {}),
252
- label:
253
- createOptions.label ??
254
- options.createOptions?.label ??
255
- `Account ${new Date().toISOString().split('T')[0]}`,
256
- rpId:
257
- createOptions_remote?.rp?.id ??
258
- options.createOptions?.rpId ??
259
- options.rpId,
278
+ label,
279
+ rpId,
260
280
  ...(createOptions_remote ?? {}),
261
281
  })
262
282
  await options.keyManager.setPublicKey({
263
283
  credential: credential.raw,
264
284
  publicKey: credential.publicKey,
265
285
  })
266
- } else {
267
- // Load credential (log in)
268
- credential = (await config.storage?.getItem(
286
+
287
+ // Get key pair (access key) to use for the account.
288
+ const keyPair = await (async () => {
289
+ if (!grantAccessKey) return undefined
290
+ return await WebCryptoP256.createKeyPair()
291
+ })()
292
+
293
+ return { credential, keyPair }
294
+ }
295
+
296
+ // If we are not selecting an account, we will check if an active credential is present in
297
+ // storage and if so, we will use it to instantiate an account.
298
+ if (!capabilities.selectAccount) {
299
+ const credential = (await config.storage?.getItem(
269
300
  'webAuthn.activeCredential',
270
- )) as WebAuthnP256.P256Credential | undefined
301
+ )) as WebAuthnP256.getCredential.ReturnValue | undefined
271
302
 
272
- // If no active credential, load (last active, if present) credential from keychain.
273
- const lastActiveCredential = await config.storage?.getItem(
274
- 'webAuthn.lastActiveCredential',
275
- )
276
- credential ??= await WebAuthnP256.getCredential({
303
+ if (credential) {
304
+ // Get key pair (access key) to use for the account.
305
+ const keyPair = await (async () => {
306
+ if (!grantAccessKey) return undefined
307
+ const address = Address.fromPublicKey(
308
+ PublicKey.fromHex(credential.publicKey),
309
+ )
310
+ return await idbStorage.getItem(`accessKey:${address}`)
311
+ })()
312
+
313
+ // If the access key policy is lax, return the credential and key pair (if exists).
314
+ if (grantAccessKey === 'lax') return { credential, keyPair }
315
+
316
+ // If a key pair is found, return the credential and key pair.
317
+ if (keyPair) return { credential, keyPair }
318
+
319
+ // If we are reconnecting, throw an error if not found.
320
+ if (parameters.isReconnecting)
321
+ throw new Error('credential not found.')
322
+
323
+ // Otherwise, we want to continue to sign up or register against new key pair.
324
+ }
325
+ }
326
+
327
+ // Discover credential
328
+ {
329
+ // Get key pair (access key) to use for the account.
330
+ const keyPair = await (async () => {
331
+ if (!grantAccessKey) return undefined
332
+ return await WebCryptoP256.createKeyPair()
333
+ })()
334
+
335
+ // If we are provisioning an access key, we will need to sign a key authorization.
336
+ // We will need the hash (digest) to sign, and the address of the access key to construct the key authorization.
337
+ const { accessKeyAddress, hash } = await (async () => {
338
+ if (!keyPair)
339
+ return { accessKeyAddress: undefined, hash: undefined }
340
+ const accessKeyAddress = Address.fromPublicKey(keyPair.publicKey)
341
+ const hash = KeyAuthorization.getSignPayload({
342
+ address: accessKeyAddress,
343
+ type: 'p256',
344
+ })
345
+ return { accessKeyAddress, hash, keyPair }
346
+ })()
347
+
348
+ // If no active credential, we will attempt to load the last active credential from storage.
349
+ const lastActiveCredential = !capabilities.selectAccount
350
+ ? await config.storage?.getItem('webAuthn.lastActiveCredential')
351
+ : undefined
352
+ const credential = await WebAuthnP256.getCredential({
277
353
  ...(options.getOptions ?? {}),
278
354
  credentialId: lastActiveCredential?.id,
279
- // biome-ignore lint/suspicious/noTsIgnore: _
280
- // @ts-ignore
281
355
  async getPublicKey(credential) {
282
356
  const publicKey = await options.keyManager.getPublicKey({
283
357
  credential,
@@ -285,21 +359,63 @@ export function webAuthn(options: webAuthn.Parameters) {
285
359
  if (!publicKey) throw new Error('publicKey not found.')
286
360
  return publicKey
287
361
  },
362
+ hash,
288
363
  rpId: options.getOptions?.rpId ?? options.rpId,
289
364
  })
290
- }
291
365
 
292
- config.storage?.setItem(
293
- 'webAuthn.activeCredential',
294
- normalizeValue(credential),
295
- )
296
- config.storage?.setItem(
297
- 'webAuthn.lastActiveCredential',
298
- normalizeValue(credential),
299
- )
300
- return Account.fromWebAuthnP256(credential)
366
+ const keyAuthorization = accessKeyAddress
367
+ ? KeyAuthorization.from({
368
+ address: accessKeyAddress,
369
+ signature: SignatureEnvelope.from({
370
+ metadata: credential.metadata,
371
+ signature: credential.signature,
372
+ publicKey: PublicKey.fromHex(credential.publicKey),
373
+ type: 'webAuthn',
374
+ }),
375
+ type: 'p256',
376
+ })
377
+ : undefined
378
+
379
+ return { credential, keyAuthorization, keyPair }
380
+ }
301
381
  })()
302
382
 
383
+ config.storage?.setItem(
384
+ 'webAuthn.lastActiveCredential',
385
+ normalizeValue(credential),
386
+ )
387
+ config.storage?.setItem(
388
+ 'webAuthn.activeCredential',
389
+ normalizeValue(credential),
390
+ )
391
+
392
+ account = Account.fromWebAuthnP256(credential, {
393
+ storage: Storage.from(config.storage as never),
394
+ })
395
+
396
+ if (keyPair) {
397
+ accessKey = Account.fromWebCryptoP256(keyPair, {
398
+ access: account,
399
+ storage: Storage.from(config.storage as never),
400
+ })
401
+
402
+ // If we are not reconnecting, orchestrate the provisioning of the access key.
403
+ if (!parameters.isReconnecting) {
404
+ const keyAuth =
405
+ keyAuthorization ?? (await account.signKeyAuthorization(accessKey))
406
+
407
+ await account.storage.setItem('pendingKeyAuthorization', keyAuth)
408
+ await idbStorage.setItem(
409
+ `accessKey:${account.address.toLowerCase()}`,
410
+ keyPair,
411
+ )
412
+ }
413
+ // If we are granting an access key, throw an error if the access key is not provisioned.
414
+ } else if (grantAccessKey === true) {
415
+ await config.storage?.removeItem('webAuthn.activeCredential')
416
+ throw new Error('access key not found')
417
+ }
418
+
303
419
  const address = getAddress(account.address)
304
420
 
305
421
  const chainId = parameters.chainId ?? config.chains[0]?.id
@@ -361,7 +477,7 @@ export function webAuthn(options: webAuthn.Parameters) {
361
477
  if (!transport) throw new ChainNotConfiguredError()
362
478
 
363
479
  return createClient({
364
- account,
480
+ account: accessKey ?? account,
365
481
  chain: chain as Chain,
366
482
  transport: walletNamespaceCompat(transport),
367
483
  })
@@ -386,6 +502,20 @@ export namespace webAuthn {
386
502
  getOptions?:
387
503
  | Pick<WebAuthnP256.getCredential.Parameters, 'getFn' | 'rpId'>
388
504
  | undefined
505
+ /**
506
+ * Whether or not to grant an access key upon connection.
507
+ *
508
+ * - `true`: The account MUST have an access key provisioned.
509
+ * On failure, the connection will fail.
510
+ * - `"lax"`: The account MAY have an access key provisioned.
511
+ * On failure, the connection will succeed, but the access key will not be provisioned
512
+ * and must be provisioned manually if the user wants to enforce access keys.
513
+ * - `false`: The account WILL NOT have an access key provisioned. The access key must be
514
+ * provisioned manually if the user wants to enforce access keys.
515
+ *
516
+ * @default false
517
+ */
518
+ grantAccessKey?: boolean | 'lax'
389
519
  /** Public key manager. */
390
520
  keyManager: KeyManager.KeyManager
391
521
  /** The RP ID to use for WebAuthn. */