tempo.ts 0.6.1 → 0.7.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 (113) 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/account.d.ts +40 -0
  22. package/dist/viem/Actions/account.d.ts.map +1 -0
  23. package/dist/viem/Actions/account.js +87 -0
  24. package/dist/viem/Actions/account.js.map +1 -0
  25. package/dist/viem/Actions/amm.d.ts +51 -1245
  26. package/dist/viem/Actions/amm.d.ts.map +1 -1
  27. package/dist/viem/Actions/amm.js +15 -478
  28. package/dist/viem/Actions/amm.js.map +1 -1
  29. package/dist/viem/Actions/index.d.ts +1 -0
  30. package/dist/viem/Actions/index.d.ts.map +1 -1
  31. package/dist/viem/Actions/index.js +1 -0
  32. package/dist/viem/Actions/index.js.map +1 -1
  33. package/dist/viem/Actions/reward.d.ts +0 -1067
  34. package/dist/viem/Actions/reward.d.ts.map +1 -1
  35. package/dist/viem/Actions/reward.js +4 -212
  36. package/dist/viem/Actions/reward.js.map +1 -1
  37. package/dist/viem/Decorator.d.ts +28 -263
  38. package/dist/viem/Decorator.d.ts.map +1 -1
  39. package/dist/viem/Decorator.js +2 -10
  40. package/dist/viem/Decorator.js.map +1 -1
  41. package/dist/viem/Storage.d.ts +23 -0
  42. package/dist/viem/Storage.d.ts.map +1 -0
  43. package/dist/viem/Storage.js +47 -0
  44. package/dist/viem/Storage.js.map +1 -0
  45. package/dist/viem/Transport.d.ts +10 -1
  46. package/dist/viem/Transport.d.ts.map +1 -1
  47. package/dist/viem/Transport.js +22 -3
  48. package/dist/viem/Transport.js.map +1 -1
  49. package/dist/viem/internal/utils.d.ts +6 -0
  50. package/dist/viem/internal/utils.d.ts.map +1 -1
  51. package/dist/viem/internal/utils.js +24 -0
  52. package/dist/viem/internal/utils.js.map +1 -1
  53. package/dist/wagmi/Actions/amm.d.ts +0 -225
  54. package/dist/wagmi/Actions/amm.d.ts.map +1 -1
  55. package/dist/wagmi/Actions/amm.js +0 -248
  56. package/dist/wagmi/Actions/amm.js.map +1 -1
  57. package/dist/wagmi/Actions/reward.d.ts +0 -110
  58. package/dist/wagmi/Actions/reward.d.ts.map +1 -1
  59. package/dist/wagmi/Actions/reward.js +0 -121
  60. package/dist/wagmi/Actions/reward.js.map +1 -1
  61. package/dist/wagmi/Connector.d.ts +6 -17
  62. package/dist/wagmi/Connector.d.ts.map +1 -1
  63. package/dist/wagmi/Connector.js +17 -43
  64. package/dist/wagmi/Connector.js.map +1 -1
  65. package/dist/wagmi/Hooks/amm.d.ts +0 -236
  66. package/dist/wagmi/Hooks/amm.d.ts.map +1 -1
  67. package/dist/wagmi/Hooks/amm.js +0 -285
  68. package/dist/wagmi/Hooks/amm.js.map +1 -1
  69. package/dist/wagmi/Hooks/reward.d.ts +0 -88
  70. package/dist/wagmi/Hooks/reward.d.ts.map +1 -1
  71. package/dist/wagmi/Hooks/reward.js +0 -103
  72. package/dist/wagmi/Hooks/reward.js.map +1 -1
  73. package/dist/wagmi/KeyManager.d.ts +57 -0
  74. package/dist/wagmi/KeyManager.d.ts.map +1 -0
  75. package/dist/wagmi/KeyManager.js +101 -0
  76. package/dist/wagmi/KeyManager.js.map +1 -0
  77. package/dist/wagmi/index.d.ts +1 -0
  78. package/dist/wagmi/index.d.ts.map +1 -1
  79. package/dist/wagmi/index.js +1 -0
  80. package/dist/wagmi/index.js.map +1 -1
  81. package/package.json +8 -2
  82. package/src/ox/Transaction.ts +1 -1
  83. package/src/ox/e2e.test.ts +7 -0
  84. package/src/server/Handler.test.ts +566 -0
  85. package/src/server/Handler.ts +577 -0
  86. package/src/server/Kv.ts +40 -0
  87. package/src/server/index.ts +2 -0
  88. package/src/server/internal/requestListener.ts +285 -0
  89. package/src/viem/Actions/account.test.ts +414 -0
  90. package/src/viem/Actions/account.ts +108 -0
  91. package/src/viem/Actions/amm.test.ts +10 -284
  92. package/src/viem/Actions/amm.ts +88 -768
  93. package/src/viem/Actions/index.ts +1 -0
  94. package/src/viem/Actions/reward.test.ts +4 -212
  95. package/src/viem/Actions/reward.ts +4 -291
  96. package/src/viem/Decorator.test.ts +1 -0
  97. package/src/viem/Decorator.ts +32 -294
  98. package/src/viem/Storage.ts +88 -0
  99. package/src/viem/Transport.ts +40 -2
  100. package/src/viem/e2e.test.ts +106 -3
  101. package/src/viem/internal/utils.ts +21 -0
  102. package/src/wagmi/Actions/amm.test.ts +7 -85
  103. package/src/wagmi/Actions/amm.ts +0 -346
  104. package/src/wagmi/Actions/reward.test.ts +0 -99
  105. package/src/wagmi/Actions/reward.ts +0 -203
  106. package/src/wagmi/Connector.test.ts +4 -1
  107. package/src/wagmi/Connector.ts +24 -58
  108. package/src/wagmi/Hooks/amm.test.ts +8 -200
  109. package/src/wagmi/Hooks/amm.ts +0 -443
  110. package/src/wagmi/Hooks/reward.test.ts +1 -142
  111. package/src/wagmi/Hooks/reward.ts +0 -196
  112. package/src/wagmi/KeyManager.ts +159 -0
  113. package/src/wagmi/index.ts +1 -0
@@ -0,0 +1,108 @@
1
+ import { Secp256k1 } from 'ox'
2
+ import * as Hex from 'ox/Hex'
3
+ import * as P256 from 'ox/P256'
4
+ import * as WebAuthnP256 from 'ox/WebAuthnP256'
5
+ import type { Chain, Client, Transport } from 'viem'
6
+ import type { VerifyHashParameters, VerifyHashReturnType } from 'viem/actions'
7
+ import { verifyHash as viem_verifyHash } from 'viem/actions'
8
+ import { getAction } from 'viem/utils'
9
+ import type { PartialBy } from '../../internal/types.js'
10
+ import * as SignatureEnvelope from '../../ox/SignatureEnvelope.js'
11
+
12
+ /**
13
+ * Verifies that a signature is valid for a given hash and address.
14
+ * Supports multiple signature types: Secp256k1, P256, WebCrypto P256, and WebAuthn P256.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { createClient, http } from 'viem'
19
+ * import { tempo } from 'tempo.ts/chains'
20
+ * import { Actions, Account, P256 } from 'tempo.ts/viem'
21
+ *
22
+ * const client = createClient({
23
+ * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })
24
+ * transport: http(),
25
+ * })
26
+ *
27
+ * const privateKey = P256.randomPrivateKey()
28
+ * const account = Account.fromP256(privateKey)
29
+ *
30
+ * const hash = '0x...'
31
+ * const signature = await account.sign({ hash })
32
+ *
33
+ * const valid = await Actions.verifyHash(client, {
34
+ * hash,
35
+ * signature,
36
+ * })
37
+ * ```
38
+ *
39
+ * @param client - Client.
40
+ * @param parameters - Parameters.
41
+ * @returns Whether the signature is valid.
42
+ */
43
+ export async function verifyHash<chain extends Chain | undefined>(
44
+ client: Client<Transport, chain>,
45
+ parameters: verifyHash.Parameters,
46
+ ): Promise<verifyHash.ReturnValue> {
47
+ const { hash } = parameters
48
+
49
+ const signature = (() => {
50
+ const signature = parameters.signature
51
+ if (Hex.validate(signature)) return signature
52
+ if (typeof signature === 'object' && 'r' in signature && 's' in signature)
53
+ return SignatureEnvelope.serialize({
54
+ type: 'secp256k1',
55
+ signature: {
56
+ r: BigInt(signature.r),
57
+ s: BigInt(signature.s),
58
+ yParity: signature.yParity!,
59
+ },
60
+ })
61
+ return Hex.fromBytes(signature)
62
+ })()
63
+
64
+ const [envelope, userAddress] = (() => {
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]
69
+ return [envelope, undefined]
70
+ })()
71
+
72
+ if (envelope.type === 'p256')
73
+ return P256.verify({
74
+ payload: hash,
75
+ publicKey: envelope.publicKey,
76
+ signature: envelope.signature,
77
+ hash: envelope.prehash,
78
+ })
79
+ if (envelope.type === 'webAuthn')
80
+ return WebAuthnP256.verify({
81
+ challenge: hash,
82
+ metadata: envelope.metadata,
83
+ publicKey: envelope.publicKey,
84
+ signature: envelope.signature,
85
+ })
86
+ // TODO: add once we have key auth
87
+ // if (envelope.type === 'keychain') throw new Error('not supported')
88
+
89
+ const address =
90
+ parameters.address ??
91
+ userAddress ??
92
+ Secp256k1.recoverAddress({
93
+ payload: hash,
94
+ signature: envelope.signature,
95
+ })
96
+
97
+ return await getAction(
98
+ client,
99
+ viem_verifyHash,
100
+ 'verifyHash',
101
+ )({ ...parameters, address } as never)
102
+ }
103
+
104
+ export declare namespace verifyHash {
105
+ export type Parameters = PartialBy<VerifyHashParameters, 'address'>
106
+
107
+ export type ReturnValue = VerifyHashReturnType
108
+ }
@@ -3,14 +3,9 @@ import { Abis, Actions } from 'tempo.ts/viem'
3
3
  import { parseUnits } from 'viem'
4
4
  import { writeContractSync } from 'viem/actions'
5
5
  import { describe, expect, test } from 'vitest'
6
- import {
7
- accounts,
8
- clientWithAccount,
9
- setupPoolWithLiquidity,
10
- } from '../../../test/viem/config.js'
6
+ import { accounts, clientWithAccount } from '../../../test/viem/config.js'
11
7
 
12
8
  const account = accounts[0]
13
- const account2 = accounts[1]
14
9
 
15
10
  describe('getPool', () => {
16
11
  test('default', async () => {
@@ -41,78 +36,6 @@ describe('getLiquidityBalance', () => {
41
36
 
42
37
  describe('mint', () => {
43
38
  test('default', async () => {
44
- // Create a new token for testing
45
- const { token } = await Actions.token.createSync(clientWithAccount, {
46
- name: 'Test Token',
47
- symbol: 'TEST',
48
- currency: 'USD',
49
- })
50
-
51
- // Grant issuer role to mint tokens
52
- await Actions.token.grantRolesSync(clientWithAccount, {
53
- token,
54
- roles: ['issuer'],
55
- to: clientWithAccount.account.address,
56
- })
57
-
58
- // Mint some tokens to account
59
- await Actions.token.mintSync(clientWithAccount, {
60
- to: clientWithAccount.account.address,
61
- amount: parseUnits('1000', 6),
62
- token,
63
- })
64
-
65
- // Add liquidity to pool
66
- const { receipt: mintReceipt, ...mintResult } = await Actions.amm.mintSync(
67
- clientWithAccount,
68
- {
69
- userToken: {
70
- address: token,
71
- amount: parseUnits('100', 6),
72
- },
73
- validatorToken: {
74
- address: 1n,
75
- amount: parseUnits('100', 6),
76
- },
77
- to: account.address,
78
- },
79
- )
80
- const { sender, userToken, ...rest } = mintResult
81
- expect(mintReceipt).toBeDefined()
82
- expect(sender).toBe(clientWithAccount.account.address)
83
- expect(userToken).toBe(token)
84
- expect(rest).toMatchInlineSnapshot(`
85
- {
86
- "amountUserToken": 100000000n,
87
- "amountValidatorToken": 100000000n,
88
- "liquidity": 4999999999999000n,
89
- "validatorToken": "0x20C0000000000000000000000000000000000001",
90
- }
91
- `)
92
-
93
- // Verify pool reserves
94
- const pool = await Actions.amm.getPool(clientWithAccount, {
95
- userToken: token,
96
- validatorToken: 1n,
97
- })
98
- expect(pool).toMatchInlineSnapshot(`
99
- {
100
- "reserveUserToken": 100000000n,
101
- "reserveValidatorToken": 100000000n,
102
- "totalSupply": 5000000000000000n,
103
- }
104
- `)
105
-
106
- // Verify LP token balance
107
- const lpBalance = await Actions.amm.getLiquidityBalance(clientWithAccount, {
108
- address: account.address,
109
- userToken: token,
110
- validatorToken: 1n,
111
- })
112
- expect(lpBalance).toBeGreaterThan(0n)
113
- })
114
-
115
- test('behavior: single-sided mint (mintWithValidatorToken)', async () => {
116
39
  // Create a new token for testing
117
40
  const { token } = await Actions.token.createSync(clientWithAccount, {
118
41
  name: 'Test Token 2',
@@ -136,15 +59,10 @@ describe('mint', () => {
136
59
 
137
60
  // First, establish initial liquidity with two-sided mint
138
61
  await Actions.amm.mintSync(clientWithAccount, {
139
- userToken: {
140
- address: token,
141
- amount: parseUnits('100', 6),
142
- },
143
- validatorToken: {
144
- address: 1n,
145
- amount: parseUnits('100', 6),
146
- },
147
62
  to: account.address,
63
+ userTokenAddress: token,
64
+ validatorTokenAddress: 1n,
65
+ validatorTokenAmount: parseUnits('100', 6),
148
66
  })
149
67
 
150
68
  // Get initial pool state
@@ -157,13 +75,9 @@ describe('mint', () => {
157
75
  const { receipt: mintReceipt, ...mintResult } = await Actions.amm.mintSync(
158
76
  clientWithAccount,
159
77
  {
160
- userToken: {
161
- address: token,
162
- },
163
- validatorToken: {
164
- address: 1n,
165
- amount: parseUnits('50', 6),
166
- },
78
+ userTokenAddress: token,
79
+ validatorTokenAddress: 1n,
80
+ validatorTokenAmount: parseUnits('50', 6),
167
81
  to: account.address,
168
82
  },
169
83
  )
@@ -188,149 +102,6 @@ describe('mint', () => {
188
102
  })
189
103
  })
190
104
 
191
- describe('burn', () => {
192
- test('default', async () => {
193
- const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
194
-
195
- // Get LP balance before burn
196
- const lpBalanceBefore = await Actions.amm.getLiquidityBalance(
197
- clientWithAccount,
198
- {
199
- address: account.address,
200
- userToken: tokenAddress,
201
- validatorToken: 1n,
202
- },
203
- )
204
-
205
- // Burn half of LP tokens
206
- const {
207
- receipt: burnReceipt,
208
- userToken,
209
- ...burnResult
210
- } = await Actions.amm.burnSync(clientWithAccount, {
211
- userToken: tokenAddress,
212
- validatorToken: 1n,
213
- liquidity: lpBalanceBefore / 2n,
214
- to: account2.address,
215
- })
216
- const { sender, to, ...rest } = burnResult
217
-
218
- expect(burnReceipt).toBeDefined()
219
- expect(userToken).toBe(tokenAddress)
220
- expect(sender).toBe(account.address)
221
- expect(to).toBe(account2.address)
222
- expect(rest).toMatchInlineSnapshot(`
223
- {
224
- "amountUserToken": 49999999n,
225
- "amountValidatorToken": 49999999n,
226
- "liquidity": 2499999999999500n,
227
- "validatorToken": "0x20C0000000000000000000000000000000000001",
228
- }
229
- `)
230
-
231
- // Verify LP balance decreased
232
- const lpBalanceAfter = await Actions.amm.getLiquidityBalance(
233
- clientWithAccount,
234
- {
235
- address: account.address,
236
- userToken: tokenAddress,
237
- validatorToken: 1n,
238
- },
239
- )
240
- expect(lpBalanceAfter).toBeLessThan(lpBalanceBefore)
241
- expect(lpBalanceAfter).toBe(lpBalanceBefore / 2n)
242
-
243
- // Verify pool reserves decreased
244
- const pool = await Actions.amm.getPool(clientWithAccount, {
245
- userToken: tokenAddress,
246
- validatorToken: 1n,
247
- })
248
- expect(pool).toMatchInlineSnapshot(`
249
- {
250
- "reserveUserToken": 50000001n,
251
- "reserveValidatorToken": 50000001n,
252
- "totalSupply": 2500000000000500n,
253
- }
254
- `)
255
- })
256
- })
257
-
258
- describe('rebalanceSwap', () => {
259
- test('default', async () => {
260
- const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
261
-
262
- // Get balance before swap
263
- const balanceBefore = await Actions.token.getBalance(clientWithAccount, {
264
- token: tokenAddress,
265
- account: account2.address,
266
- })
267
-
268
- // Perform rebalance swap
269
- const {
270
- receipt: swapReceipt,
271
- swapper,
272
- userToken,
273
- ...swapResult
274
- } = await Actions.amm.rebalanceSwapSync(clientWithAccount, {
275
- userToken: tokenAddress,
276
- validatorToken: 1n,
277
- amountOut: parseUnits('10', 6),
278
- to: account2.address,
279
- account: account,
280
- })
281
- expect(swapReceipt).toBeDefined()
282
- expect(userToken).toBe(tokenAddress)
283
- expect(swapper).toBe(account.address)
284
- expect(swapResult).toMatchInlineSnapshot(`
285
- {
286
- "amountIn": 9985001n,
287
- "amountOut": 10000000n,
288
- "validatorToken": "0x20C0000000000000000000000000000000000001",
289
- }
290
- `)
291
-
292
- // Verify balance increased
293
- const balanceAfter = await Actions.token.getBalance(clientWithAccount, {
294
- token: tokenAddress,
295
- account: account2.address,
296
- })
297
- expect(balanceAfter).toBe(balanceBefore + parseUnits('10', 6))
298
- })
299
- })
300
-
301
- describe('watchRebalanceSwap', () => {
302
- test('default', async () => {
303
- const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
304
-
305
- let eventArgs: any = null
306
- const unwatch = Actions.amm.watchRebalanceSwap(clientWithAccount, {
307
- onRebalanceSwap: (args) => {
308
- eventArgs = args
309
- },
310
- })
311
-
312
- // Perform rebalance swap
313
- await Actions.amm.rebalanceSwapSync(clientWithAccount, {
314
- userToken: tokenAddress,
315
- validatorToken: 1n,
316
- amountOut: parseUnits('10', 6),
317
- to: account2.address,
318
- account: account,
319
- })
320
-
321
- await setTimeout(1000)
322
-
323
- expect(eventArgs).toBeDefined()
324
- expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase())
325
- expect(eventArgs.validatorToken.toLowerCase()).toBe(
326
- '0x20c0000000000000000000000000000000000001',
327
- )
328
- expect(eventArgs.amountOut).toBe(parseUnits('10', 6))
329
-
330
- unwatch()
331
- })
332
- })
333
-
334
105
  describe('watchMint', () => {
335
106
  test('default', async () => {
336
107
  // Create a new token for testing
@@ -371,14 +142,9 @@ describe('watchMint', () => {
371
142
 
372
143
  // Add liquidity to pool
373
144
  await Actions.amm.mintSync(clientWithAccount, {
374
- userToken: {
375
- address: token,
376
- amount: parseUnits('100', 6),
377
- },
378
- validatorToken: {
379
- address: 1n,
380
- amount: parseUnits('100', 6),
381
- },
145
+ userTokenAddress: token,
146
+ validatorTokenAddress: 1n,
147
+ validatorTokenAmount: parseUnits('100', 6),
382
148
  to: account.address,
383
149
  })
384
150
 
@@ -389,48 +155,8 @@ describe('watchMint', () => {
389
155
  expect(eventArgs.validatorToken.address.toLowerCase()).toBe(
390
156
  '0x20c0000000000000000000000000000000000001',
391
157
  )
392
- expect(eventArgs.userToken.amount).toBe(parseUnits('100', 6))
393
158
  expect(eventArgs.validatorToken.amount).toBe(parseUnits('100', 6))
394
159
 
395
160
  unwatch()
396
161
  })
397
162
  })
398
-
399
- describe('watchBurn', () => {
400
- test('default', async () => {
401
- const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
402
-
403
- // Get LP balance
404
- const lpBalance = await Actions.amm.getLiquidityBalance(clientWithAccount, {
405
- userToken: tokenAddress,
406
- validatorToken: 1n,
407
- address: account.address,
408
- })
409
-
410
- let eventArgs: any = null
411
- const unwatch = Actions.amm.watchBurn(clientWithAccount, {
412
- onBurn: (args) => {
413
- eventArgs = args
414
- },
415
- })
416
-
417
- // Burn LP tokens
418
- await Actions.amm.burnSync(clientWithAccount, {
419
- userToken: tokenAddress,
420
- validatorToken: 1n,
421
- liquidity: lpBalance / 2n,
422
- to: account.address,
423
- })
424
-
425
- await setTimeout(1000)
426
-
427
- expect(eventArgs).toBeDefined()
428
- expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase())
429
- expect(eventArgs.validatorToken.toLowerCase()).toBe(
430
- '0x20c0000000000000000000000000000000000001',
431
- )
432
- expect(eventArgs.liquidity).toBe(lpBalance / 2n)
433
-
434
- unwatch()
435
- })
436
- })