tempo.ts 0.6.2 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +6 -2
  3. package/dist/ox/Transaction.js +1 -1
  4. package/dist/ox/Transaction.js.map +1 -1
  5. package/dist/server/Handler.d.ts +346 -0
  6. package/dist/server/Handler.d.ts.map +1 -0
  7. package/dist/server/Handler.js +441 -0
  8. package/dist/server/Handler.js.map +1 -0
  9. package/dist/server/Kv.d.ts +16 -0
  10. package/dist/server/Kv.d.ts.map +1 -0
  11. package/dist/server/Kv.js +25 -0
  12. package/dist/server/Kv.js.map +1 -0
  13. package/dist/server/index.d.ts +3 -0
  14. package/dist/server/index.d.ts.map +1 -0
  15. package/dist/server/index.js +3 -0
  16. package/dist/server/index.js.map +1 -0
  17. package/dist/server/internal/requestListener.d.ts +124 -0
  18. package/dist/server/internal/requestListener.d.ts.map +1 -0
  19. package/dist/server/internal/requestListener.js +174 -0
  20. package/dist/server/internal/requestListener.js.map +1 -0
  21. package/dist/viem/Actions/amm.d.ts +9 -41
  22. package/dist/viem/Actions/amm.d.ts.map +1 -1
  23. package/dist/viem/Actions/amm.js +15 -26
  24. package/dist/viem/Actions/amm.js.map +1 -1
  25. package/dist/viem/Actions/reward.d.ts +0 -1067
  26. package/dist/viem/Actions/reward.d.ts.map +1 -1
  27. package/dist/viem/Actions/reward.js +4 -212
  28. package/dist/viem/Actions/reward.js.map +1 -1
  29. package/dist/viem/Decorator.d.ts +0 -263
  30. package/dist/viem/Decorator.d.ts.map +1 -1
  31. package/dist/viem/Decorator.js +0 -10
  32. package/dist/viem/Decorator.js.map +1 -1
  33. package/dist/viem/Storage.d.ts +23 -0
  34. package/dist/viem/Storage.d.ts.map +1 -0
  35. package/dist/viem/Storage.js +47 -0
  36. package/dist/viem/Storage.js.map +1 -0
  37. package/dist/viem/Transport.d.ts +10 -1
  38. package/dist/viem/Transport.d.ts.map +1 -1
  39. package/dist/viem/Transport.js +22 -3
  40. package/dist/viem/Transport.js.map +1 -1
  41. package/dist/viem/internal/utils.d.ts +6 -0
  42. package/dist/viem/internal/utils.d.ts.map +1 -1
  43. package/dist/viem/internal/utils.js +24 -0
  44. package/dist/viem/internal/utils.js.map +1 -1
  45. package/dist/wagmi/Actions/reward.d.ts +0 -110
  46. package/dist/wagmi/Actions/reward.d.ts.map +1 -1
  47. package/dist/wagmi/Actions/reward.js +0 -121
  48. package/dist/wagmi/Actions/reward.js.map +1 -1
  49. package/dist/wagmi/Connector.d.ts +6 -17
  50. package/dist/wagmi/Connector.d.ts.map +1 -1
  51. package/dist/wagmi/Connector.js +17 -43
  52. package/dist/wagmi/Connector.js.map +1 -1
  53. package/dist/wagmi/Hooks/reward.d.ts +0 -88
  54. package/dist/wagmi/Hooks/reward.d.ts.map +1 -1
  55. package/dist/wagmi/Hooks/reward.js +0 -103
  56. package/dist/wagmi/Hooks/reward.js.map +1 -1
  57. package/dist/wagmi/KeyManager.d.ts +57 -0
  58. package/dist/wagmi/KeyManager.d.ts.map +1 -0
  59. package/dist/wagmi/KeyManager.js +101 -0
  60. package/dist/wagmi/KeyManager.js.map +1 -0
  61. package/dist/wagmi/index.d.ts +1 -0
  62. package/dist/wagmi/index.d.ts.map +1 -1
  63. package/dist/wagmi/index.js +1 -0
  64. package/dist/wagmi/index.js.map +1 -1
  65. package/package.json +8 -2
  66. package/src/ox/Transaction.ts +1 -1
  67. package/src/ox/e2e.test.ts +7 -0
  68. package/src/server/Handler.test.ts +566 -0
  69. package/src/server/Handler.ts +577 -0
  70. package/src/server/Kv.ts +40 -0
  71. package/src/server/index.ts +2 -0
  72. package/src/server/internal/requestListener.ts +285 -0
  73. package/src/viem/Actions/amm.test.ts +10 -284
  74. package/src/viem/Actions/amm.ts +32 -40
  75. package/src/viem/Actions/reward.test.ts +4 -212
  76. package/src/viem/Actions/reward.ts +4 -291
  77. package/src/viem/Decorator.ts +0 -294
  78. package/src/viem/Storage.ts +88 -0
  79. package/src/viem/Transport.ts +40 -2
  80. package/src/viem/e2e.test.ts +106 -3
  81. package/src/viem/internal/utils.ts +21 -0
  82. package/src/wagmi/Actions/amm.test.ts +7 -85
  83. package/src/wagmi/Actions/reward.test.ts +0 -99
  84. package/src/wagmi/Actions/reward.ts +0 -203
  85. package/src/wagmi/Connector.test.ts +4 -1
  86. package/src/wagmi/Connector.ts +24 -58
  87. package/src/wagmi/Hooks/amm.test.ts +8 -200
  88. package/src/wagmi/Hooks/reward.test.ts +1 -142
  89. package/src/wagmi/Hooks/reward.ts +0 -196
  90. package/src/wagmi/KeyManager.ts +159 -0
  91. package/src/wagmi/index.ts +1 -0
@@ -1,125 +1,9 @@
1
- import { type Address, parseUnits } from 'viem'
1
+ import type { Address } from 'viem'
2
2
  import { describe, expect, test, vi } from 'vitest'
3
3
  import { useConnect } from 'wagmi'
4
4
  import { config, renderHook, setupToken } from '../../../test/wagmi/config.js'
5
5
  import * as hooks from './reward.js'
6
6
 
7
- describe('useCancelSync', () => {
8
- test('default', async () => {
9
- const { result } = await renderHook(() => ({
10
- cancel: hooks.useCancelSync(),
11
- connect: useConnect(),
12
- start: hooks.useStartSync(),
13
- }))
14
-
15
- await result.current.connect.connectAsync({
16
- connector: config.connectors[0]!,
17
- })
18
-
19
- const { token } = await setupToken()
20
-
21
- // Start a reward stream
22
- const { id: streamId } = await result.current.start.mutateAsync({
23
- amount: parseUnits('100', 6),
24
- seconds: 3600,
25
- token,
26
- })
27
-
28
- // Cancel the stream
29
- await result.current.cancel.mutateAsync({
30
- id: streamId,
31
- token,
32
- })
33
-
34
- await vi.waitFor(() => expect(result.current.cancel.isSuccess).toBeTruthy())
35
- })
36
- })
37
-
38
- describe('useGetStream', () => {
39
- test('default', async () => {
40
- const { result } = await renderHook(() => ({
41
- connect: useConnect(),
42
- getStream: hooks.useGetStream(),
43
- startSync: hooks.useStartSync(),
44
- }))
45
-
46
- await result.current.connect.connectAsync({
47
- connector: config.connectors[0]!,
48
- })
49
-
50
- const { token } = await setupToken()
51
-
52
- const { id: streamId } = await result.current.startSync.mutateAsync({
53
- amount: parseUnits('100', 6),
54
- seconds: 10,
55
- token,
56
- })
57
-
58
- // Update the hook to query the stream
59
- const { result: streamResult } = await renderHook(() =>
60
- hooks.useGetStream({
61
- id: streamId,
62
- token,
63
- }),
64
- )
65
-
66
- await vi.waitFor(() => expect(streamResult.current.isSuccess).toBeTruthy())
67
-
68
- expect(streamResult.current.data?.funder).toBeDefined()
69
- expect(streamResult.current.data?.amountTotal).toBe(parseUnits('100', 6))
70
- })
71
-
72
- test('reactivity: id and token parameters', async () => {
73
- const { result: setupResult } = await renderHook(() => ({
74
- connect: useConnect(),
75
- startSync: hooks.useStartSync(),
76
- }))
77
-
78
- await setupResult.current.connect.connectAsync({
79
- connector: config.connectors[0]!,
80
- })
81
-
82
- const { token } = await setupToken()
83
-
84
- const { id } = await setupResult.current.startSync.mutateAsync({
85
- amount: parseUnits('100', 6),
86
- seconds: 10,
87
- token,
88
- })
89
-
90
- const { result, rerender } = await renderHook(
91
- (props) =>
92
- hooks.useGetStream({
93
- id: props?.id,
94
- token: props?.token,
95
- }),
96
- {
97
- initialProps: {
98
- id: undefined as bigint | undefined,
99
- token: undefined as Address | undefined,
100
- },
101
- },
102
- )
103
-
104
- await vi.waitFor(() => result.current.fetchStatus === 'idle')
105
-
106
- // Should be disabled when parameters are undefined
107
- expect(result.current.data).toBeUndefined()
108
- expect(result.current.isPending).toBe(true)
109
- expect(result.current.isEnabled).toBe(false)
110
-
111
- // Set parameters
112
- rerender({ id, token })
113
-
114
- await vi.waitFor(() => expect(result.current.isSuccess).toBeTruthy())
115
-
116
- // Should now be enabled and have data
117
- expect(result.current.isEnabled).toBe(true)
118
- expect(result.current.data).toBeDefined()
119
- expect(result.current.data?.amountTotal).toBe(parseUnits('100', 6))
120
- })
121
- })
122
-
123
7
  describe('useGetTotalPerSecond', () => {
124
8
  test('default', async () => {
125
9
  const { token } = await setupToken()
@@ -192,28 +76,3 @@ describe('useSetRecipientSync', () => {
192
76
  )
193
77
  })
194
78
  })
195
-
196
- describe('useStartSync', () => {
197
- test('default', async () => {
198
- const { result } = await renderHook(() => ({
199
- connect: useConnect(),
200
- start: hooks.useStartSync(),
201
- }))
202
-
203
- await result.current.connect.connectAsync({
204
- connector: config.connectors[0]!,
205
- })
206
-
207
- const { token } = await setupToken()
208
-
209
- const { id } = await result.current.start.mutateAsync({
210
- amount: parseUnits('100', 6),
211
- seconds: 10,
212
- token,
213
- })
214
-
215
- expect(id).toBeGreaterThan(0n)
216
-
217
- await vi.waitFor(() => expect(result.current.start.isSuccess).toBeTruthy())
218
- })
219
- })
@@ -12,140 +12,6 @@ import {
12
12
  import type { ExactPartial } from '../../internal/types.js'
13
13
  import * as Actions from '../Actions/reward.js'
14
14
 
15
- /**
16
- * Hook for canceling an active reward stream.
17
- *
18
- * @example
19
- * ```tsx
20
- * import { Hooks } from 'tempo.ts/wagmi'
21
- *
22
- * function App() {
23
- * const { mutate: cancel } = Hooks.reward.useCancel()
24
- *
25
- * return (
26
- * <button onClick={() => cancel({
27
- * id: 1n,
28
- * token: '0x20c0000000000000000000000000000000000001'
29
- * })}>
30
- * Cancel Stream
31
- * </button>
32
- * )
33
- * }
34
- * ```
35
- *
36
- * @param parameters - Parameters.
37
- * @returns Mutation result.
38
- */
39
- export function useCancel<
40
- config extends Config = ResolvedRegister['config'],
41
- context = unknown,
42
- >(
43
- parameters: useCancel.Parameters<config, context> = {},
44
- ): useCancel.ReturnType<config, context> {
45
- const { mutation } = parameters
46
- const config = useConfig(parameters)
47
- return useMutation({
48
- ...mutation,
49
- async mutationFn(variables) {
50
- return Actions.cancel(config, variables as never)
51
- },
52
- mutationKey: ['cancel'],
53
- }) as never
54
- }
55
-
56
- export declare namespace useCancel {
57
- type Parameters<
58
- config extends Config = Config,
59
- context = unknown,
60
- > = ConfigParameter<config> & {
61
- mutation?:
62
- | UseMutationParameters<
63
- Actions.cancel.ReturnValue,
64
- Actions.cancel.ErrorType,
65
- Actions.cancel.Parameters<config>,
66
- context
67
- >
68
- | undefined
69
- }
70
-
71
- type ReturnType<
72
- config extends Config = Config,
73
- context = unknown,
74
- > = UseMutationResult<
75
- Actions.cancel.ReturnValue,
76
- Actions.cancel.ErrorType,
77
- Actions.cancel.Parameters<config>,
78
- context
79
- >
80
- }
81
-
82
- /**
83
- * Hook for canceling an active reward stream and waiting for confirmation.
84
- *
85
- * @example
86
- * ```tsx
87
- * import { Hooks } from 'tempo.ts/wagmi'
88
- *
89
- * function App() {
90
- * const { mutate: cancelSync } = Hooks.reward.useCancelSync()
91
- *
92
- * return (
93
- * <button onClick={() => cancelSync({
94
- * id: 1n,
95
- * token: '0x20c0000000000000000000000000000000000001'
96
- * })}>
97
- * Cancel Stream
98
- * </button>
99
- * )
100
- * }
101
- * ```
102
- *
103
- * @param parameters - Parameters.
104
- * @returns Mutation result.
105
- */
106
- export function useCancelSync<
107
- config extends Config = ResolvedRegister['config'],
108
- context = unknown,
109
- >(
110
- parameters: useCancelSync.Parameters<config, context> = {},
111
- ): useCancelSync.ReturnType<config, context> {
112
- const { mutation } = parameters
113
- const config = useConfig(parameters)
114
- return useMutation({
115
- ...mutation,
116
- async mutationFn(variables) {
117
- return Actions.cancelSync(config, variables as never)
118
- },
119
- mutationKey: ['cancelSync'],
120
- }) as never
121
- }
122
-
123
- export declare namespace useCancelSync {
124
- type Parameters<
125
- config extends Config = Config,
126
- context = unknown,
127
- > = ConfigParameter<config> & {
128
- mutation?:
129
- | UseMutationParameters<
130
- Actions.cancelSync.ReturnValue,
131
- Actions.cancelSync.ErrorType,
132
- Actions.cancelSync.Parameters<config>,
133
- context
134
- >
135
- | undefined
136
- }
137
-
138
- type ReturnType<
139
- config extends Config = Config,
140
- context = unknown,
141
- > = UseMutationResult<
142
- Actions.cancelSync.ReturnValue,
143
- Actions.cancelSync.ErrorType,
144
- Actions.cancelSync.Parameters<config>,
145
- context
146
- >
147
- }
148
-
149
15
  /**
150
16
  * Hook for claiming accumulated rewards.
151
17
  *
@@ -278,68 +144,6 @@ export declare namespace useClaimSync {
278
144
  >
279
145
  }
280
146
 
281
- /**
282
- * Hook for getting a reward stream by its ID.
283
- *
284
- * @example
285
- * ```tsx
286
- * import { Hooks } from 'tempo.ts/wagmi'
287
- *
288
- * function App() {
289
- * const { data, isLoading } = Hooks.reward.useGetStream({
290
- * id: 1n,
291
- * token: '0x20c0000000000000000000000000000000000001',
292
- * })
293
- *
294
- * if (isLoading) return <div>Loading...</div>
295
- * return <div>Funder: {data?.funder}</div>
296
- * }
297
- * ```
298
- *
299
- * @param parameters - Parameters.
300
- * @returns Query result with stream details.
301
- */
302
- export function useGetStream<
303
- config extends Config = ResolvedRegister['config'],
304
- selectData = Actions.getStream.ReturnValue,
305
- >(parameters: useGetStream.Parameters<config, selectData> = {}) {
306
- const { id, query = {}, token } = parameters
307
-
308
- const config = useConfig(parameters)
309
- const chainId = useChainId({ config })
310
-
311
- const options = Actions.getStream.queryOptions(config, {
312
- ...parameters,
313
- chainId: parameters.chainId ?? chainId,
314
- query: undefined,
315
- } as never)
316
- const enabled = Boolean(id !== undefined && token && (query.enabled ?? true))
317
-
318
- return useQuery({ ...query, ...options, enabled })
319
- }
320
-
321
- export declare namespace useGetStream {
322
- export type Parameters<
323
- config extends Config = ResolvedRegister['config'],
324
- selectData = Actions.getStream.ReturnValue,
325
- > = ConfigParameter<config> &
326
- QueryParameter<
327
- Actions.getStream.ReturnValue,
328
- DefaultError,
329
- selectData,
330
- Actions.getStream.QueryKey<config>
331
- > &
332
- ExactPartial<
333
- Omit<
334
- Actions.getStream.queryOptions.Parameters<config, selectData>,
335
- 'query'
336
- >
337
- >
338
-
339
- export type ReturnValue<selectData = Actions.getStream.ReturnValue> =
340
- UseQueryReturnType<selectData, Error>
341
- }
342
-
343
147
  /**
344
148
  * Hook for getting the total reward per second rate.
345
149
  *
@@ -0,0 +1,159 @@
1
+ import type * as Hex from 'ox/Hex'
2
+ import * as Json from 'ox/Json'
3
+ import type * as Handler from '../server/Handler.js'
4
+ import * as Storage from '../viem/Storage.js'
5
+
6
+ export type KeyManager = {
7
+ /** Function to fetch create options for WebAuthn. */
8
+ getChallenge?:
9
+ | (() => Promise<Handler.keyManager.ChallengeResponse>)
10
+ | undefined
11
+ /** Function to fetch the public key for a credential. */
12
+ getPublicKey: (
13
+ parameters: Handler.keyManager.GetPublicKeyParameters,
14
+ ) => Promise<Hex.Hex>
15
+ /** Function to set the public key for a credential. */
16
+ setPublicKey: (
17
+ parameters: Handler.keyManager.SetPublicKeyParameters,
18
+ ) => Promise<void>
19
+ }
20
+
21
+ /** Instantiates a key manager. */
22
+ export function from<manager extends KeyManager>(manager: manager): manager {
23
+ return manager
24
+ }
25
+
26
+ /** Instantiates a key manager from a Storage instance. */
27
+ export function fromStorage(s: Storage.Storage): KeyManager {
28
+ const storage = Storage.from(s, { key: 'webAuthn:publicKey' })
29
+ return from({
30
+ async getPublicKey(parameters) {
31
+ const publicKey = await storage.getItem(parameters.credential.id)
32
+ if (!publicKey) throw new Error('publicKey not found.')
33
+ return publicKey as Hex.Hex
34
+ },
35
+ async setPublicKey(parameters) {
36
+ await storage.setItem(parameters.credential.id, parameters.publicKey)
37
+ },
38
+ })
39
+ }
40
+
41
+ /**
42
+ * Instantiates a key manager from a localStorage instance.
43
+ *
44
+ * WARNING: Do not use this in production.
45
+ * This is because we are unable to extract a user's public key after the registration
46
+ * process. If a user clears their storage, or visits the website on a different device,
47
+ * they will not be able to access their account.
48
+ *
49
+ * Instead, we recommend to set up a remote store such as [`KeyManager.http`](#http) to register
50
+ * public keys against their WebAuthn credential.
51
+ *
52
+ * @see {@link http}
53
+ *
54
+ * @deprecated
55
+ */
56
+ export function localStorage(options: Storage.localStorage.Options = {}) {
57
+ return fromStorage(Storage.localStorage(options))
58
+ }
59
+
60
+ /**
61
+ * Instantiates a key manager that uses HTTP endpoints for credential management.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * import { KeyManager } from 'tempo.ts/wagmi'
66
+ *
67
+ * const keyManager = KeyManager.http('https://api.example.com')
68
+ * ```
69
+ *
70
+ * @param url - The URL to use for the HTTP endpoints.
71
+ * @param options - Configuration options for HTTP endpoints.
72
+ * @returns A KeyManager instance that uses HTTP for credential operations.
73
+ */
74
+ export function http(
75
+ url:
76
+ | string
77
+ | {
78
+ getChallenge?: string | Request | undefined
79
+ getPublicKey?: string | Request | undefined
80
+ setPublicKey?: string | Request | undefined
81
+ },
82
+ options: http.Options = {},
83
+ ): KeyManager {
84
+ const { fetch: fetchFn = globalThis.fetch } = options
85
+ const { getChallenge, getPublicKey, setPublicKey } = (() => {
86
+ const base = typeof url === 'string' ? url : ''
87
+ const urls = typeof url === 'object' ? url : {}
88
+ return {
89
+ getChallenge: urls.getChallenge ?? `${base}/challenge`,
90
+ getPublicKey: urls.getPublicKey ?? `${base}/:credentialId`,
91
+ setPublicKey: urls.setPublicKey ?? `${base}/:credentialId`,
92
+ }
93
+ })()
94
+
95
+ return from({
96
+ async getChallenge() {
97
+ const request =
98
+ getChallenge instanceof Request
99
+ ? getChallenge
100
+ : new Request(getChallenge)
101
+
102
+ const response = await fetchFn(request)
103
+
104
+ if (!response.ok)
105
+ throw new Error(`Failed to get create options: ${response.statusText}`)
106
+ return await response.json()
107
+ },
108
+
109
+ async getPublicKey(parameters) {
110
+ const request =
111
+ getPublicKey instanceof Request
112
+ ? getPublicKey
113
+ : new Request(getPublicKey)
114
+
115
+ const response = await fetchFn(
116
+ new Request(
117
+ request.url.replace(':credentialId', parameters.credential.id),
118
+ request,
119
+ ),
120
+ )
121
+
122
+ if (!response.ok)
123
+ throw new Error(`Failed to get public key: ${response.statusText}`)
124
+ const data = await response.json()
125
+ return data.publicKey as Hex.Hex
126
+ },
127
+
128
+ async setPublicKey(parameters) {
129
+ const request =
130
+ setPublicKey instanceof Request
131
+ ? setPublicKey
132
+ : new Request(setPublicKey)
133
+
134
+ const response = await fetchFn(
135
+ new Request(
136
+ request.url.replace(':credentialId', parameters.credential.id),
137
+ request,
138
+ ),
139
+ {
140
+ method: 'POST',
141
+ headers: {
142
+ 'Content-Type': 'application/json',
143
+ },
144
+ body: Json.stringify(parameters),
145
+ },
146
+ )
147
+
148
+ if (!response.ok)
149
+ throw new Error(`Failed to set public key: ${response.statusText}`)
150
+ },
151
+ })
152
+ }
153
+
154
+ export namespace http {
155
+ export type Options = {
156
+ /** Custom fetch function. @default `globalThis.fetch`. */
157
+ fetch?: typeof fetch | undefined
158
+ }
159
+ }
@@ -1,3 +1,4 @@
1
1
  export * as Actions from './Actions/index.js'
2
2
  export { dangerous_secp256k1, webAuthn } from './Connector.js'
3
3
  export * as Hooks from './Hooks/index.js'
4
+ export * as KeyManager from './KeyManager.js'