tempo.ts 0.1.5 → 0.2.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 (297) hide show
  1. package/README.md +33 -2
  2. package/dist/chains.d.ts +509 -115
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/chains.js +20 -9
  5. package/dist/chains.js.map +1 -1
  6. package/dist/ox/Order.d.ts +92 -0
  7. package/dist/ox/Order.d.ts.map +1 -0
  8. package/dist/ox/Order.js +88 -0
  9. package/dist/ox/Order.js.map +1 -0
  10. package/dist/ox/OrdersFilters.d.ts +72 -0
  11. package/dist/ox/OrdersFilters.d.ts.map +1 -0
  12. package/dist/ox/OrdersFilters.js +100 -0
  13. package/dist/ox/OrdersFilters.js.map +1 -0
  14. package/dist/ox/Pagination.d.ts +128 -0
  15. package/dist/ox/Pagination.d.ts.map +1 -0
  16. package/dist/ox/Pagination.js +78 -0
  17. package/dist/ox/Pagination.js.map +1 -0
  18. package/dist/ox/PoolId.d.ts +18 -0
  19. package/dist/ox/PoolId.d.ts.map +1 -0
  20. package/dist/ox/PoolId.js +13 -0
  21. package/dist/ox/PoolId.js.map +1 -0
  22. package/dist/ox/RpcSchema.d.ts +32 -0
  23. package/dist/ox/RpcSchema.d.ts.map +1 -0
  24. package/dist/ox/RpcSchema.js +2 -0
  25. package/dist/ox/RpcSchema.js.map +1 -0
  26. package/dist/ox/SignatureEnvelope.d.ts +1 -1
  27. package/dist/ox/SignatureEnvelope.d.ts.map +1 -1
  28. package/dist/ox/SignatureEnvelope.js.map +1 -1
  29. package/dist/{viem → ox}/Tick.d.ts +4 -0
  30. package/dist/ox/Tick.d.ts.map +1 -0
  31. package/dist/ox/Tick.js.map +1 -0
  32. package/dist/ox/Transaction.d.ts.map +1 -1
  33. package/dist/ox/Transaction.js +2 -1
  34. package/dist/ox/Transaction.js.map +1 -1
  35. package/dist/ox/TransactionEnvelopeAA.d.ts +6 -6
  36. package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -1
  37. package/dist/ox/TransactionEnvelopeAA.js +4 -2
  38. package/dist/ox/TransactionEnvelopeAA.js.map +1 -1
  39. package/dist/ox/TransactionRequest.d.ts +4 -0
  40. package/dist/ox/TransactionRequest.d.ts.map +1 -1
  41. package/dist/ox/TransactionRequest.js.map +1 -1
  42. package/dist/ox/index.d.ts +6 -0
  43. package/dist/ox/index.d.ts.map +1 -1
  44. package/dist/ox/index.js +6 -0
  45. package/dist/ox/index.js.map +1 -1
  46. package/dist/prool/Instance.d.ts.map +1 -1
  47. package/dist/prool/Instance.js +20 -4
  48. package/dist/prool/Instance.js.map +1 -1
  49. package/dist/viem/Abis.d.ts +1469 -1082
  50. package/dist/viem/Abis.d.ts.map +1 -1
  51. package/dist/viem/Abis.js +932 -671
  52. package/dist/viem/Abis.js.map +1 -1
  53. package/dist/viem/Account.d.ts +150 -0
  54. package/dist/viem/Account.d.ts.map +1 -0
  55. package/dist/viem/Account.js +221 -0
  56. package/dist/viem/Account.js.map +1 -0
  57. package/dist/viem/Actions/amm.d.ts +144 -161
  58. package/dist/viem/Actions/amm.d.ts.map +1 -1
  59. package/dist/viem/Actions/amm.js +109 -163
  60. package/dist/viem/Actions/amm.js.map +1 -1
  61. package/dist/viem/Actions/dex.d.ts +920 -664
  62. package/dist/viem/Actions/dex.d.ts.map +1 -1
  63. package/dist/viem/Actions/dex.js +129 -30
  64. package/dist/viem/Actions/dex.js.map +1 -1
  65. package/dist/viem/Actions/faucet.d.ts +34 -0
  66. package/dist/viem/Actions/faucet.d.ts.map +1 -0
  67. package/dist/viem/Actions/faucet.js +33 -0
  68. package/dist/viem/Actions/faucet.js.map +1 -0
  69. package/dist/viem/Actions/fee.d.ts +16 -30
  70. package/dist/viem/Actions/fee.d.ts.map +1 -1
  71. package/dist/viem/Actions/fee.js +13 -13
  72. package/dist/viem/Actions/fee.js.map +1 -1
  73. package/dist/viem/Actions/index.d.ts +2 -0
  74. package/dist/viem/Actions/index.d.ts.map +1 -1
  75. package/dist/viem/Actions/index.js +2 -0
  76. package/dist/viem/Actions/index.js.map +1 -1
  77. package/dist/viem/Actions/policy.d.ts +46 -46
  78. package/dist/viem/Actions/policy.js +46 -46
  79. package/dist/viem/Actions/reward.d.ts +3236 -0
  80. package/dist/viem/Actions/reward.d.ts.map +1 -0
  81. package/dist/viem/Actions/reward.js +725 -0
  82. package/dist/viem/Actions/reward.js.map +1 -0
  83. package/dist/viem/Actions/token.d.ts +4399 -2750
  84. package/dist/viem/Actions/token.d.ts.map +1 -1
  85. package/dist/viem/Actions/token.js +361 -482
  86. package/dist/viem/Actions/token.js.map +1 -1
  87. package/dist/viem/Addresses.d.ts +1 -2
  88. package/dist/viem/Addresses.d.ts.map +1 -1
  89. package/dist/viem/Addresses.js +1 -2
  90. package/dist/viem/Addresses.js.map +1 -1
  91. package/dist/viem/Chain.d.ts +38 -12
  92. package/dist/viem/Chain.d.ts.map +1 -1
  93. package/dist/viem/Chain.js +27 -18
  94. package/dist/viem/Chain.js.map +1 -1
  95. package/dist/viem/Decorator.d.ts +1009 -428
  96. package/dist/viem/Decorator.d.ts.map +1 -1
  97. package/dist/viem/Decorator.js +17 -5
  98. package/dist/viem/Decorator.js.map +1 -1
  99. package/dist/viem/Formatters.d.ts +8 -1
  100. package/dist/viem/Formatters.d.ts.map +1 -1
  101. package/dist/viem/Formatters.js +17 -0
  102. package/dist/viem/Formatters.js.map +1 -1
  103. package/dist/viem/P256.d.ts +2 -0
  104. package/dist/viem/P256.d.ts.map +1 -0
  105. package/dist/viem/P256.js +2 -0
  106. package/dist/viem/P256.js.map +1 -0
  107. package/dist/viem/Secp256k1.d.ts +2 -0
  108. package/dist/viem/Secp256k1.d.ts.map +1 -0
  109. package/dist/viem/Secp256k1.js +2 -0
  110. package/dist/viem/Secp256k1.js.map +1 -0
  111. package/dist/viem/TokenIds.d.ts +1 -2
  112. package/dist/viem/TokenIds.d.ts.map +1 -1
  113. package/dist/viem/TokenIds.js +1 -2
  114. package/dist/viem/TokenIds.js.map +1 -1
  115. package/dist/viem/Transaction.d.ts +1 -1
  116. package/dist/viem/Transaction.d.ts.map +1 -1
  117. package/dist/viem/Transaction.js +46 -5
  118. package/dist/viem/Transaction.js.map +1 -1
  119. package/dist/viem/WebAuthnP256.d.ts +79 -0
  120. package/dist/viem/WebAuthnP256.d.ts.map +1 -0
  121. package/dist/viem/WebAuthnP256.js +95 -0
  122. package/dist/viem/WebAuthnP256.js.map +1 -0
  123. package/dist/viem/WebCryptoP256.d.ts +2 -0
  124. package/dist/viem/WebCryptoP256.d.ts.map +1 -0
  125. package/dist/viem/WebCryptoP256.js +2 -0
  126. package/dist/viem/WebCryptoP256.js.map +1 -0
  127. package/dist/viem/index.d.ts +6 -3
  128. package/dist/viem/index.d.ts.map +1 -1
  129. package/dist/viem/index.js +6 -3
  130. package/dist/viem/index.js.map +1 -1
  131. package/dist/viem/internal/account.d.ts +24 -0
  132. package/dist/viem/internal/account.d.ts.map +1 -0
  133. package/dist/viem/internal/account.js +68 -0
  134. package/dist/viem/internal/account.js.map +1 -0
  135. package/dist/viem/internal/types.d.ts +10 -0
  136. package/dist/viem/internal/types.d.ts.map +1 -1
  137. package/dist/wagmi/Actions/amm.d.ts +428 -0
  138. package/dist/wagmi/Actions/amm.d.ts.map +1 -0
  139. package/dist/wagmi/Actions/amm.js +472 -0
  140. package/dist/wagmi/Actions/amm.js.map +1 -0
  141. package/dist/wagmi/Actions/dex.d.ts +908 -0
  142. package/dist/wagmi/Actions/dex.d.ts.map +1 -0
  143. package/dist/wagmi/Actions/dex.js +1023 -0
  144. package/dist/wagmi/Actions/dex.js.map +1 -0
  145. package/dist/wagmi/Actions/faucet.d.ts +35 -0
  146. package/dist/wagmi/Actions/faucet.d.ts.map +1 -0
  147. package/dist/wagmi/Actions/faucet.js +33 -0
  148. package/dist/wagmi/Actions/faucet.js.map +1 -0
  149. package/dist/wagmi/Actions/fee.d.ts +111 -0
  150. package/dist/wagmi/Actions/fee.d.ts.map +1 -0
  151. package/dist/wagmi/Actions/fee.js +126 -0
  152. package/dist/wagmi/Actions/fee.js.map +1 -0
  153. package/dist/wagmi/Actions/index.d.ts +7 -0
  154. package/dist/wagmi/Actions/index.d.ts.map +1 -0
  155. package/dist/wagmi/Actions/index.js +7 -0
  156. package/dist/wagmi/Actions/index.js.map +1 -0
  157. package/dist/wagmi/Actions/reward.d.ts +348 -0
  158. package/dist/wagmi/Actions/reward.d.ts.map +1 -0
  159. package/dist/wagmi/Actions/reward.js +388 -0
  160. package/dist/wagmi/Actions/reward.js.map +1 -0
  161. package/dist/wagmi/Actions/token.d.ts +1546 -0
  162. package/dist/wagmi/Actions/token.d.ts.map +1 -0
  163. package/dist/wagmi/Actions/token.js +1712 -0
  164. package/dist/wagmi/Actions/token.js.map +1 -0
  165. package/dist/wagmi/Connector.d.ts +81 -0
  166. package/dist/wagmi/Connector.d.ts.map +1 -0
  167. package/dist/wagmi/Connector.js +261 -0
  168. package/dist/wagmi/Connector.js.map +1 -0
  169. package/dist/wagmi/Hooks/amm.d.ts +421 -0
  170. package/dist/wagmi/Hooks/amm.d.ts.map +1 -0
  171. package/dist/wagmi/Hooks/amm.js +504 -0
  172. package/dist/wagmi/Hooks/amm.js.map +1 -0
  173. package/dist/wagmi/Hooks/dex.d.ts +816 -0
  174. package/dist/wagmi/Hooks/dex.d.ts.map +1 -0
  175. package/dist/wagmi/Hooks/dex.js +973 -0
  176. package/dist/wagmi/Hooks/dex.js.map +1 -0
  177. package/dist/wagmi/Hooks/faucet.d.ts +39 -0
  178. package/dist/wagmi/Hooks/faucet.d.ts.map +1 -0
  179. package/dist/wagmi/Hooks/faucet.js +40 -0
  180. package/dist/wagmi/Hooks/faucet.js.map +1 -0
  181. package/dist/wagmi/Hooks/fee.d.ts +97 -0
  182. package/dist/wagmi/Hooks/fee.d.ts.map +1 -0
  183. package/dist/wagmi/Hooks/fee.js +109 -0
  184. package/dist/wagmi/Hooks/fee.js.map +1 -0
  185. package/dist/wagmi/Hooks/index.d.ts +7 -0
  186. package/dist/wagmi/Hooks/index.d.ts.map +1 -0
  187. package/dist/wagmi/Hooks/index.js +7 -0
  188. package/dist/wagmi/Hooks/index.js.map +1 -0
  189. package/dist/wagmi/Hooks/reward.d.ts +307 -0
  190. package/dist/wagmi/Hooks/reward.d.ts.map +1 -0
  191. package/dist/wagmi/Hooks/reward.js +349 -0
  192. package/dist/wagmi/Hooks/reward.js.map +1 -0
  193. package/dist/wagmi/Hooks/token.d.ts +1388 -0
  194. package/dist/wagmi/Hooks/token.d.ts.map +1 -0
  195. package/dist/wagmi/Hooks/token.js +1657 -0
  196. package/dist/wagmi/Hooks/token.js.map +1 -0
  197. package/dist/wagmi/index.d.ts +4 -0
  198. package/dist/wagmi/index.d.ts.map +1 -0
  199. package/dist/wagmi/index.js +4 -0
  200. package/dist/wagmi/index.js.map +1 -0
  201. package/package.json +54 -10
  202. package/src/chains.ts +21 -9
  203. package/src/ox/Order.test.ts +78 -0
  204. package/src/ox/Order.ts +125 -0
  205. package/src/ox/OrdersFilters.test.ts +182 -0
  206. package/src/ox/OrdersFilters.ts +125 -0
  207. package/src/ox/Pagination.test.ts +162 -0
  208. package/src/ox/Pagination.ts +164 -0
  209. package/src/ox/PoolId.test.ts +33 -0
  210. package/src/ox/PoolId.ts +27 -0
  211. package/src/ox/RpcSchema.ts +35 -0
  212. package/src/ox/SignatureEnvelope.ts +3 -1
  213. package/src/{viem → ox}/Tick.test.ts +1 -1
  214. package/src/{viem → ox}/Tick.ts +5 -0
  215. package/src/ox/Transaction.test.ts +1 -1
  216. package/src/ox/Transaction.ts +2 -1
  217. package/src/ox/TransactionEnvelopeAA.test.ts +239 -96
  218. package/src/ox/TransactionEnvelopeAA.ts +9 -7
  219. package/src/ox/TransactionRequest.ts +4 -0
  220. package/src/ox/index.ts +6 -0
  221. package/src/prool/Instance.ts +51 -37
  222. package/src/prool/internal/chain.json +104 -52
  223. package/src/tsconfig.json +9 -0
  224. package/src/viem/Abis.ts +972 -710
  225. package/src/viem/Account.ts +279 -0
  226. package/src/viem/Actions/__snapshots__/dex.test.ts.snap +850 -0
  227. package/src/viem/Actions/amm.test.ts +173 -169
  228. package/src/viem/Actions/amm.ts +131 -203
  229. package/src/viem/Actions/dex.test.ts +563 -484
  230. package/src/viem/Actions/dex.ts +203 -30
  231. package/src/viem/Actions/faucet.ts +50 -0
  232. package/src/viem/Actions/fee.test.ts +23 -34
  233. package/src/viem/Actions/fee.ts +20 -13
  234. package/src/viem/Actions/index.ts +2 -0
  235. package/src/viem/Actions/policy.test.ts +19 -33
  236. package/src/viem/Actions/policy.ts +46 -46
  237. package/src/viem/Actions/reward.test.ts +457 -0
  238. package/src/viem/Actions/reward.ts +999 -0
  239. package/src/viem/Actions/token.test.ts +453 -287
  240. package/src/viem/Actions/token.ts +605 -693
  241. package/src/viem/Addresses.ts +1 -2
  242. package/src/viem/Chain.bench-d.ts +12 -0
  243. package/src/viem/Chain.ts +70 -20
  244. package/src/viem/Decorator.bench-d.ts +1 -1
  245. package/src/viem/Decorator.test.ts +3 -1
  246. package/src/viem/Decorator.ts +1049 -442
  247. package/src/viem/Formatters.ts +31 -5
  248. package/src/viem/P256.ts +1 -0
  249. package/src/viem/Secp256k1.ts +1 -0
  250. package/src/viem/TokenIds.ts +1 -2
  251. package/src/viem/Transaction.ts +53 -7
  252. package/src/viem/WebAuthnP256.ts +140 -0
  253. package/src/viem/WebCryptoP256.ts +1 -0
  254. package/src/viem/e2e.test.ts +1126 -297
  255. package/src/viem/index.ts +6 -3
  256. package/src/viem/internal/account.ts +107 -0
  257. package/src/viem/internal/types.ts +9 -0
  258. package/src/wagmi/Actions/__snapshots__/dex.test.ts.snap +310 -0
  259. package/src/wagmi/Actions/amm.test.ts +198 -0
  260. package/src/wagmi/Actions/amm.ts +691 -0
  261. package/src/wagmi/Actions/dex.test.ts +1507 -0
  262. package/src/wagmi/Actions/dex.ts +1640 -0
  263. package/src/wagmi/Actions/faucet.ts +46 -0
  264. package/src/wagmi/Actions/fee.test.ts +63 -0
  265. package/src/wagmi/Actions/fee.ts +208 -0
  266. package/src/wagmi/Actions/index.ts +6 -0
  267. package/src/wagmi/Actions/reward.test.ts +210 -0
  268. package/src/wagmi/Actions/reward.ts +632 -0
  269. package/src/wagmi/Actions/token.test.ts +1308 -0
  270. package/src/wagmi/Actions/token.ts +2613 -0
  271. package/src/wagmi/Connector.test.ts +53 -0
  272. package/src/wagmi/Connector.ts +390 -0
  273. package/src/wagmi/Hooks/__snapshots__/dex.test.ts.snap +457 -0
  274. package/src/wagmi/Hooks/amm.test.ts +424 -0
  275. package/src/wagmi/Hooks/amm.ts +806 -0
  276. package/src/wagmi/Hooks/dex.test.ts +1017 -0
  277. package/src/wagmi/Hooks/dex.ts +1685 -0
  278. package/src/wagmi/Hooks/faucet.ts +76 -0
  279. package/src/wagmi/Hooks/fee.test.ts +166 -0
  280. package/src/wagmi/Hooks/fee.ts +206 -0
  281. package/src/wagmi/Hooks/index.ts +6 -0
  282. package/src/wagmi/Hooks/reward.test.ts +219 -0
  283. package/src/wagmi/Hooks/reward.ts +672 -0
  284. package/src/wagmi/Hooks/token.test.ts +1670 -0
  285. package/src/wagmi/Hooks/token.ts +2906 -0
  286. package/src/wagmi/index.ts +3 -0
  287. package/src/wagmi/internal/types.ts +16 -0
  288. package/dist/viem/Client.d.ts +0 -27
  289. package/dist/viem/Client.d.ts.map +0 -1
  290. package/dist/viem/Client.js +0 -28
  291. package/dist/viem/Client.js.map +0 -1
  292. package/dist/viem/Tick.d.ts.map +0 -1
  293. package/dist/viem/Tick.js.map +0 -1
  294. package/src/viem/Client.bench-d.ts +0 -8
  295. package/src/viem/Client.test.ts +0 -178
  296. package/src/viem/Client.ts +0 -91
  297. /package/dist/{viem → ox}/Tick.js +0 -0
@@ -0,0 +1,457 @@
1
+ import { parseEther, parseUnits } from 'viem'
2
+ import { describe, expect, test } from 'vitest'
3
+ import { client, setupToken } from '../../../test/viem/config.js'
4
+ import * as actions from './index.js'
5
+
6
+ const account = client.account
7
+
8
+ describe('cancelSync', () => {
9
+ test('default', async () => {
10
+ const { token } = await setupToken(client)
11
+
12
+ // Start a reward stream with longer duration
13
+ const rewardAmount = parseUnits('100', 6)
14
+ const { id: streamId } = await actions.reward.startSync(client, {
15
+ amount: rewardAmount,
16
+ seconds: 3600, // 1 hour to avoid stream ending during test
17
+ token,
18
+ })
19
+
20
+ // Cancel the reward
21
+ const { receipt, refund, ...result } = await actions.reward.cancelSync(
22
+ client,
23
+ {
24
+ id: streamId,
25
+ token,
26
+ },
27
+ )
28
+
29
+ expect(refund).toBeGreaterThan(0n)
30
+ expect(receipt).toBeDefined()
31
+ expect(result).toMatchInlineSnapshot(`
32
+ {
33
+ "funder": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
34
+ "id": 1n,
35
+ }
36
+ `)
37
+ })
38
+ })
39
+
40
+ // TODO: unskip
41
+ describe.skip('claimSync', () => {
42
+ test('default', async () => {
43
+ const { token } = await setupToken(client)
44
+
45
+ const balanceBefore = await actions.token.getBalance(client, {
46
+ token,
47
+ })
48
+
49
+ // Opt in to rewards
50
+ await actions.reward.setRecipientSync(client, {
51
+ recipient: account.address,
52
+ token,
53
+ })
54
+
55
+ // Mint reward tokens
56
+ const rewardAmount = parseUnits('100', 6)
57
+ await actions.token.mintSync(client, {
58
+ amount: rewardAmount,
59
+ to: account.address,
60
+ token,
61
+ })
62
+
63
+ // Start immediate reward to distribute rewards
64
+ await actions.reward.startSync(client, {
65
+ amount: rewardAmount,
66
+ seconds: 0,
67
+ token,
68
+ })
69
+
70
+ // Trigger reward accrual by transferring
71
+ await actions.token.transferSync(client, {
72
+ amount: 1n,
73
+ to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
74
+ token,
75
+ })
76
+
77
+ // Claim rewards
78
+ await actions.reward.claimSync(client, {
79
+ token,
80
+ })
81
+
82
+ const balanceAfter = await actions.token.getBalance(client, {
83
+ token,
84
+ })
85
+
86
+ expect(balanceAfter).toBeGreaterThan(
87
+ balanceBefore + rewardAmount - parseUnits('1', 6),
88
+ )
89
+ })
90
+
91
+ test('behavior: claiming from streaming reward', async () => {
92
+ const { token } = await setupToken(client)
93
+
94
+ const balanceBefore = await actions.token.getBalance(client, {
95
+ token,
96
+ })
97
+
98
+ // Mint tokens to have balance
99
+ const mintAmount = parseUnits('1000', 6)
100
+ await actions.token.mintSync(client, {
101
+ amount: mintAmount,
102
+ to: account.address,
103
+ token,
104
+ })
105
+
106
+ // Opt in to rewards
107
+ await actions.reward.setRecipientSync(client, {
108
+ recipient: account.address,
109
+ token,
110
+ })
111
+
112
+ // Mint reward tokens
113
+ const rewardAmount = parseUnits('100', 6)
114
+ await actions.token.mintSync(client, {
115
+ amount: rewardAmount,
116
+ to: account.address,
117
+ token,
118
+ })
119
+
120
+ // Start a streaming reward (not immediate)
121
+ await actions.reward.startSync(client, {
122
+ amount: rewardAmount,
123
+ seconds: 10,
124
+ token,
125
+ })
126
+
127
+ // Wait a bit and trigger accrual by transferring
128
+ await new Promise((resolve) => setTimeout(resolve, 2000))
129
+ await actions.token.transferSync(client, {
130
+ amount: 1n,
131
+ to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
132
+ token,
133
+ })
134
+
135
+ // Claim accumulated rewards from the stream
136
+ await actions.reward.claimSync(client, {
137
+ token,
138
+ })
139
+
140
+ const balanceAfter = await actions.token.getBalance(client, {
141
+ token,
142
+ })
143
+
144
+ // Should have accumulated some rewards (at least 10% of total after 2 seconds)
145
+ expect(balanceAfter).toBeGreaterThan(balanceBefore + rewardAmount / 10n)
146
+ })
147
+ })
148
+
149
+ describe('getStream', () => {
150
+ test('default', async () => {
151
+ const { token } = await setupToken(client)
152
+
153
+ // Start a reward stream
154
+ const rewardAmount = parseUnits('100', 6)
155
+ const duration = 10
156
+ const { id: streamId } = await actions.reward.startSync(client, {
157
+ amount: rewardAmount,
158
+ seconds: duration,
159
+ token,
160
+ })
161
+
162
+ // Get the stream
163
+ const { endTime, startTime, ...stream } = await actions.reward.getStream(
164
+ client,
165
+ {
166
+ id: streamId,
167
+ token,
168
+ },
169
+ )
170
+
171
+ expect(startTime).toBeGreaterThan(0)
172
+ expect(endTime).toBeGreaterThan(startTime)
173
+ expect(stream).toMatchInlineSnapshot(`
174
+ {
175
+ "amountTotal": 100000000n,
176
+ "funder": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
177
+ "ratePerSecondScaled": 10000000000000000000000000n,
178
+ }
179
+ `)
180
+ })
181
+
182
+ test('behavior: canceled stream has zero funder', async () => {
183
+ const { token } = await setupToken(client)
184
+
185
+ // Start and cancel a reward stream
186
+ const rewardAmount = parseUnits('100', 6)
187
+ const { id: streamId } = await actions.reward.startSync(client, {
188
+ amount: rewardAmount,
189
+ seconds: 3600, // 1 hour to avoid stream ending during test
190
+ token,
191
+ })
192
+
193
+ await actions.reward.cancelSync(client, {
194
+ id: streamId,
195
+ token,
196
+ })
197
+
198
+ // Get the canceled stream
199
+ const stream = await actions.reward.getStream(client, {
200
+ id: streamId,
201
+ token,
202
+ })
203
+
204
+ expect(stream).toMatchInlineSnapshot(`
205
+ {
206
+ "amountTotal": 0n,
207
+ "endTime": 0n,
208
+ "funder": "0x0000000000000000000000000000000000000000",
209
+ "ratePerSecondScaled": 0n,
210
+ "startTime": 0n,
211
+ }
212
+ `)
213
+ })
214
+ })
215
+
216
+ describe('getTotalPerSecond', () => {
217
+ test('default', async () => {
218
+ const { token } = await setupToken(client)
219
+
220
+ const rate = await actions.reward.getTotalPerSecond(client, {
221
+ token,
222
+ })
223
+
224
+ expect(rate).toBe(0n)
225
+ })
226
+
227
+ test('behavior: increases after starting stream', async () => {
228
+ const { token } = await setupToken(client)
229
+
230
+ // Start a reward stream
231
+ const rewardAmount = parseUnits('100', 6)
232
+ const duration = 100
233
+ await actions.reward.startSync(client, {
234
+ amount: rewardAmount,
235
+ seconds: duration,
236
+ token,
237
+ })
238
+
239
+ // Check total reward per second
240
+ const rate = await actions.reward.getTotalPerSecond(client, {
241
+ token,
242
+ })
243
+
244
+ // Expected rate = (amount * ACC_PRECISION) / seconds
245
+ // ACC_PRECISION = 1e18
246
+ const expectedRate = (rewardAmount * parseEther('1')) / BigInt(duration)
247
+ expect(rate).toBe(expectedRate)
248
+ })
249
+ })
250
+
251
+ describe('setRecipientSync', () => {
252
+ test('default', async () => {
253
+ const { token } = await setupToken(client)
254
+
255
+ // Set reward recipient to self
256
+ const { holder, receipt, recipient } =
257
+ await actions.reward.setRecipientSync(client, {
258
+ recipient: account.address,
259
+ token,
260
+ })
261
+
262
+ expect(receipt).toBeDefined()
263
+ expect(holder).toBe(account.address)
264
+ expect(recipient).toBe(account.address)
265
+ })
266
+
267
+ test('behavior: opt out with zero address', async () => {
268
+ const { token } = await setupToken(client)
269
+
270
+ // First opt in
271
+ await actions.reward.setRecipientSync(client, {
272
+ recipient: account.address,
273
+ token,
274
+ })
275
+
276
+ // Then opt out
277
+ const { holder, recipient } = await actions.reward.setRecipientSync(
278
+ client,
279
+ {
280
+ recipient: '0x0000000000000000000000000000000000000000',
281
+ token,
282
+ },
283
+ )
284
+
285
+ expect(holder).toBe(account.address)
286
+ expect(recipient).toBe('0x0000000000000000000000000000000000000000')
287
+ })
288
+ })
289
+
290
+ describe('startSync', () => {
291
+ test('default', async () => {
292
+ const { token } = await setupToken(client)
293
+
294
+ // Start a reward stream
295
+ const duration = 10
296
+ const rewardAmount = parseUnits('100', 6)
297
+ const { id, receipt, ...result } = await actions.reward.startSync(client, {
298
+ amount: rewardAmount,
299
+ seconds: duration,
300
+ token,
301
+ })
302
+
303
+ expect(receipt).toBeDefined()
304
+ expect(result).toMatchInlineSnapshot(`
305
+ {
306
+ "amount": 100000000n,
307
+ "durationSeconds": 10,
308
+ "funder": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
309
+ }
310
+ `)
311
+
312
+ // Verify the stream was created
313
+ const { endTime, startTime, ...stream } = await actions.reward.getStream(
314
+ client,
315
+ {
316
+ id,
317
+ token,
318
+ },
319
+ )
320
+
321
+ expect(startTime).toBeGreaterThan(0)
322
+ expect(endTime).toBeGreaterThan(startTime)
323
+ expect(stream).toMatchInlineSnapshot(`
324
+ {
325
+ "amountTotal": 100000000n,
326
+ "funder": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
327
+ "ratePerSecondScaled": 10000000000000000000000000n,
328
+ }
329
+ `)
330
+
331
+ // Verify total reward per second
332
+ const totalRate = await actions.reward.getTotalPerSecond(client, {
333
+ token,
334
+ })
335
+ const expectedRate = (rewardAmount * parseEther('1')) / BigInt(duration)
336
+ expect(totalRate).toBe(expectedRate)
337
+ })
338
+
339
+ test('behavior: streaming distribution', async () => {
340
+ const { token } = await setupToken(client)
341
+
342
+ // Start a streaming reward
343
+ const duration = 3600
344
+ const rewardAmount = parseUnits('100', 6)
345
+ const { id } = await actions.reward.startSync(client, {
346
+ amount: rewardAmount,
347
+ seconds: duration,
348
+ token,
349
+ })
350
+
351
+ expect(id).toBeGreaterThan(0n) // Streaming distributions return ID > 0
352
+
353
+ // Verify the stream was created with correct rate
354
+ const totalRate = await actions.reward.getTotalPerSecond(client, {
355
+ token,
356
+ })
357
+
358
+ const expectedRate = (rewardAmount * parseEther('1')) / BigInt(duration)
359
+ expect(totalRate).toBe(expectedRate)
360
+ })
361
+
362
+ // TODO: unskip
363
+ test.skip('behavior: immediate distribution (seconds = 0)', async () => {
364
+ const { token } = await setupToken(client)
365
+
366
+ // Opt in to rewards
367
+ await actions.reward.setRecipientSync(client, {
368
+ recipient: account.address,
369
+ token,
370
+ })
371
+
372
+ const balanceBeforeReward = await actions.token.getBalance(client, {
373
+ token,
374
+ })
375
+
376
+ // Mint reward tokens
377
+ const rewardAmount = parseUnits('100', 6)
378
+ await actions.token.mintSync(client, {
379
+ amount: rewardAmount,
380
+ to: account.address,
381
+ token,
382
+ })
383
+
384
+ // Start immediate reward (seconds = 0)
385
+ const { id } = await actions.reward.startSync(client, {
386
+ amount: rewardAmount,
387
+ seconds: 0,
388
+ token,
389
+ })
390
+
391
+ expect(id).toBe(0n) // Immediate distributions return ID 0
392
+
393
+ // Trigger reward distribution by transferring
394
+ await actions.token.transferSync(client, {
395
+ amount: 1n,
396
+ to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
397
+ token,
398
+ })
399
+
400
+ // Claim the accumulated rewards
401
+ await actions.reward.claimSync(client, {
402
+ token,
403
+ })
404
+
405
+ const balanceAfter = await actions.token.getBalance(client, {
406
+ token,
407
+ })
408
+
409
+ // Account should have received rewards
410
+ expect(balanceAfter).toBeGreaterThanOrEqual(
411
+ balanceBeforeReward + rewardAmount - 1n,
412
+ )
413
+
414
+ // Total reward per second should be zero for immediate distributions
415
+ const totalRate = await actions.reward.getTotalPerSecond(client, {
416
+ token,
417
+ })
418
+ expect(totalRate).toBe(0n)
419
+ })
420
+
421
+ test('behavior: immediate distribution with opted-in holders', async () => {
422
+ const { token } = await setupToken(client)
423
+
424
+ // Opt in to rewards
425
+ await actions.reward.setRecipientSync(client, {
426
+ recipient: account.address,
427
+ token,
428
+ })
429
+
430
+ // Mint reward tokens
431
+ const rewardAmount = parseUnits('100', 6)
432
+ await actions.token.mintSync(client, {
433
+ amount: rewardAmount,
434
+ to: account.address,
435
+ token,
436
+ })
437
+
438
+ // Start immediate reward
439
+ const { amount, durationSeconds, funder, id } =
440
+ await actions.reward.startSync(client, {
441
+ amount: rewardAmount,
442
+ seconds: 0,
443
+ token,
444
+ })
445
+
446
+ expect(id).toBe(0n) // Immediate distributions return ID 0
447
+ expect(funder).toBe(account.address)
448
+ expect(amount).toBe(rewardAmount)
449
+ expect(durationSeconds).toBe(0)
450
+
451
+ // Total reward per second should be zero for immediate distributions
452
+ const totalRate = await actions.reward.getTotalPerSecond(client, {
453
+ token,
454
+ })
455
+ expect(totalRate).toBe(0n)
456
+ })
457
+ })