tempo.ts 0.11.1 → 0.12.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 (228) hide show
  1. package/CHANGELOG.md +61 -4
  2. package/README.md +3 -34
  3. package/dist/server/Handler.d.ts +14 -14
  4. package/dist/server/Handler.d.ts.map +1 -1
  5. package/dist/server/Handler.js +16 -17
  6. package/dist/server/Handler.js.map +1 -1
  7. package/dist/wagmi/Actions/amm.d.ts +51 -51
  8. package/dist/wagmi/Actions/amm.d.ts.map +1 -1
  9. package/dist/wagmi/Actions/amm.js +37 -37
  10. package/dist/wagmi/Actions/amm.js.map +1 -1
  11. package/dist/wagmi/Actions/dex.d.ts +129 -129
  12. package/dist/wagmi/Actions/dex.d.ts.map +1 -1
  13. package/dist/wagmi/Actions/dex.js +73 -73
  14. package/dist/wagmi/Actions/dex.js.map +1 -1
  15. package/dist/wagmi/Actions/faucet.d.ts +9 -9
  16. package/dist/wagmi/Actions/faucet.d.ts.map +1 -1
  17. package/dist/wagmi/Actions/faucet.js +7 -7
  18. package/dist/wagmi/Actions/faucet.js.map +1 -1
  19. package/dist/wagmi/Actions/fee.d.ts +17 -17
  20. package/dist/wagmi/Actions/fee.d.ts.map +1 -1
  21. package/dist/wagmi/Actions/fee.js +10 -10
  22. package/dist/wagmi/Actions/fee.js.map +1 -1
  23. package/dist/wagmi/Actions/nonce.d.ts +9 -79
  24. package/dist/wagmi/Actions/nonce.d.ts.map +1 -1
  25. package/dist/wagmi/Actions/nonce.js +7 -89
  26. package/dist/wagmi/Actions/nonce.js.map +1 -1
  27. package/dist/wagmi/Actions/policy.d.ts +69 -70
  28. package/dist/wagmi/Actions/policy.d.ts.map +1 -1
  29. package/dist/wagmi/Actions/policy.js +43 -43
  30. package/dist/wagmi/Actions/policy.js.map +1 -1
  31. package/dist/wagmi/Actions/reward.d.ts +51 -51
  32. package/dist/wagmi/Actions/reward.d.ts.map +1 -1
  33. package/dist/wagmi/Actions/reward.js +31 -31
  34. package/dist/wagmi/Actions/reward.js.map +1 -1
  35. package/dist/wagmi/Actions/token.d.ts +238 -238
  36. package/dist/wagmi/Actions/token.d.ts.map +1 -1
  37. package/dist/wagmi/Actions/token.js +136 -136
  38. package/dist/wagmi/Actions/token.js.map +1 -1
  39. package/dist/wagmi/Connector.d.ts +2 -1
  40. package/dist/wagmi/Connector.d.ts.map +1 -1
  41. package/dist/wagmi/Connector.js +83 -22
  42. package/dist/wagmi/Connector.js.map +1 -1
  43. package/dist/wagmi/Hooks/nonce.d.ts +1 -52
  44. package/dist/wagmi/Hooks/nonce.d.ts.map +1 -1
  45. package/dist/wagmi/Hooks/nonce.js +1 -70
  46. package/dist/wagmi/Hooks/nonce.js.map +1 -1
  47. package/dist/wagmi/Hooks/policy.d.ts +0 -1
  48. package/dist/wagmi/Hooks/policy.d.ts.map +1 -1
  49. package/dist/wagmi/Hooks/policy.js.map +1 -1
  50. package/dist/wagmi/KeyManager.d.ts +6 -3
  51. package/dist/wagmi/KeyManager.d.ts.map +1 -1
  52. package/dist/wagmi/KeyManager.js +9 -4
  53. package/dist/wagmi/KeyManager.js.map +1 -1
  54. package/package.json +2 -12
  55. package/src/server/Handler.test.ts +2 -2
  56. package/src/server/Handler.ts +16 -17
  57. package/src/wagmi/Actions/amm.ts +63 -63
  58. package/src/wagmi/Actions/dex.test.ts +1 -1
  59. package/src/wagmi/Actions/dex.ts +153 -153
  60. package/src/wagmi/Actions/faucet.ts +11 -11
  61. package/src/wagmi/Actions/fee.ts +20 -20
  62. package/src/wagmi/Actions/nonce.test.ts +1 -64
  63. package/src/wagmi/Actions/nonce.ts +10 -142
  64. package/src/wagmi/Actions/policy.ts +83 -85
  65. package/src/wagmi/Actions/reward.ts +64 -61
  66. package/src/wagmi/Actions/token.ts +287 -283
  67. package/src/wagmi/Connector.ts +105 -31
  68. package/src/wagmi/Hooks/dex.test.ts +1 -1
  69. package/src/wagmi/Hooks/fee.test.ts +0 -6
  70. package/src/wagmi/Hooks/nonce.test.ts +1 -66
  71. package/src/wagmi/Hooks/nonce.ts +1 -114
  72. package/src/wagmi/Hooks/policy.ts +0 -2
  73. package/src/wagmi/KeyManager.ts +18 -5
  74. package/dist/chains.d.ts +0 -73
  75. package/dist/chains.d.ts.map +0 -1
  76. package/dist/chains.js +0 -51
  77. package/dist/chains.js.map +0 -1
  78. package/dist/viem/Abis.d.ts +0 -2649
  79. package/dist/viem/Abis.d.ts.map +0 -1
  80. package/dist/viem/Abis.js +0 -1677
  81. package/dist/viem/Abis.js.map +0 -1
  82. package/dist/viem/Account.d.ts +0 -244
  83. package/dist/viem/Account.d.ts.map +0 -1
  84. package/dist/viem/Account.js +0 -382
  85. package/dist/viem/Account.js.map +0 -1
  86. package/dist/viem/Actions/account.d.ts +0 -40
  87. package/dist/viem/Actions/account.d.ts.map +0 -1
  88. package/dist/viem/Actions/account.js +0 -86
  89. package/dist/viem/Actions/account.js.map +0 -1
  90. package/dist/viem/Actions/amm.d.ts +0 -1991
  91. package/dist/viem/Actions/amm.d.ts.map +0 -1
  92. package/dist/viem/Actions/amm.js +0 -814
  93. package/dist/viem/Actions/amm.js.map +0 -1
  94. package/dist/viem/Actions/dex.d.ts +0 -3900
  95. package/dist/viem/Actions/dex.d.ts.map +0 -1
  96. package/dist/viem/Actions/dex.js +0 -1414
  97. package/dist/viem/Actions/dex.js.map +0 -1
  98. package/dist/viem/Actions/faucet.d.ts +0 -69
  99. package/dist/viem/Actions/faucet.d.ts.map +0 -1
  100. package/dist/viem/Actions/faucet.js +0 -73
  101. package/dist/viem/Actions/faucet.js.map +0 -1
  102. package/dist/viem/Actions/fee.d.ts +0 -360
  103. package/dist/viem/Actions/fee.d.ts.map +0 -1
  104. package/dist/viem/Actions/fee.js +0 -237
  105. package/dist/viem/Actions/fee.js.map +0 -1
  106. package/dist/viem/Actions/index.d.ts +0 -10
  107. package/dist/viem/Actions/index.d.ts.map +0 -1
  108. package/dist/viem/Actions/index.js +0 -10
  109. package/dist/viem/Actions/index.js.map +0 -1
  110. package/dist/viem/Actions/nonce.d.ts +0 -257
  111. package/dist/viem/Actions/nonce.d.ts.map +0 -1
  112. package/dist/viem/Actions/nonce.js +0 -228
  113. package/dist/viem/Actions/nonce.js.map +0 -1
  114. package/dist/viem/Actions/policy.d.ts +0 -1680
  115. package/dist/viem/Actions/policy.d.ts.map +0 -1
  116. package/dist/viem/Actions/policy.js +0 -875
  117. package/dist/viem/Actions/policy.js.map +0 -1
  118. package/dist/viem/Actions/reward.d.ts +0 -2422
  119. package/dist/viem/Actions/reward.d.ts.map +0 -1
  120. package/dist/viem/Actions/reward.js +0 -651
  121. package/dist/viem/Actions/reward.js.map +0 -1
  122. package/dist/viem/Actions/token.d.ts +0 -16007
  123. package/dist/viem/Actions/token.d.ts.map +0 -1
  124. package/dist/viem/Actions/token.js +0 -2936
  125. package/dist/viem/Actions/token.js.map +0 -1
  126. package/dist/viem/Addresses.d.ts +0 -9
  127. package/dist/viem/Addresses.d.ts.map +0 -1
  128. package/dist/viem/Addresses.js +0 -9
  129. package/dist/viem/Addresses.js.map +0 -1
  130. package/dist/viem/Chain.d.ts +0 -451
  131. package/dist/viem/Chain.d.ts.map +0 -1
  132. package/dist/viem/Chain.js +0 -96
  133. package/dist/viem/Chain.js.map +0 -1
  134. package/dist/viem/Decorator.d.ts +0 -2783
  135. package/dist/viem/Decorator.d.ts.map +0 -1
  136. package/dist/viem/Decorator.js +0 -137
  137. package/dist/viem/Decorator.js.map +0 -1
  138. package/dist/viem/Formatters.d.ts +0 -10
  139. package/dist/viem/Formatters.d.ts.map +0 -1
  140. package/dist/viem/Formatters.js +0 -104
  141. package/dist/viem/Formatters.js.map +0 -1
  142. package/dist/viem/P256.d.ts +0 -2
  143. package/dist/viem/P256.d.ts.map +0 -1
  144. package/dist/viem/P256.js +0 -2
  145. package/dist/viem/P256.js.map +0 -1
  146. package/dist/viem/Secp256k1.d.ts +0 -2
  147. package/dist/viem/Secp256k1.d.ts.map +0 -1
  148. package/dist/viem/Secp256k1.js +0 -2
  149. package/dist/viem/Secp256k1.js.map +0 -1
  150. package/dist/viem/Storage.d.ts +0 -24
  151. package/dist/viem/Storage.d.ts.map +0 -1
  152. package/dist/viem/Storage.js +0 -68
  153. package/dist/viem/Storage.js.map +0 -1
  154. package/dist/viem/TokenIds.d.ts +0 -2
  155. package/dist/viem/TokenIds.d.ts.map +0 -1
  156. package/dist/viem/TokenIds.js +0 -2
  157. package/dist/viem/TokenIds.js.map +0 -1
  158. package/dist/viem/Transaction.d.ts +0 -76
  159. package/dist/viem/Transaction.d.ts.map +0 -1
  160. package/dist/viem/Transaction.js +0 -176
  161. package/dist/viem/Transaction.js.map +0 -1
  162. package/dist/viem/Transport.d.ts +0 -33
  163. package/dist/viem/Transport.d.ts.map +0 -1
  164. package/dist/viem/Transport.js +0 -138
  165. package/dist/viem/Transport.js.map +0 -1
  166. package/dist/viem/WebAuthnP256.d.ts +0 -82
  167. package/dist/viem/WebAuthnP256.d.ts.map +0 -1
  168. package/dist/viem/WebAuthnP256.js +0 -97
  169. package/dist/viem/WebAuthnP256.js.map +0 -1
  170. package/dist/viem/WebCryptoP256.d.ts +0 -2
  171. package/dist/viem/WebCryptoP256.d.ts.map +0 -1
  172. package/dist/viem/WebCryptoP256.js +0 -2
  173. package/dist/viem/WebCryptoP256.js.map +0 -1
  174. package/dist/viem/index.d.ts +0 -26
  175. package/dist/viem/index.d.ts.map +0 -1
  176. package/dist/viem/index.js +0 -17
  177. package/dist/viem/index.js.map +0 -1
  178. package/dist/viem/internal/types.d.ts +0 -20
  179. package/dist/viem/internal/types.d.ts.map +0 -1
  180. package/dist/viem/internal/types.js +0 -2
  181. package/dist/viem/internal/types.js.map +0 -1
  182. package/dist/viem/internal/utils.d.ts +0 -14
  183. package/dist/viem/internal/utils.d.ts.map +0 -1
  184. package/dist/viem/internal/utils.js +0 -33
  185. package/dist/viem/internal/utils.js.map +0 -1
  186. package/src/chains.ts +0 -54
  187. package/src/viem/Abis.ts +0 -1688
  188. package/src/viem/Account.test.ts +0 -444
  189. package/src/viem/Account.ts +0 -601
  190. package/src/viem/Actions/account.test.ts +0 -414
  191. package/src/viem/Actions/account.ts +0 -106
  192. package/src/viem/Actions/amm.test.ts +0 -381
  193. package/src/viem/Actions/amm.ts +0 -1227
  194. package/src/viem/Actions/dex.test.ts +0 -1549
  195. package/src/viem/Actions/dex.ts +0 -2150
  196. package/src/viem/Actions/faucet.ts +0 -121
  197. package/src/viem/Actions/fee.test.ts +0 -259
  198. package/src/viem/Actions/fee.ts +0 -372
  199. package/src/viem/Actions/index.ts +0 -9
  200. package/src/viem/Actions/nonce.test.ts +0 -206
  201. package/src/viem/Actions/nonce.ts +0 -347
  202. package/src/viem/Actions/policy.test.ts +0 -534
  203. package/src/viem/Actions/policy.ts +0 -1335
  204. package/src/viem/Actions/reward.test.ts +0 -434
  205. package/src/viem/Actions/reward.ts +0 -944
  206. package/src/viem/Actions/token.test.ts +0 -3029
  207. package/src/viem/Actions/token.ts +0 -4458
  208. package/src/viem/Addresses.ts +0 -9
  209. package/src/viem/Chain.bench-d.ts +0 -12
  210. package/src/viem/Chain.test.ts +0 -168
  211. package/src/viem/Chain.ts +0 -157
  212. package/src/viem/Decorator.bench-d.ts +0 -11
  213. package/src/viem/Decorator.test.ts +0 -39
  214. package/src/viem/Decorator.ts +0 -3179
  215. package/src/viem/Formatters.ts +0 -164
  216. package/src/viem/P256.ts +0 -1
  217. package/src/viem/Secp256k1.ts +0 -1
  218. package/src/viem/Storage.ts +0 -110
  219. package/src/viem/TokenIds.ts +0 -1
  220. package/src/viem/Transaction.ts +0 -382
  221. package/src/viem/Transport.ts +0 -191
  222. package/src/viem/WebAuthnP256.ts +0 -146
  223. package/src/viem/WebCryptoP256.ts +0 -1
  224. package/src/viem/e2e.test.ts +0 -1602
  225. package/src/viem/index.ts +0 -30
  226. package/src/viem/internal/types.ts +0 -69
  227. package/src/viem/internal/utils.ts +0 -58
  228. package/src/wagmi/internal/types.ts +0 -16
@@ -1,3029 +0,0 @@
1
- import { setTimeout } from 'node:timers/promises'
2
- import { Hex } from 'ox'
3
- import { TokenRole } from 'ox/tempo'
4
- import { Abis, Addresses, TokenIds } from 'tempo.ts/viem'
5
- import { parseUnits } from 'viem'
6
- import { getCode, writeContractSync } from 'viem/actions'
7
- import { beforeAll, describe, expect, test } from 'vitest'
8
- import { addresses, rpcUrl } from '../../../test/config.js'
9
- import { accounts, clientWithAccount } from '../../../test/viem/config.js'
10
- import * as actions from './index.js'
11
-
12
- const account = accounts[0]
13
- const account2 = accounts[1]
14
- const account3 = accounts[2]
15
-
16
- describe('approve', () => {
17
- test('default', async () => {
18
- {
19
- // approve
20
- const { receipt, ...result } = await actions.token.approveSync(
21
- clientWithAccount,
22
- {
23
- spender: account2.address,
24
- amount: parseUnits('100', 6),
25
- token: addresses.alphaUsd,
26
- },
27
- )
28
- expect(receipt).toBeDefined()
29
- expect(result).toMatchInlineSnapshot(`
30
- {
31
- "amount": 100000000n,
32
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
33
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
34
- }
35
- `)
36
- }
37
-
38
- {
39
- // check allowance
40
- const allowance = await actions.token.getAllowance(clientWithAccount, {
41
- spender: account2.address,
42
- token: addresses.alphaUsd,
43
- })
44
- expect(allowance).toBe(parseUnits('100', 6))
45
- }
46
-
47
- // transfer tokens for gas
48
- await writeContractSync(clientWithAccount, {
49
- abi: Abis.tip20,
50
- address: addresses.alphaUsd,
51
- functionName: 'transfer',
52
- args: [account2.address, parseUnits('1', 6)],
53
- })
54
-
55
- // transfer tokens from approved account
56
- await actions.token.transferSync(clientWithAccount, {
57
- amount: parseUnits('50', 6),
58
- account: account2,
59
- from: account.address,
60
- to: '0x0000000000000000000000000000000000000001',
61
- token: addresses.alphaUsd,
62
- })
63
-
64
- {
65
- // verify updated allowance
66
- const allowance = await actions.token.getAllowance(clientWithAccount, {
67
- spender: account2.address,
68
- token: addresses.alphaUsd,
69
- })
70
- expect(allowance).toBe(parseUnits('50', 6))
71
- }
72
-
73
- // verify balance
74
- const balance = await actions.token.getBalance(clientWithAccount, {
75
- account: '0x0000000000000000000000000000000000000001',
76
- token: addresses.alphaUsd,
77
- })
78
- expect(balance).toBe(parseUnits('50', 6))
79
- })
80
-
81
- test('behavior: token address', async () => {
82
- const balanceBefore = await actions.token.getBalance(clientWithAccount, {
83
- account: '0x0000000000000000000000000000000000000001',
84
- token: addresses.alphaUsd,
85
- })
86
-
87
- {
88
- // approve
89
- const { receipt, ...result } = await actions.token.approveSync(
90
- clientWithAccount,
91
- {
92
- amount: parseUnits('100', 6),
93
- token: addresses.alphaUsd,
94
- spender: account2.address,
95
- },
96
- )
97
- expect(receipt).toBeDefined()
98
- expect(result).toMatchInlineSnapshot(`
99
- {
100
- "amount": 100000000n,
101
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
102
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
103
- }
104
- `)
105
- }
106
-
107
- {
108
- // check allowance
109
- const allowance = await actions.token.getAllowance(clientWithAccount, {
110
- token: addresses.alphaUsd,
111
- spender: account2.address,
112
- })
113
- expect(allowance).toBe(parseUnits('100', 6))
114
- }
115
-
116
- // transfer tokens for gas
117
- await writeContractSync(clientWithAccount, {
118
- abi: Abis.tip20,
119
- address: addresses.alphaUsd,
120
- functionName: 'transfer',
121
- args: [account2.address, parseUnits('1', 6)],
122
- })
123
-
124
- // transfer tokens from approved account
125
- await actions.token.transferSync(clientWithAccount, {
126
- amount: parseUnits('50', 6),
127
- account: account2,
128
- from: account.address,
129
- to: '0x0000000000000000000000000000000000000001',
130
- token: addresses.alphaUsd,
131
- })
132
-
133
- {
134
- // verify updated allowance
135
- const allowance = await actions.token.getAllowance(clientWithAccount, {
136
- spender: account2.address,
137
- token: addresses.alphaUsd,
138
- })
139
- expect(allowance).toBe(parseUnits('50', 6))
140
- }
141
-
142
- // verify balance
143
- const balance = await actions.token.getBalance(clientWithAccount, {
144
- account: '0x0000000000000000000000000000000000000001',
145
- token: addresses.alphaUsd,
146
- })
147
- expect(balance).toBe(balanceBefore + parseUnits('50', 6))
148
- })
149
-
150
- test('behavior: token address', async () => {
151
- const balanceBefore = await actions.token.getBalance(clientWithAccount, {
152
- account: '0x0000000000000000000000000000000000000001',
153
- token: addresses.alphaUsd,
154
- })
155
-
156
- {
157
- // approve
158
- const { receipt, ...result } = await actions.token.approveSync(
159
- clientWithAccount,
160
- {
161
- amount: parseUnits('100', 6),
162
- token: addresses.alphaUsd,
163
- spender: account2.address,
164
- },
165
- )
166
- expect(receipt).toBeDefined()
167
- expect(result).toMatchInlineSnapshot(`
168
- {
169
- "amount": 100000000n,
170
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
171
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
172
- }
173
- `)
174
- }
175
-
176
- {
177
- // check allowance
178
- const allowance = await actions.token.getAllowance(clientWithAccount, {
179
- token: addresses.alphaUsd,
180
- spender: account2.address,
181
- })
182
- expect(allowance).toBe(parseUnits('100', 6))
183
- }
184
-
185
- // transfer tokens for gas
186
- await writeContractSync(clientWithAccount, {
187
- abi: Abis.tip20,
188
- address: addresses.alphaUsd,
189
- functionName: 'transfer',
190
- args: [account2.address, parseUnits('1', 6)],
191
- })
192
-
193
- // transfer tokens from approved account
194
- await actions.token.transferSync(clientWithAccount, {
195
- amount: parseUnits('50', 6),
196
- account: account2,
197
- from: account.address,
198
- to: '0x0000000000000000000000000000000000000001',
199
- token: addresses.alphaUsd,
200
- })
201
-
202
- {
203
- // verify updated allowance
204
- const allowance = await actions.token.getAllowance(clientWithAccount, {
205
- spender: account2.address,
206
- token: addresses.alphaUsd,
207
- })
208
- expect(allowance).toBe(parseUnits('50', 6))
209
- }
210
-
211
- // verify balance
212
- const balance = await actions.token.getBalance(clientWithAccount, {
213
- account: '0x0000000000000000000000000000000000000001',
214
- token: addresses.alphaUsd,
215
- })
216
- expect(balance).toBe(balanceBefore + parseUnits('50', 6))
217
- })
218
- })
219
-
220
- describe('create', () => {
221
- test('default', async () => {
222
- const { receipt, token, tokenId, ...result } =
223
- await actions.token.createSync(clientWithAccount, {
224
- currency: 'USD',
225
- name: 'Test USD',
226
- symbol: 'TUSD',
227
- })
228
-
229
- expect(result).toMatchInlineSnapshot(`
230
- {
231
- "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
232
- "currency": "USD",
233
- "name": "Test USD",
234
- "quoteToken": "0x20C0000000000000000000000000000000000000",
235
- "symbol": "TUSD",
236
- }
237
- `)
238
- expect(token).toBeDefined()
239
- expect(tokenId).toBeDefined()
240
- expect(receipt).toBeDefined()
241
-
242
- const code = await getCode(clientWithAccount, {
243
- address: token,
244
- })
245
- expect(code).toBe('0xef')
246
- })
247
- })
248
-
249
- describe('getAllowance', () => {
250
- test('default', async () => {
251
- // First, approve some allowance
252
- await writeContractSync(clientWithAccount, {
253
- abi: Abis.tip20,
254
- address: addresses.alphaUsd,
255
- functionName: 'approve',
256
- args: [account2.address, parseUnits('50', 6)],
257
- })
258
-
259
- {
260
- // Test with default token
261
- const allowance = await actions.token.getAllowance(clientWithAccount, {
262
- spender: account2.address,
263
- token: addresses.alphaUsd,
264
- })
265
- expect(allowance).toBe(parseUnits('50', 6))
266
- }
267
-
268
- {
269
- // Test with token address
270
- const allowance = await actions.token.getAllowance(clientWithAccount, {
271
- token: addresses.alphaUsd,
272
- spender: account2.address,
273
- })
274
-
275
- expect(allowance).toBe(parseUnits('50', 6))
276
- }
277
-
278
- {
279
- // Test with token ID
280
- const allowance = await actions.token.getAllowance(clientWithAccount, {
281
- token: addresses.alphaUsd,
282
- spender: account2.address,
283
- })
284
-
285
- expect(allowance).toBe(parseUnits('50', 6))
286
- }
287
- })
288
- })
289
-
290
- describe('getBalance', () => {
291
- test('default', async () => {
292
- {
293
- // Test with token address
294
- const balance = await actions.token.getBalance(clientWithAccount, {
295
- token: addresses.alphaUsd,
296
- })
297
-
298
- expect(balance).toBeGreaterThan(0n)
299
- }
300
-
301
- {
302
- // Test with token ID & different account
303
- const balance = await actions.token.getBalance(clientWithAccount, {
304
- token: addresses.alphaUsd,
305
- account: Hex.random(20),
306
- })
307
-
308
- expect(balance).toBe(0n)
309
- }
310
- })
311
- })
312
-
313
- describe('getMetadata', () => {
314
- test('default', async () => {
315
- const metadata = await actions.token.getMetadata(clientWithAccount, {
316
- token: addresses.alphaUsd,
317
- })
318
-
319
- expect(metadata).toMatchInlineSnapshot(`
320
- {
321
- "currency": "USD",
322
- "decimals": 6,
323
- "name": "AlphaUSD",
324
- "paused": false,
325
- "quoteToken": "0x20C0000000000000000000000000000000000000",
326
- "supplyCap": 340282366920938463463374607431768211455n,
327
- "symbol": "AlphaUSD",
328
- "totalSupply": 202914184810805067765n,
329
- "transferPolicyId": 1n,
330
- }
331
- `)
332
- })
333
-
334
- test('behavior: custom token (address)', async () => {
335
- const { token } = await actions.token.createSync(clientWithAccount, {
336
- currency: 'USD',
337
- name: 'Test USD',
338
- symbol: 'TUSD',
339
- })
340
-
341
- const metadata = await actions.token.getMetadata(clientWithAccount, {
342
- token,
343
- })
344
-
345
- expect(metadata).toMatchInlineSnapshot(`
346
- {
347
- "currency": "USD",
348
- "decimals": 6,
349
- "name": "Test USD",
350
- "paused": false,
351
- "quoteToken": "0x20C0000000000000000000000000000000000000",
352
- "supplyCap": 340282366920938463463374607431768211455n,
353
- "symbol": "TUSD",
354
- "totalSupply": 0n,
355
- "transferPolicyId": 1n,
356
- }
357
- `)
358
- })
359
-
360
- test('behavior: quote token', async () => {
361
- {
362
- const metadata = await actions.token.getMetadata(clientWithAccount, {
363
- token: TokenIds.pathUsd,
364
- })
365
-
366
- expect(metadata).toMatchInlineSnapshot(`
367
- {
368
- "currency": "USD",
369
- "decimals": 6,
370
- "name": "pathUSD",
371
- "symbol": "pathUSD",
372
- "totalSupply": 184467440737095516150n,
373
- }
374
- `)
375
- }
376
-
377
- {
378
- const metadata = await actions.token.getMetadata(clientWithAccount, {
379
- token: Addresses.pathUsd,
380
- })
381
-
382
- expect(metadata).toMatchInlineSnapshot(`
383
- {
384
- "currency": "USD",
385
- "decimals": 6,
386
- "name": "pathUSD",
387
- "symbol": "pathUSD",
388
- "totalSupply": 184467440737095516150n,
389
- }
390
- `)
391
- }
392
- })
393
-
394
- test('behavior: custom token (id)', async () => {
395
- const token = await actions.token.createSync(clientWithAccount, {
396
- currency: 'USD',
397
- name: 'Test USD',
398
- symbol: 'TUSD',
399
- })
400
-
401
- const metadata = await actions.token.getMetadata(clientWithAccount, {
402
- token: token.tokenId,
403
- })
404
-
405
- expect(metadata).toMatchInlineSnapshot(`
406
- {
407
- "currency": "USD",
408
- "decimals": 6,
409
- "name": "Test USD",
410
- "paused": false,
411
- "quoteToken": "0x20C0000000000000000000000000000000000000",
412
- "supplyCap": 340282366920938463463374607431768211455n,
413
- "symbol": "TUSD",
414
- "totalSupply": 0n,
415
- "transferPolicyId": 1n,
416
- }
417
- `)
418
- })
419
- })
420
-
421
- describe('mint', () => {
422
- test('default', async () => {
423
- // Create a new token where we're the admin
424
- const { token } = await actions.token.createSync(clientWithAccount, {
425
- currency: 'USD',
426
- name: 'Mintable Token',
427
- symbol: 'MINT',
428
- })
429
-
430
- // Grant issuer role
431
- await actions.token.grantRolesSync(clientWithAccount, {
432
- token,
433
- roles: ['issuer'],
434
- to: clientWithAccount.account.address,
435
- })
436
-
437
- // Check initial balance
438
- const balanceBefore = await actions.token.getBalance(clientWithAccount, {
439
- token,
440
- account: account2.address,
441
- })
442
- expect(balanceBefore).toBe(0n)
443
-
444
- // Mint tokens
445
- const { receipt: mintReceipt, ...mintResult } =
446
- await actions.token.mintSync(clientWithAccount, {
447
- token,
448
- to: account2.address,
449
- amount: parseUnits('1000', 6),
450
- })
451
- expect(mintReceipt).toBeDefined()
452
- expect(mintResult).toMatchInlineSnapshot(`
453
- {
454
- "amount": 1000000000n,
455
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
456
- }
457
- `)
458
-
459
- // Check balance after mint
460
- const balanceAfter = await actions.token.getBalance(clientWithAccount, {
461
- token,
462
- account: account2.address,
463
- })
464
- expect(balanceAfter).toBe(parseUnits('1000', 6))
465
-
466
- // Check total supply
467
- const metadata = await actions.token.getMetadata(clientWithAccount, {
468
- token,
469
- })
470
- expect(metadata.totalSupply).toBe(parseUnits('1000', 6))
471
- })
472
-
473
- // TODO: fix
474
- test.skip('with memo', async () => {
475
- // Create a new token
476
- const { token } = await actions.token.createSync(clientWithAccount, {
477
- admin: clientWithAccount.account,
478
- currency: 'USD',
479
- name: 'Mintable Token 2',
480
- symbol: 'MINT2',
481
- })
482
-
483
- // Grant issuer role
484
- await actions.token.grantRolesSync(clientWithAccount, {
485
- token,
486
- roles: ['issuer'],
487
- to: clientWithAccount.account.address,
488
- })
489
-
490
- // Mint tokens with memo
491
- const { receipt: mintMemoReceipt, ...mintMemoResult } =
492
- await actions.token.mintSync(clientWithAccount, {
493
- token,
494
- to: account2.address,
495
- amount: parseUnits('500', 6),
496
- memo: Hex.fromString('test'),
497
- })
498
- expect(mintMemoReceipt.status).toBe('success')
499
- expect(mintMemoResult).toMatchInlineSnapshot(`
500
- {
501
- "amount": 500000000000000000000n,
502
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
503
- }
504
- `)
505
-
506
- // Verify balance
507
- const balance = await actions.token.getBalance(clientWithAccount, {
508
- token,
509
- account: account2.address,
510
- })
511
- expect(balance).toBe(parseUnits('500', 6))
512
- })
513
- })
514
-
515
- describe('transfer', () => {
516
- test('default', async () => {
517
- // Get initial balances
518
- const senderBalanceBefore = await actions.token.getBalance(
519
- clientWithAccount,
520
- {
521
- account: account.address,
522
- token: addresses.alphaUsd,
523
- },
524
- )
525
- const receiverBalanceBefore = await actions.token.getBalance(
526
- clientWithAccount,
527
- {
528
- account: account2.address,
529
- token: addresses.alphaUsd,
530
- },
531
- )
532
-
533
- // Transfer tokens
534
- const { receipt: transferReceipt, ...transferResult } =
535
- await actions.token.transferSync(clientWithAccount, {
536
- to: account2.address,
537
- amount: parseUnits('10', 6),
538
- token: addresses.alphaUsd,
539
- })
540
- expect(transferReceipt).toBeDefined()
541
- expect(transferResult).toMatchInlineSnapshot(`
542
- {
543
- "amount": 10000000n,
544
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
545
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
546
- }
547
- `)
548
-
549
- // Verify balances
550
- const senderBalanceAfter = await actions.token.getBalance(
551
- clientWithAccount,
552
- {
553
- account: account.address,
554
- token: addresses.alphaUsd,
555
- },
556
- )
557
- const receiverBalanceAfter = await actions.token.getBalance(
558
- clientWithAccount,
559
- {
560
- account: account2.address,
561
- token: addresses.alphaUsd,
562
- },
563
- )
564
-
565
- expect(senderBalanceAfter - senderBalanceBefore).toBeLessThan(
566
- parseUnits('10', 6),
567
- )
568
- expect(receiverBalanceAfter - receiverBalanceBefore).toBe(
569
- parseUnits('10', 6),
570
- )
571
- })
572
-
573
- test('behavior: with custom token', async () => {
574
- // Create a new token
575
- const { token } = await actions.token.createSync(clientWithAccount, {
576
- currency: 'USD',
577
- name: 'Transfer Token',
578
- symbol: 'XFER',
579
- })
580
-
581
- // Grant issuer role and mint tokens
582
- await actions.token.grantRolesSync(clientWithAccount, {
583
- token,
584
- roles: ['issuer'],
585
- to: clientWithAccount.account.address,
586
- })
587
-
588
- await actions.token.mintSync(clientWithAccount, {
589
- token,
590
- to: clientWithAccount.account.address,
591
- amount: parseUnits('1000', 6),
592
- })
593
-
594
- // Transfer custom tokens
595
- await actions.token.transferSync(clientWithAccount, {
596
- token,
597
- to: account2.address,
598
- amount: parseUnits('100', 6),
599
- })
600
-
601
- // Verify balance
602
- const balance = await actions.token.getBalance(clientWithAccount, {
603
- token,
604
- account: account2.address,
605
- })
606
- expect(balance).toBe(parseUnits('100', 6))
607
- })
608
-
609
- test('behavior: with memo', async () => {
610
- const memo = Hex.fromString('Payment for services')
611
-
612
- const { receipt: transferMemoReceipt, ...transferMemoResult } =
613
- await actions.token.transferSync(clientWithAccount, {
614
- to: account2.address,
615
- amount: parseUnits('5', 6),
616
- memo,
617
- token: addresses.alphaUsd,
618
- })
619
-
620
- expect(transferMemoReceipt.status).toBe('success')
621
- expect(transferMemoResult).toMatchInlineSnapshot(`
622
- {
623
- "amount": 5000000n,
624
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
625
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
626
- }
627
- `)
628
- })
629
-
630
- test('behavior: from another account (transferFrom)', async () => {
631
- // First approve account2 to spend tokens
632
- await actions.token.approveSync(clientWithAccount, {
633
- spender: account2.address,
634
- amount: parseUnits('50', 6),
635
- token: addresses.alphaUsd,
636
- })
637
-
638
- // Transfer tokens for gas
639
- await writeContractSync(clientWithAccount, {
640
- abi: Abis.tip20,
641
- address: addresses.alphaUsd,
642
- functionName: 'transfer',
643
- args: [account2.address, parseUnits('1', 6)],
644
- })
645
-
646
- // Get initial balance
647
- const balanceBefore = await actions.token.getBalance(clientWithAccount, {
648
- account: account3.address,
649
- token: addresses.alphaUsd,
650
- })
651
-
652
- // Account2 transfers from account to account3
653
- await actions.token.transferSync(clientWithAccount, {
654
- account: account2,
655
- from: account.address,
656
- to: account3.address,
657
- amount: parseUnits('25', 6),
658
- token: addresses.alphaUsd,
659
- })
660
-
661
- // Verify balance
662
- const balanceAfter = await actions.token.getBalance(clientWithAccount, {
663
- account: account3.address,
664
- token: addresses.alphaUsd,
665
- })
666
- expect(balanceAfter - balanceBefore).toBe(parseUnits('25', 6))
667
-
668
- // Verify allowance was reduced
669
- const allowance = await actions.token.getAllowance(clientWithAccount, {
670
- spender: account2.address,
671
- token: addresses.alphaUsd,
672
- })
673
- expect(allowance).toBe(parseUnits('25', 6))
674
- })
675
- })
676
-
677
- describe('burn', () => {
678
- test('default', async () => {
679
- // Create a new token where we have issuer role
680
- const { token } = await actions.token.createSync(clientWithAccount, {
681
- currency: 'USD',
682
- name: 'Burnable Token',
683
- symbol: 'BURN',
684
- })
685
-
686
- // Grant issuer role
687
- await actions.token.grantRolesSync(clientWithAccount, {
688
- token,
689
- roles: ['issuer'],
690
- to: clientWithAccount.account.address,
691
- })
692
-
693
- // Mint some tokens
694
- await actions.token.mintSync(clientWithAccount, {
695
- token,
696
- to: clientWithAccount.account.address,
697
- amount: parseUnits('1000', 6),
698
- })
699
-
700
- // Check balance before burn
701
- const balanceBefore = await actions.token.getBalance(clientWithAccount, {
702
- token,
703
- })
704
- expect(balanceBefore).toBe(parseUnits('1000', 6))
705
-
706
- // Check total supply before
707
- const metadataBefore = await actions.token.getMetadata(clientWithAccount, {
708
- token,
709
- })
710
- expect(metadataBefore.totalSupply).toBe(parseUnits('1000', 6))
711
-
712
- // Burn tokens
713
- const { receipt, ...result } = await actions.token.burnSync(
714
- clientWithAccount,
715
- {
716
- token,
717
- amount: parseUnits('100', 6),
718
- },
719
- )
720
- expect(receipt).toBeDefined()
721
- expect(result).toMatchInlineSnapshot(`
722
- {
723
- "amount": 100000000n,
724
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
725
- }
726
- `)
727
-
728
- // Check balance after burn
729
- const balanceAfter = await actions.token.getBalance(clientWithAccount, {
730
- token,
731
- })
732
- expect(balanceAfter).toBe(parseUnits('900', 6))
733
-
734
- // Check total supply after
735
- const metadataAfter = await actions.token.getMetadata(clientWithAccount, {
736
- token,
737
- })
738
- expect(metadataAfter.totalSupply).toBe(parseUnits('900', 6))
739
- })
740
-
741
- test('behavior: requires issuer role', async () => {
742
- // Create a new token
743
- const { token } = await actions.token.createSync(clientWithAccount, {
744
- currency: 'USD',
745
- name: 'Restricted Burn Token',
746
- symbol: 'RBURN',
747
- })
748
-
749
- // Grant issuer role to account2 (not us)
750
- await actions.token.grantRolesSync(clientWithAccount, {
751
- token,
752
- roles: ['issuer'],
753
- to: account2.address,
754
- })
755
-
756
- // Transfer gas to account2
757
- await writeContractSync(clientWithAccount, {
758
- abi: Abis.tip20,
759
- address: addresses.alphaUsd,
760
- functionName: 'transfer',
761
- args: [account2.address, parseUnits('1', 6)],
762
- })
763
-
764
- await actions.token.mintSync(clientWithAccount, {
765
- account: account2,
766
- feeToken: addresses.alphaUsd,
767
- token,
768
- to: clientWithAccount.account.address,
769
- amount: parseUnits('100', 6),
770
- })
771
-
772
- // Try to burn without issuer role - should fail
773
- await expect(
774
- actions.token.burnSync(clientWithAccount, {
775
- token,
776
- amount: parseUnits('10', 6),
777
- }),
778
- ).rejects.toThrow()
779
- })
780
- })
781
-
782
- describe.todo('burnBlockedToken')
783
-
784
- describe.todo('changeTokenTransferPolicy')
785
-
786
- describe('pause', () => {
787
- test('default', async () => {
788
- // Create a new token
789
- const { token } = await actions.token.createSync(clientWithAccount, {
790
- currency: 'USD',
791
- name: 'Pausable Token',
792
- symbol: 'PAUSE',
793
- })
794
-
795
- // Grant pause role
796
- await actions.token.grantRolesSync(clientWithAccount, {
797
- token,
798
- roles: ['pause'],
799
- to: clientWithAccount.account.address,
800
- })
801
-
802
- // Grant issuer role and mint tokens
803
- await actions.token.grantRolesSync(clientWithAccount, {
804
- token,
805
- roles: ['issuer'],
806
- to: clientWithAccount.account.address,
807
- })
808
-
809
- await actions.token.mintSync(clientWithAccount, {
810
- token,
811
- to: account2.address,
812
- amount: parseUnits('1000', 6),
813
- })
814
-
815
- // Verify token is not paused
816
- let metadata = await actions.token.getMetadata(clientWithAccount, {
817
- token,
818
- })
819
- expect(metadata.paused).toBe(false)
820
-
821
- // Transfer gas
822
- await writeContractSync(clientWithAccount, {
823
- abi: Abis.tip20,
824
- address: addresses.alphaUsd,
825
- functionName: 'transfer',
826
- args: [account2.address, parseUnits('1', 6)],
827
- })
828
-
829
- await actions.token.transferSync(clientWithAccount, {
830
- account: account2,
831
- token,
832
- to: account3.address,
833
- amount: parseUnits('100', 6),
834
- })
835
-
836
- // Pause the token
837
- const { receipt: pauseReceipt, ...pauseResult } =
838
- await actions.token.pauseSync(clientWithAccount, {
839
- token,
840
- })
841
- expect(pauseReceipt).toBeDefined()
842
- expect(pauseResult).toMatchInlineSnapshot(`
843
- {
844
- "isPaused": true,
845
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
846
- }
847
- `)
848
-
849
- // Verify token is paused
850
- metadata = await actions.token.getMetadata(clientWithAccount, {
851
- token,
852
- })
853
- expect(metadata.paused).toBe(true)
854
-
855
- // Transfers should now fail
856
- await expect(
857
- actions.token.transferSync(clientWithAccount, {
858
- account: account2,
859
- token,
860
- to: account3.address,
861
- amount: parseUnits('100', 6),
862
- }),
863
- ).rejects.toThrow()
864
- })
865
-
866
- test('behavior: requires pause role', async () => {
867
- // Create a new token
868
- const { token } = await actions.token.createSync(clientWithAccount, {
869
- currency: 'USD',
870
- name: 'Restricted Pause Token',
871
- symbol: 'RPAUSE',
872
- })
873
-
874
- // Try to pause without pause role - should fail
875
- await expect(
876
- actions.token.pauseSync(clientWithAccount, {
877
- token,
878
- }),
879
- ).rejects.toThrow()
880
-
881
- // Grant pause role to account2
882
- await actions.token.grantRolesSync(clientWithAccount, {
883
- token,
884
- roles: ['pause'],
885
- to: account2.address,
886
- })
887
-
888
- // Transfer gas to account2
889
- await writeContractSync(clientWithAccount, {
890
- abi: Abis.tip20,
891
- address: addresses.alphaUsd,
892
- functionName: 'transfer',
893
- args: [account2.address, parseUnits('1', 6)],
894
- })
895
-
896
- await actions.token.pauseSync(clientWithAccount, {
897
- account: account2,
898
- feeToken: addresses.alphaUsd,
899
- token,
900
- })
901
-
902
- // Verify token is paused
903
- const metadata = await actions.token.getMetadata(clientWithAccount, {
904
- token,
905
- })
906
- expect(metadata.paused).toBe(true)
907
- })
908
-
909
- test('behavior: cannot pause already paused token', async () => {
910
- // Create a new token
911
- const { token: address } = await actions.token.createSync(
912
- clientWithAccount,
913
- {
914
- currency: 'USD',
915
- name: 'Double Pause Token',
916
- symbol: 'DPAUSE',
917
- },
918
- )
919
-
920
- // Grant pause role
921
- await actions.token.grantRolesSync(clientWithAccount, {
922
- token: address,
923
- roles: ['pause'],
924
- to: clientWithAccount.account.address,
925
- })
926
-
927
- // Pause the token
928
- await actions.token.pauseSync(clientWithAccount, {
929
- token: address,
930
- })
931
-
932
- // Try to pause again - implementation may vary, but typically this succeeds without error
933
- const { receipt: doublePauseReceipt, ...doublePauseResult } =
934
- await actions.token.pauseSync(clientWithAccount, {
935
- token: address,
936
- })
937
- expect(doublePauseReceipt.status).toBe('success')
938
- expect(doublePauseResult).toMatchInlineSnapshot(`
939
- {
940
- "isPaused": true,
941
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
942
- }
943
- `)
944
- })
945
- })
946
-
947
- describe('unpause', () => {
948
- test('default', async () => {
949
- // Create a new token
950
- const { token: address } = await actions.token.createSync(
951
- clientWithAccount,
952
- {
953
- currency: 'USD',
954
- name: 'Unpausable Token',
955
- symbol: 'UNPAUSE',
956
- },
957
- )
958
-
959
- // Grant pause and unpause roles
960
- await actions.token.grantRolesSync(clientWithAccount, {
961
- token: address,
962
- roles: ['pause'],
963
- to: clientWithAccount.account.address,
964
- })
965
-
966
- await actions.token.grantRolesSync(clientWithAccount, {
967
- token: address,
968
- roles: ['unpause'],
969
- to: clientWithAccount.account.address,
970
- })
971
-
972
- // Grant issuer role and mint tokens
973
- await actions.token.grantRolesSync(clientWithAccount, {
974
- token: address,
975
- roles: ['issuer'],
976
- to: clientWithAccount.account.address,
977
- })
978
-
979
- await actions.token.mintSync(clientWithAccount, {
980
- token: address,
981
- to: account2.address,
982
- amount: parseUnits('1000', 6),
983
- })
984
-
985
- // First pause the token
986
- await actions.token.pauseSync(clientWithAccount, {
987
- token: address,
988
- })
989
-
990
- // Verify token is paused
991
- let metadata = await actions.token.getMetadata(clientWithAccount, {
992
- token: address,
993
- })
994
- expect(metadata.paused).toBe(true)
995
-
996
- // Transfer gas to account2
997
- await writeContractSync(clientWithAccount, {
998
- abi: Abis.tip20,
999
- address: addresses.alphaUsd,
1000
- functionName: 'transfer',
1001
- args: [account2.address, parseUnits('1', 6)],
1002
- })
1003
-
1004
- // Verify transfers fail when paused
1005
- await expect(
1006
- actions.token.transferSync(clientWithAccount, {
1007
- account: account2,
1008
- token: address,
1009
- to: account3.address,
1010
- amount: parseUnits('100', 6),
1011
- }),
1012
- ).rejects.toThrow()
1013
-
1014
- // Unpause the token
1015
- const { receipt: unpauseReceipt, ...unpauseResult } =
1016
- await actions.token.unpauseSync(clientWithAccount, {
1017
- token: address,
1018
- })
1019
- expect(unpauseReceipt).toBeDefined()
1020
- expect(unpauseResult).toMatchInlineSnapshot(`
1021
- {
1022
- "isPaused": false,
1023
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1024
- }
1025
- `)
1026
-
1027
- // Verify token is unpaused
1028
- metadata = await actions.token.getMetadata(clientWithAccount, {
1029
- token: address,
1030
- })
1031
- expect(metadata.paused).toBe(false)
1032
-
1033
- // Transfers should work again
1034
- await actions.token.transferSync(clientWithAccount, {
1035
- account: account2,
1036
- token: address,
1037
- to: account3.address,
1038
- amount: parseUnits('100', 6),
1039
- })
1040
-
1041
- const balance = await actions.token.getBalance(clientWithAccount, {
1042
- token: address,
1043
- account: account3.address,
1044
- })
1045
- expect(balance).toBe(parseUnits('100', 6))
1046
- })
1047
-
1048
- test('behavior: requires unpause role', async () => {
1049
- // Create a new token
1050
- const { token: address } = await actions.token.createSync(
1051
- clientWithAccount,
1052
- {
1053
- currency: 'USD',
1054
- name: 'Restricted Unpause Token',
1055
- symbol: 'RUNPAUSE',
1056
- },
1057
- )
1058
-
1059
- // Grant pause role and pause the token
1060
- await actions.token.grantRolesSync(clientWithAccount, {
1061
- token: address,
1062
- roles: ['pause'],
1063
- to: clientWithAccount.account.address,
1064
- })
1065
-
1066
- await actions.token.pauseSync(clientWithAccount, {
1067
- token: address,
1068
- })
1069
-
1070
- // Try to unpause without unpause role - should fail
1071
- await expect(
1072
- actions.token.unpauseSync(clientWithAccount, {
1073
- token: address,
1074
- }),
1075
- ).rejects.toThrow()
1076
-
1077
- // Grant unpause role to account2
1078
- await actions.token.grantRolesSync(clientWithAccount, {
1079
- token: address,
1080
- roles: ['unpause'],
1081
- to: account2.address,
1082
- })
1083
-
1084
- // Transfer gas to account2
1085
- await writeContractSync(clientWithAccount, {
1086
- abi: Abis.tip20,
1087
- address: addresses.alphaUsd,
1088
- functionName: 'transfer',
1089
- args: [account2.address, parseUnits('1', 6)],
1090
- })
1091
-
1092
- // Now account2 should be able to unpause
1093
- await actions.token.unpauseSync(clientWithAccount, {
1094
- account: account2,
1095
- feeToken: addresses.alphaUsd,
1096
- token: address,
1097
- })
1098
-
1099
- // Verify token is unpaused
1100
- const metadata = await actions.token.getMetadata(clientWithAccount, {
1101
- token: address,
1102
- })
1103
- expect(metadata.paused).toBe(false)
1104
- })
1105
-
1106
- test('behavior: different roles for pause and unpause', async () => {
1107
- // Create a new token
1108
- const { token: address } = await actions.token.createSync(
1109
- clientWithAccount,
1110
- {
1111
- currency: 'USD',
1112
- name: 'Split Role Token',
1113
- symbol: 'SPLIT',
1114
- },
1115
- )
1116
-
1117
- // Grant pause role to account2
1118
- await actions.token.grantRolesSync(clientWithAccount, {
1119
- token: address,
1120
- roles: ['pause'],
1121
- to: account2.address,
1122
- })
1123
-
1124
- // Grant unpause role to account3
1125
- await actions.token.grantRolesSync(clientWithAccount, {
1126
- token: address,
1127
- roles: ['unpause'],
1128
- to: account3.address,
1129
- })
1130
-
1131
- // Transfer gas to both accounts
1132
- await writeContractSync(clientWithAccount, {
1133
- abi: Abis.tip20,
1134
- address: addresses.alphaUsd,
1135
- functionName: 'transfer',
1136
- args: [account2.address, parseUnits('1', 6)],
1137
- })
1138
-
1139
- await writeContractSync(clientWithAccount, {
1140
- abi: Abis.tip20,
1141
- address: addresses.alphaUsd,
1142
- functionName: 'transfer',
1143
- args: [account3.address, parseUnits('1', 6)],
1144
- })
1145
-
1146
- // Account2 can pause
1147
- await actions.token.pauseSync(clientWithAccount, {
1148
- account: account2,
1149
- feeToken: addresses.alphaUsd,
1150
- token: address,
1151
- })
1152
-
1153
- // Account2 cannot unpause
1154
- await expect(
1155
- actions.token.unpauseSync(clientWithAccount, {
1156
- account: account2,
1157
- token: address,
1158
- }),
1159
- ).rejects.toThrow()
1160
-
1161
- // Account3 can unpause
1162
- await actions.token.unpauseSync(clientWithAccount, {
1163
- account: account3,
1164
- feeToken: addresses.alphaUsd,
1165
- token: address,
1166
- })
1167
-
1168
- // Verify token is unpaused
1169
- const metadata = await actions.token.getMetadata(clientWithAccount, {
1170
- token: address,
1171
- })
1172
- expect(metadata.paused).toBe(false)
1173
- })
1174
- })
1175
-
1176
- describe('prepareUpdateQuoteToken', () => {
1177
- test('default', async () => {
1178
- // Create two tokens - one to be the new quote token
1179
- const { token: quoteTokenAddress } = await actions.token.createSync(
1180
- clientWithAccount,
1181
- {
1182
- currency: 'USD',
1183
- name: 'Quote Token',
1184
- symbol: 'LINK',
1185
- },
1186
- )
1187
-
1188
- const { token: address } = await actions.token.createSync(
1189
- clientWithAccount,
1190
- {
1191
- currency: 'USD',
1192
- name: 'Main Token',
1193
- symbol: 'MAIN',
1194
- },
1195
- )
1196
-
1197
- // Update quote token
1198
- const {
1199
- receipt: updateReceipt,
1200
- nextQuoteToken,
1201
- ...updateResult
1202
- } = await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1203
- token: address,
1204
- quoteToken: quoteTokenAddress,
1205
- })
1206
-
1207
- expect(updateReceipt).toBeDefined()
1208
- expect(updateResult).toMatchInlineSnapshot(`
1209
- {
1210
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1211
- }
1212
- `)
1213
-
1214
- // Verify the event was emitted with correct quote token
1215
- expect(nextQuoteToken).toBe(quoteTokenAddress)
1216
- })
1217
-
1218
- test('behavior: requires admin role', async () => {
1219
- // Create quote token
1220
- const { token: quoteTokenAddress } = await actions.token.createSync(
1221
- clientWithAccount,
1222
- {
1223
- currency: 'USD',
1224
- name: 'Quote Token 2',
1225
- symbol: 'LINK2',
1226
- },
1227
- )
1228
-
1229
- // Create main token where clientWithAccount.account is admin
1230
- const { token: address } = await actions.token.createSync(
1231
- clientWithAccount,
1232
- {
1233
- currency: 'USD',
1234
- name: 'Restricted Token',
1235
- symbol: 'RESTR',
1236
- },
1237
- )
1238
-
1239
- // Transfer gas to account2
1240
- await writeContractSync(clientWithAccount, {
1241
- abi: Abis.tip20,
1242
- address: addresses.alphaUsd,
1243
- functionName: 'transfer',
1244
- args: [account2.address, parseUnits('1', 6)],
1245
- })
1246
-
1247
- // Try to update quote token from account2 (not admin) - should fail
1248
- await expect(
1249
- actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1250
- account: account2,
1251
- token: address,
1252
- quoteToken: quoteTokenAddress,
1253
- }),
1254
- ).rejects.toThrow()
1255
- })
1256
-
1257
- test('behavior: with token ID', async () => {
1258
- // Create quote token
1259
- const { token: quoteTokenAddress } = await actions.token.createSync(
1260
- clientWithAccount,
1261
- {
1262
- currency: 'USD',
1263
- name: 'Quote Token 3',
1264
- symbol: 'LINK3',
1265
- },
1266
- )
1267
-
1268
- // Create main token using token ID
1269
- const { tokenId: mainTokenId } = await actions.token.createSync(
1270
- clientWithAccount,
1271
- {
1272
- currency: 'USD',
1273
- name: 'Main Token ID',
1274
- symbol: 'MAINID',
1275
- },
1276
- )
1277
-
1278
- // Update quote token using token ID for main token, address for quote token
1279
- const {
1280
- receipt: updateReceipt,
1281
- nextQuoteToken,
1282
- ...updateResult
1283
- } = await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1284
- token: mainTokenId,
1285
- quoteToken: quoteTokenAddress,
1286
- })
1287
-
1288
- expect(updateResult).toMatchInlineSnapshot(`
1289
- {
1290
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1291
- }
1292
- `)
1293
- expect(nextQuoteToken).toBe(quoteTokenAddress)
1294
- expect(updateReceipt.status).toBe('success')
1295
- })
1296
- })
1297
-
1298
- describe('finalizeUpdateQuoteToken', () => {
1299
- test('default', async () => {
1300
- // Create quote token
1301
- const { token: quoteTokenAddress } = await actions.token.createSync(
1302
- clientWithAccount,
1303
- {
1304
- currency: 'USD',
1305
- name: 'Quote Token',
1306
- symbol: 'LINK',
1307
- },
1308
- )
1309
-
1310
- // Create main token
1311
- const { token: address } = await actions.token.createSync(
1312
- clientWithAccount,
1313
- {
1314
- currency: 'USD',
1315
- name: 'Main Token',
1316
- symbol: 'MAIN',
1317
- },
1318
- )
1319
-
1320
- // Prepare update quote token (step 1)
1321
- await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1322
- token: address,
1323
- quoteToken: quoteTokenAddress,
1324
- })
1325
-
1326
- // Finalize the update (step 2)
1327
- const {
1328
- receipt: finalizeReceipt,
1329
- newQuoteToken,
1330
- ...finalizeResult
1331
- } = await actions.token.updateQuoteTokenSync(clientWithAccount, {
1332
- token: address,
1333
- })
1334
-
1335
- expect(finalizeReceipt).toBeDefined()
1336
- expect(finalizeResult).toMatchInlineSnapshot(`
1337
- {
1338
- "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1339
- }
1340
- `)
1341
-
1342
- // Verify the quote token was updated
1343
- expect(newQuoteToken).toBe(quoteTokenAddress)
1344
-
1345
- // Verify it's reflected in metadata
1346
- const metadata = await actions.token.getMetadata(clientWithAccount, {
1347
- token: address,
1348
- })
1349
- expect(metadata.quoteToken).toBe(quoteTokenAddress)
1350
- })
1351
-
1352
- test('behavior: requires admin role', async () => {
1353
- // Create quote token
1354
- const { token: quoteTokenAddress } = await actions.token.createSync(
1355
- clientWithAccount,
1356
- {
1357
- currency: 'USD',
1358
- name: 'Quote Token 2',
1359
- symbol: 'LINK2',
1360
- },
1361
- )
1362
-
1363
- // Create main token
1364
- const { token: address } = await actions.token.createSync(
1365
- clientWithAccount,
1366
- {
1367
- currency: 'USD',
1368
- name: 'Restricted Token',
1369
- symbol: 'RESTR',
1370
- },
1371
- )
1372
-
1373
- // Update quote token as admin
1374
- await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1375
- token: address,
1376
- quoteToken: quoteTokenAddress,
1377
- })
1378
-
1379
- // Transfer gas to account2
1380
- await writeContractSync(clientWithAccount, {
1381
- abi: Abis.tip20,
1382
- address: addresses.alphaUsd,
1383
- functionName: 'transfer',
1384
- args: [account2.address, parseUnits('1', 6)],
1385
- })
1386
-
1387
- // Try to finalize as non-admin - should fail
1388
- await expect(
1389
- actions.token.updateQuoteTokenSync(clientWithAccount, {
1390
- account: account2,
1391
- token: address,
1392
- }),
1393
- ).rejects.toThrow()
1394
- })
1395
-
1396
- test('behavior: prevents circular references', async () => {
1397
- // Create token B
1398
- const { token: tokenBAddress } = await actions.token.createSync(
1399
- clientWithAccount,
1400
- {
1401
- currency: 'USD',
1402
- name: 'Token B',
1403
- symbol: 'TKB',
1404
- },
1405
- )
1406
-
1407
- // Create token A that links to token B
1408
- const { token: tokenAAddress } = await actions.token.createSync(
1409
- clientWithAccount,
1410
- {
1411
- currency: 'USD',
1412
- name: 'Token A',
1413
- symbol: 'TKA',
1414
- quoteToken: tokenBAddress,
1415
- },
1416
- )
1417
-
1418
- // Try to make token B link to token A (would create A -> B -> A loop)
1419
- await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
1420
- token: tokenBAddress,
1421
- quoteToken: tokenAAddress,
1422
- })
1423
-
1424
- // Finalize should fail due to circular reference detection
1425
- await expect(
1426
- actions.token.updateQuoteTokenSync(clientWithAccount, {
1427
- token: tokenBAddress,
1428
- }),
1429
- ).rejects.toThrow()
1430
- })
1431
- })
1432
-
1433
- describe.todo('setTokenSupplyCap')
1434
-
1435
- describe('hasRole', () => {
1436
- test('default', async () => {
1437
- // Create a new token where we're the admin
1438
- const { token: address } = await actions.token.createSync(
1439
- clientWithAccount,
1440
- {
1441
- currency: 'USD',
1442
- name: 'HasRole Test Token',
1443
- symbol: 'HRTEST',
1444
- },
1445
- )
1446
-
1447
- // Client account should have defaultAdmin role on the new token
1448
- const hasDefaultAdminRole = await actions.token.hasRole(clientWithAccount, {
1449
- token: address,
1450
- role: 'defaultAdmin',
1451
- })
1452
- expect(hasDefaultAdminRole).toBe(true)
1453
-
1454
- // Client account should not have issuer role initially on the new token
1455
- const hasIssuerRole = await actions.token.hasRole(clientWithAccount, {
1456
- token: address,
1457
- role: 'issuer',
1458
- })
1459
- expect(hasIssuerRole).toBe(false)
1460
-
1461
- // Grant issuer role
1462
- await actions.token.grantRolesSync(clientWithAccount, {
1463
- token: address,
1464
- roles: ['issuer'],
1465
- to: clientWithAccount.account.address,
1466
- })
1467
-
1468
- // Now should have issuer role
1469
- const hasIssuerRoleAfterGrant = await actions.token.hasRole(
1470
- clientWithAccount,
1471
- {
1472
- token: address,
1473
- role: 'issuer',
1474
- },
1475
- )
1476
- expect(hasIssuerRoleAfterGrant).toBe(true)
1477
- })
1478
-
1479
- test('behavior: check other account', async () => {
1480
- // Create a new token
1481
- const { token: address } = await actions.token.createSync(
1482
- clientWithAccount,
1483
- {
1484
- currency: 'USD',
1485
- name: 'HasRole Other Account',
1486
- symbol: 'HROAC',
1487
- },
1488
- )
1489
-
1490
- // Account2 should not have issuer role
1491
- const hasIssuerBefore = await actions.token.hasRole(clientWithAccount, {
1492
- token: address,
1493
- account: account2.address,
1494
- role: 'issuer',
1495
- })
1496
- expect(hasIssuerBefore).toBe(false)
1497
-
1498
- // Grant issuer role to account2
1499
- await actions.token.grantRolesSync(clientWithAccount, {
1500
- token: address,
1501
- roles: ['issuer'],
1502
- to: account2.address,
1503
- })
1504
-
1505
- // Account2 should now have issuer role
1506
- const hasIssuerAfter = await actions.token.hasRole(clientWithAccount, {
1507
- token: address,
1508
- account: account2.address,
1509
- role: 'issuer',
1510
- })
1511
- expect(hasIssuerAfter).toBe(true)
1512
-
1513
- // Account3 should still not have issuer role
1514
- const account3HasIssuer = await actions.token.hasRole(clientWithAccount, {
1515
- token: address,
1516
- account: account3.address,
1517
- role: 'issuer',
1518
- })
1519
- expect(account3HasIssuer).toBe(false)
1520
- })
1521
-
1522
- test('behavior: multiple roles', async () => {
1523
- // Create a new token
1524
- const { token: address } = await actions.token.createSync(
1525
- clientWithAccount,
1526
- {
1527
- currency: 'USD',
1528
- name: 'HasRole Multiple',
1529
- symbol: 'HRMULTI',
1530
- },
1531
- )
1532
-
1533
- // Grant multiple roles to account2
1534
- await actions.token.grantRolesSync(clientWithAccount, {
1535
- token: address,
1536
- roles: ['issuer', 'pause'],
1537
- to: account2.address,
1538
- })
1539
-
1540
- // Check issuer role
1541
- const hasIssuer = await actions.token.hasRole(clientWithAccount, {
1542
- token: address,
1543
- account: account2.address,
1544
- role: 'issuer',
1545
- })
1546
- expect(hasIssuer).toBe(true)
1547
-
1548
- // Check pause role
1549
- const hasPause = await actions.token.hasRole(clientWithAccount, {
1550
- token: address,
1551
- account: account2.address,
1552
- role: 'pause',
1553
- })
1554
- expect(hasPause).toBe(true)
1555
-
1556
- // Check unpause role (not granted)
1557
- const hasUnpause = await actions.token.hasRole(clientWithAccount, {
1558
- token: address,
1559
- account: account2.address,
1560
- role: 'unpause',
1561
- })
1562
- expect(hasUnpause).toBe(false)
1563
- })
1564
-
1565
- test('behavior: after revoke', async () => {
1566
- // Create a new token
1567
- const { token: address } = await actions.token.createSync(
1568
- clientWithAccount,
1569
- {
1570
- currency: 'USD',
1571
- name: 'HasRole Revoke',
1572
- symbol: 'HRREV',
1573
- },
1574
- )
1575
-
1576
- // Grant issuer role to account2
1577
- await actions.token.grantRolesSync(clientWithAccount, {
1578
- token: address,
1579
- roles: ['issuer'],
1580
- to: account2.address,
1581
- })
1582
-
1583
- // Verify has role
1584
- const hasRoleBefore = await actions.token.hasRole(clientWithAccount, {
1585
- token: address,
1586
- account: account2.address,
1587
- role: 'issuer',
1588
- })
1589
- expect(hasRoleBefore).toBe(true)
1590
-
1591
- // Revoke the role
1592
- await actions.token.revokeRolesSync(clientWithAccount, {
1593
- token: address,
1594
- roles: ['issuer'],
1595
- from: account2.address,
1596
- })
1597
-
1598
- // Verify no longer has role
1599
- const hasRoleAfter = await actions.token.hasRole(clientWithAccount, {
1600
- token: address,
1601
- account: account2.address,
1602
- role: 'issuer',
1603
- })
1604
- expect(hasRoleAfter).toBe(false)
1605
- })
1606
-
1607
- test('behavior: with token ID', async () => {
1608
- // Create a new token
1609
- const { token: address, tokenId } = await actions.token.createSync(
1610
- clientWithAccount,
1611
- {
1612
- currency: 'USD',
1613
- name: 'HasRole Token ID',
1614
- symbol: 'HRTID',
1615
- },
1616
- )
1617
-
1618
- // Grant issuer role
1619
- await actions.token.grantRolesSync(clientWithAccount, {
1620
- token: tokenId,
1621
- roles: ['issuer'],
1622
- to: account2.address,
1623
- })
1624
-
1625
- // Check using token ID
1626
- const hasRole = await actions.token.hasRole(clientWithAccount, {
1627
- token: tokenId,
1628
- account: account2.address,
1629
- role: 'issuer',
1630
- })
1631
- expect(hasRole).toBe(true)
1632
-
1633
- // Verify same result with address
1634
- const hasRoleWithAddress = await actions.token.hasRole(clientWithAccount, {
1635
- token: address,
1636
- account: account2.address,
1637
- role: 'issuer',
1638
- })
1639
- expect(hasRoleWithAddress).toBe(true)
1640
- })
1641
- })
1642
-
1643
- describe('getRoleAdmin', () => {
1644
- test('default', async () => {
1645
- // Create a new token where we're the admin
1646
- const { token: address } = await actions.token.createSync(
1647
- clientWithAccount,
1648
- {
1649
- currency: 'USD',
1650
- name: 'GetRoleAdmin Test Token',
1651
- symbol: 'GRATEST',
1652
- },
1653
- )
1654
-
1655
- // Get admin role for issuer role (should be defaultAdmin)
1656
- const issuerAdminRole = await actions.token.getRoleAdmin(
1657
- clientWithAccount,
1658
- {
1659
- token: address,
1660
- role: 'issuer',
1661
- },
1662
- )
1663
- expect(issuerAdminRole).toBe(
1664
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1665
- )
1666
-
1667
- // Get admin role for pause role (should be defaultAdmin)
1668
- const pauseAdminRole = await actions.token.getRoleAdmin(clientWithAccount, {
1669
- token: address,
1670
- role: 'pause',
1671
- })
1672
- expect(pauseAdminRole).toBe(
1673
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1674
- )
1675
-
1676
- // Get admin role for unpause role (should be defaultAdmin)
1677
- const unpauseAdminRole = await actions.token.getRoleAdmin(
1678
- clientWithAccount,
1679
- {
1680
- token: address,
1681
- role: 'unpause',
1682
- },
1683
- )
1684
- expect(unpauseAdminRole).toBe(
1685
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1686
- )
1687
- })
1688
-
1689
- test('behavior: after setting role admin', async () => {
1690
- // Create a new token
1691
- const { token: address } = await actions.token.createSync(
1692
- clientWithAccount,
1693
- {
1694
- currency: 'USD',
1695
- name: 'GetRoleAdmin After Set',
1696
- symbol: 'GRASET',
1697
- },
1698
- )
1699
-
1700
- // Get initial admin role for issuer
1701
- const initialAdminRole = await actions.token.getRoleAdmin(
1702
- clientWithAccount,
1703
- {
1704
- token: address,
1705
- role: 'issuer',
1706
- },
1707
- )
1708
- expect(initialAdminRole).toBe(
1709
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1710
- )
1711
-
1712
- // Set pause as admin role for issuer
1713
- await actions.token.setRoleAdminSync(clientWithAccount, {
1714
- token: address,
1715
- role: 'issuer',
1716
- adminRole: 'pause',
1717
- })
1718
-
1719
- // Get updated admin role for issuer
1720
- const updatedAdminRole = await actions.token.getRoleAdmin(
1721
- clientWithAccount,
1722
- {
1723
- token: address,
1724
- role: 'issuer',
1725
- },
1726
- )
1727
- expect(updatedAdminRole).toBe(TokenRole.serialize('pause'))
1728
- })
1729
-
1730
- test('behavior: with token ID', async () => {
1731
- // Create a new token
1732
- const { token: address, tokenId } = await actions.token.createSync(
1733
- clientWithAccount,
1734
- {
1735
- currency: 'USD',
1736
- name: 'GetRoleAdmin Token ID',
1737
- symbol: 'GRATID',
1738
- },
1739
- )
1740
-
1741
- // Get admin role using token ID
1742
- const adminRoleWithId = await actions.token.getRoleAdmin(
1743
- clientWithAccount,
1744
- {
1745
- token: tokenId,
1746
- role: 'issuer',
1747
- },
1748
- )
1749
- expect(adminRoleWithId).toBe(
1750
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1751
- )
1752
-
1753
- // Get admin role using address
1754
- const adminRoleWithAddress = await actions.token.getRoleAdmin(
1755
- clientWithAccount,
1756
- {
1757
- token: address,
1758
- role: 'issuer',
1759
- },
1760
- )
1761
- expect(adminRoleWithAddress).toBe(adminRoleWithId)
1762
- })
1763
-
1764
- test('behavior: defaultAdmin role admin', async () => {
1765
- // Create a new token
1766
- const { token: address } = await actions.token.createSync(
1767
- clientWithAccount,
1768
- {
1769
- currency: 'USD',
1770
- name: 'GetRoleAdmin DefaultAdmin',
1771
- symbol: 'GRADMIN',
1772
- },
1773
- )
1774
-
1775
- // Get admin role for defaultAdmin role (should be itself - 0x00)
1776
- const defaultAdminAdminRole = await actions.token.getRoleAdmin(
1777
- clientWithAccount,
1778
- {
1779
- token: address,
1780
- role: 'defaultAdmin',
1781
- },
1782
- )
1783
- expect(defaultAdminAdminRole).toBe(
1784
- '0x0000000000000000000000000000000000000000000000000000000000000000',
1785
- )
1786
- })
1787
- })
1788
-
1789
- describe('grantRoles', () => {
1790
- test('default', async () => {
1791
- // Create a new token where we're the admin
1792
- const { token: address } = await actions.token.createSync(
1793
- clientWithAccount,
1794
- {
1795
- admin: clientWithAccount.account,
1796
- currency: 'USD',
1797
- name: 'Test Token',
1798
- symbol: 'TEST',
1799
- },
1800
- )
1801
-
1802
- // Grant issuer role to account2
1803
- const { receipt: grantReceipt, value: grantValue } =
1804
- await actions.token.grantRolesSync(clientWithAccount, {
1805
- token: address,
1806
- roles: ['issuer'],
1807
- to: account2.address,
1808
- })
1809
-
1810
- expect(grantReceipt.status).toBe('success')
1811
- expect(grantValue).toHaveLength(1)
1812
- const { role, ...restGrant } = grantValue[0]!
1813
- expect(restGrant).toMatchInlineSnapshot(`
1814
- {
1815
- "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
1816
- "hasRole": true,
1817
- "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1818
- }
1819
- `)
1820
- expect(role).toBeDefined()
1821
- })
1822
- })
1823
-
1824
- describe('revokeTokenRole', async () => {
1825
- test('default', async () => {
1826
- const { token: address } = await actions.token.createSync(
1827
- clientWithAccount,
1828
- {
1829
- admin: clientWithAccount.account,
1830
- currency: 'USD',
1831
- name: 'Test Token 2',
1832
- symbol: 'TEST2',
1833
- },
1834
- )
1835
-
1836
- await actions.token.grantRolesSync(clientWithAccount, {
1837
- token: address,
1838
- roles: ['issuer'],
1839
- to: account2.address,
1840
- })
1841
-
1842
- const { receipt: revokeReceipt, value: revokeValue } =
1843
- await actions.token.revokeRolesSync(clientWithAccount, {
1844
- from: account2.address,
1845
- token: address,
1846
- roles: ['issuer'],
1847
- })
1848
-
1849
- expect(revokeReceipt.status).toBe('success')
1850
- expect(revokeValue).toHaveLength(1)
1851
- const { role, ...restRevoke } = revokeValue[0]!
1852
- expect(restRevoke).toMatchInlineSnapshot(`
1853
- {
1854
- "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
1855
- "hasRole": false,
1856
- "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1857
- }
1858
- `)
1859
- expect(role).toBeDefined()
1860
- })
1861
- })
1862
-
1863
- describe('renounceTokenRole', async () => {
1864
- test('default', async () => {
1865
- const { token: address } = await actions.token.createSync(
1866
- clientWithAccount,
1867
- {
1868
- admin: clientWithAccount.account,
1869
- currency: 'USD',
1870
- name: 'Test Token 3',
1871
- symbol: 'TEST3',
1872
- },
1873
- )
1874
-
1875
- const { receipt: grantReceipt } = await actions.token.grantRolesSync(
1876
- clientWithAccount,
1877
- {
1878
- token: address,
1879
- roles: ['issuer'],
1880
- to: clientWithAccount.account.address,
1881
- },
1882
- )
1883
- expect(grantReceipt.status).toBe('success')
1884
-
1885
- const { receipt: renounceReceipt, value: renounceValue } =
1886
- await actions.token.renounceRolesSync(clientWithAccount, {
1887
- token: address,
1888
- roles: ['issuer'],
1889
- })
1890
-
1891
- expect(renounceReceipt.status).toBe('success')
1892
- expect(renounceValue).toHaveLength(1)
1893
- const { role, ...restRenounce } = renounceValue[0]!
1894
- expect(restRenounce).toMatchInlineSnapshot(`
1895
- {
1896
- "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1897
- "hasRole": false,
1898
- "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1899
- }
1900
- `)
1901
- expect(role).toBeDefined()
1902
- })
1903
- })
1904
-
1905
- describe.todo('setRoleAdmin')
1906
-
1907
- describe('watchCreate', () => {
1908
- test('default', async () => {
1909
- const receivedTokens: Array<{
1910
- args: actions.token.watchCreate.Args
1911
- log: actions.token.watchCreate.Log
1912
- }> = []
1913
-
1914
- const unwatch = actions.token.watchCreate(clientWithAccount, {
1915
- onTokenCreated: (args, log) => {
1916
- receivedTokens.push({ args, log })
1917
- },
1918
- })
1919
-
1920
- try {
1921
- await actions.token.createSync(clientWithAccount, {
1922
- currency: 'USD',
1923
- name: 'Watch Test Token 1',
1924
- symbol: 'WATCH1',
1925
- })
1926
-
1927
- await actions.token.createSync(clientWithAccount, {
1928
- currency: 'USD',
1929
- name: 'Watch Test Token 2',
1930
- symbol: 'WATCH2',
1931
- })
1932
-
1933
- await setTimeout(500)
1934
-
1935
- expect(receivedTokens).toHaveLength(2)
1936
- } finally {
1937
- // Clean up watcher
1938
- if (unwatch) unwatch()
1939
- }
1940
- })
1941
-
1942
- test('behavior: filter by tokenId', async () => {
1943
- // First, create a token to know what ID we're at
1944
- const { tokenId: firstId } = await actions.token.createSync(
1945
- clientWithAccount,
1946
- {
1947
- currency: 'USD',
1948
- name: 'Setup Token',
1949
- symbol: 'SETUP',
1950
- },
1951
- )
1952
-
1953
- // We want to watch for the token with ID = firstId + 2
1954
- const targetTokenId = firstId + 2n
1955
-
1956
- const receivedTokens: Array<{
1957
- args: actions.token.watchCreate.Args
1958
- log: actions.token.watchCreate.Log
1959
- }> = []
1960
-
1961
- // Start watching for token creation events only for targetTokenId
1962
- const unwatch = actions.token.watchCreate(clientWithAccount, {
1963
- args: {
1964
- tokenId: targetTokenId,
1965
- },
1966
- onTokenCreated: (args, log) => {
1967
- receivedTokens.push({ args, log })
1968
- },
1969
- })
1970
-
1971
- try {
1972
- // Create first token (should NOT be captured - ID will be firstId + 1)
1973
- await actions.token.createSync(clientWithAccount, {
1974
- currency: 'USD',
1975
- name: 'Filtered Watch Token 1',
1976
- symbol: 'FWATCH1',
1977
- })
1978
-
1979
- // Create second token (should be captured - ID will be firstId + 2 = targetTokenId)
1980
- const { tokenId: id2 } = await actions.token.createSync(
1981
- clientWithAccount,
1982
- {
1983
- currency: 'USD',
1984
- name: 'Filtered Watch Token 2',
1985
- symbol: 'FWATCH2',
1986
- },
1987
- )
1988
-
1989
- // Create third token (should NOT be captured - ID will be firstId + 3)
1990
- await actions.token.createSync(clientWithAccount, {
1991
- currency: 'USD',
1992
- name: 'Filtered Watch Token 3',
1993
- symbol: 'FWATCH3',
1994
- })
1995
-
1996
- await setTimeout(500)
1997
-
1998
- // Should only receive 1 event (for targetTokenId)
1999
- expect(receivedTokens).toHaveLength(1)
2000
-
2001
- expect(receivedTokens.at(0)!.args.tokenId).toBe(targetTokenId)
2002
- expect(receivedTokens.at(0)!.args.tokenId).toBe(id2)
2003
-
2004
- const { token, tokenId, ...rest } = receivedTokens.at(0)!.args
2005
- expect(rest).toMatchInlineSnapshot(`
2006
- {
2007
- "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2008
- "currency": "USD",
2009
- "name": "Filtered Watch Token 2",
2010
- "quoteToken": "0x20C0000000000000000000000000000000000000",
2011
- "symbol": "FWATCH2",
2012
- }
2013
- `)
2014
- expect(token).toBeDefined()
2015
- expect(tokenId).toBe(targetTokenId)
2016
- } finally {
2017
- if (unwatch) unwatch()
2018
- }
2019
- })
2020
- })
2021
-
2022
- describe('watchMint', () => {
2023
- test('default', async () => {
2024
- // Create a new token for testing
2025
- const { token: address } = await actions.token.createSync(
2026
- clientWithAccount,
2027
- {
2028
- currency: 'USD',
2029
- name: 'Mint Watch Token',
2030
- symbol: 'MINT',
2031
- },
2032
- )
2033
-
2034
- // Grant issuer role
2035
- await actions.token.grantRolesSync(clientWithAccount, {
2036
- token: address,
2037
- roles: ['issuer'],
2038
- to: clientWithAccount.account.address,
2039
- })
2040
-
2041
- const receivedMints: Array<{
2042
- args: actions.token.watchMint.Args
2043
- log: actions.token.watchMint.Log
2044
- }> = []
2045
-
2046
- // Start watching for mint events
2047
- const unwatch = actions.token.watchMint(clientWithAccount, {
2048
- token: address,
2049
- onMint: (args, log) => {
2050
- receivedMints.push({ args, log })
2051
- },
2052
- })
2053
-
2054
- try {
2055
- // Mint first batch
2056
- await actions.token.mintSync(clientWithAccount, {
2057
- token: address,
2058
- to: account2.address,
2059
- amount: parseUnits('100', 6),
2060
- })
2061
-
2062
- // Mint second batch
2063
- await actions.token.mintSync(clientWithAccount, {
2064
- token: address,
2065
- to: account3.address,
2066
- amount: parseUnits('50', 6),
2067
- })
2068
-
2069
- await setTimeout(500)
2070
-
2071
- expect(receivedMints).toHaveLength(2)
2072
-
2073
- expect(receivedMints.at(0)!.args).toMatchInlineSnapshot(`
2074
- {
2075
- "amount": 100000000n,
2076
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2077
- }
2078
- `)
2079
- expect(receivedMints.at(1)!.args).toMatchInlineSnapshot(`
2080
- {
2081
- "amount": 50000000n,
2082
- "to": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46",
2083
- }
2084
- `)
2085
- } finally {
2086
- if (unwatch) unwatch()
2087
- }
2088
- })
2089
-
2090
- test('behavior: filter by to address', async () => {
2091
- // Create a new token for testing
2092
- const { token: address } = await actions.token.createSync(
2093
- clientWithAccount,
2094
- {
2095
- currency: 'USD',
2096
- name: 'Filtered Mint Token',
2097
- symbol: 'FMINT',
2098
- },
2099
- )
2100
-
2101
- // Grant issuer role
2102
- await actions.token.grantRolesSync(clientWithAccount, {
2103
- token: address,
2104
- roles: ['issuer'],
2105
- to: clientWithAccount.account.address,
2106
- })
2107
-
2108
- const receivedMints: Array<{
2109
- args: actions.token.watchMint.Args
2110
- log: actions.token.watchMint.Log
2111
- }> = []
2112
-
2113
- // Start watching for mint events only to account2
2114
- const unwatch = actions.token.watchMint(clientWithAccount, {
2115
- token: address,
2116
- args: {
2117
- to: account2.address,
2118
- },
2119
- onMint: (args, log) => {
2120
- receivedMints.push({ args, log })
2121
- },
2122
- })
2123
-
2124
- try {
2125
- // Mint to account2 (should be captured)
2126
- await actions.token.mintSync(clientWithAccount, {
2127
- token: address,
2128
- to: account2.address,
2129
- amount: parseUnits('100', 6),
2130
- })
2131
-
2132
- // Mint to account3 (should NOT be captured)
2133
- await actions.token.mintSync(clientWithAccount, {
2134
- token: address,
2135
- to: account3.address,
2136
- amount: parseUnits('50', 6),
2137
- })
2138
-
2139
- // Mint to account2 again (should be captured)
2140
- await actions.token.mintSync(clientWithAccount, {
2141
- token: address,
2142
- to: account2.address,
2143
- amount: parseUnits('75', 6),
2144
- })
2145
-
2146
- await setTimeout(500)
2147
-
2148
- // Should only receive 2 events (for account2)
2149
- expect(receivedMints).toHaveLength(2)
2150
-
2151
- expect(receivedMints.at(0)!.args).toMatchInlineSnapshot(`
2152
- {
2153
- "amount": 100000000n,
2154
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2155
- }
2156
- `)
2157
- expect(receivedMints.at(1)!.args).toMatchInlineSnapshot(`
2158
- {
2159
- "amount": 75000000n,
2160
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2161
- }
2162
- `)
2163
-
2164
- // Verify all received mints are to account2
2165
- for (const mint of receivedMints) {
2166
- expect(mint.args.to).toBe(account2.address)
2167
- }
2168
- } finally {
2169
- if (unwatch) unwatch()
2170
- }
2171
- })
2172
- })
2173
-
2174
- describe('watchApprove', () => {
2175
- test('default', async () => {
2176
- // Create a new token for testing
2177
- const { token: address } = await actions.token.createSync(
2178
- clientWithAccount,
2179
- {
2180
- currency: 'USD',
2181
- name: 'Approval Watch Token',
2182
- symbol: 'APPR',
2183
- },
2184
- )
2185
-
2186
- const receivedApprovals: Array<{
2187
- args: actions.token.watchApprove.Args
2188
- log: actions.token.watchApprove.Log
2189
- }> = []
2190
-
2191
- // Start watching for approval events
2192
- const unwatch = actions.token.watchApprove(clientWithAccount, {
2193
- token: address,
2194
- onApproval: (args, log) => {
2195
- receivedApprovals.push({ args, log })
2196
- },
2197
- })
2198
-
2199
- try {
2200
- // Approve account2
2201
- await actions.token.approveSync(clientWithAccount, {
2202
- token: address,
2203
- spender: account2.address,
2204
- amount: parseUnits('100', 6),
2205
- })
2206
-
2207
- // Approve account3
2208
- await actions.token.approveSync(clientWithAccount, {
2209
- token: address,
2210
- spender: account3.address,
2211
- amount: parseUnits('50', 6),
2212
- })
2213
-
2214
- await setTimeout(500)
2215
-
2216
- expect(receivedApprovals).toHaveLength(2)
2217
-
2218
- expect(receivedApprovals.at(0)!.args).toMatchInlineSnapshot(`
2219
- {
2220
- "amount": 100000000n,
2221
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2222
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2223
- }
2224
- `)
2225
- expect(receivedApprovals.at(1)!.args).toMatchInlineSnapshot(`
2226
- {
2227
- "amount": 50000000n,
2228
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2229
- "spender": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46",
2230
- }
2231
- `)
2232
- } finally {
2233
- if (unwatch) unwatch()
2234
- }
2235
- })
2236
-
2237
- test('behavior: filter by spender address', async () => {
2238
- // Create a new token for testing
2239
- const { token: address } = await actions.token.createSync(
2240
- clientWithAccount,
2241
- {
2242
- currency: 'USD',
2243
- name: 'Filtered Approval Token',
2244
- symbol: 'FAPPR',
2245
- },
2246
- )
2247
-
2248
- const receivedApprovals: Array<{
2249
- args: actions.token.watchApprove.Args
2250
- log: actions.token.watchApprove.Log
2251
- }> = []
2252
-
2253
- // Start watching for approval events only to account2
2254
- const unwatch = actions.token.watchApprove(clientWithAccount, {
2255
- token: address,
2256
- args: {
2257
- spender: account2.address,
2258
- },
2259
- onApproval: (args, log) => {
2260
- receivedApprovals.push({ args, log })
2261
- },
2262
- })
2263
-
2264
- try {
2265
- // Approve account2 (should be captured)
2266
- await actions.token.approveSync(clientWithAccount, {
2267
- token: address,
2268
- spender: account2.address,
2269
- amount: parseUnits('100', 6),
2270
- })
2271
-
2272
- // Approve account3 (should NOT be captured)
2273
- await actions.token.approveSync(clientWithAccount, {
2274
- token: address,
2275
- spender: account3.address,
2276
- amount: parseUnits('50', 6),
2277
- })
2278
-
2279
- // Approve account2 again (should be captured)
2280
- await actions.token.approveSync(clientWithAccount, {
2281
- token: address,
2282
- spender: account2.address,
2283
- amount: parseUnits('75', 6),
2284
- })
2285
-
2286
- await setTimeout(500)
2287
-
2288
- // Should only receive 2 events (for account2)
2289
- expect(receivedApprovals).toHaveLength(2)
2290
-
2291
- expect(receivedApprovals.at(0)!.args).toMatchInlineSnapshot(`
2292
- {
2293
- "amount": 100000000n,
2294
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2295
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2296
- }
2297
- `)
2298
- expect(receivedApprovals.at(1)!.args).toMatchInlineSnapshot(`
2299
- {
2300
- "amount": 75000000n,
2301
- "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2302
- "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2303
- }
2304
- `)
2305
-
2306
- // Verify all received approvals are for account2
2307
- for (const approval of receivedApprovals) {
2308
- expect(approval.args.spender).toBe(account2.address)
2309
- }
2310
- } finally {
2311
- if (unwatch) unwatch()
2312
- }
2313
- })
2314
- })
2315
-
2316
- describe('watchBurn', () => {
2317
- test('default', async () => {
2318
- // Create a new token for testing
2319
- const { token: address } = await actions.token.createSync(
2320
- clientWithAccount,
2321
- {
2322
- currency: 'USD',
2323
- name: 'Burn Watch Token',
2324
- symbol: 'BURN',
2325
- },
2326
- )
2327
-
2328
- // Grant issuer role to mint/burn tokens
2329
- await actions.token.grantRolesSync(clientWithAccount, {
2330
- token: address,
2331
- roles: ['issuer'],
2332
- to: clientWithAccount.account.address,
2333
- })
2334
-
2335
- // Grant issuer role to mint/burn tokens
2336
- await actions.token.grantRolesSync(clientWithAccount, {
2337
- token: address,
2338
- roles: ['issuer'],
2339
- to: account2.address,
2340
- })
2341
-
2342
- // Mint tokens to burn later
2343
- await actions.token.mintSync(clientWithAccount, {
2344
- token: address,
2345
- to: clientWithAccount.account.address,
2346
- amount: parseUnits('200', 6),
2347
- })
2348
-
2349
- await actions.token.mintSync(clientWithAccount, {
2350
- token: address,
2351
- to: account2.address,
2352
- amount: parseUnits('100', 6),
2353
- })
2354
-
2355
- const receivedBurns: Array<{
2356
- args: actions.token.watchBurn.Args
2357
- log: actions.token.watchBurn.Log
2358
- }> = []
2359
-
2360
- // Start watching for burn events
2361
- const unwatch = actions.token.watchBurn(clientWithAccount, {
2362
- token: address,
2363
- onBurn: (args, log) => {
2364
- receivedBurns.push({ args, log })
2365
- },
2366
- })
2367
-
2368
- try {
2369
- // Burn first batch
2370
- await actions.token.burnSync(clientWithAccount, {
2371
- token: address,
2372
- amount: parseUnits('50', 6),
2373
- })
2374
-
2375
- // Transfer gas to account2
2376
- await writeContractSync(clientWithAccount, {
2377
- abi: Abis.tip20,
2378
- address: addresses.alphaUsd,
2379
- functionName: 'transfer',
2380
- args: [account2.address, parseUnits('1', 6)],
2381
- })
2382
-
2383
- // Burn second batch from account2
2384
- await actions.token.burnSync(clientWithAccount, {
2385
- account: account2,
2386
- token: address,
2387
- amount: parseUnits('25', 6),
2388
- })
2389
-
2390
- await setTimeout(500)
2391
-
2392
- expect(receivedBurns).toHaveLength(2)
2393
-
2394
- expect(receivedBurns.at(0)!.args).toMatchInlineSnapshot(`
2395
- {
2396
- "amount": 50000000n,
2397
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2398
- }
2399
- `)
2400
- expect(receivedBurns.at(1)!.args).toMatchInlineSnapshot(`
2401
- {
2402
- "amount": 25000000n,
2403
- "from": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2404
- }
2405
- `)
2406
- } finally {
2407
- if (unwatch) unwatch()
2408
- }
2409
- })
2410
-
2411
- test('behavior: filter by from address', async () => {
2412
- // Create a new token for testing
2413
- const { token: address } = await actions.token.createSync(
2414
- clientWithAccount,
2415
- {
2416
- currency: 'USD',
2417
- name: 'Filtered Burn Token',
2418
- symbol: 'FBURN',
2419
- },
2420
- )
2421
-
2422
- // Grant issuer role
2423
- await actions.token.grantRolesSync(clientWithAccount, {
2424
- token: address,
2425
- roles: ['issuer'],
2426
- to: clientWithAccount.account.address,
2427
- })
2428
-
2429
- // Grant issuer role
2430
- await actions.token.grantRolesSync(clientWithAccount, {
2431
- token: address,
2432
- roles: ['issuer'],
2433
- to: account2.address,
2434
- })
2435
-
2436
- // Mint tokens to multiple accounts
2437
- await actions.token.mintSync(clientWithAccount, {
2438
- token: address,
2439
- to: clientWithAccount.account.address,
2440
- amount: parseUnits('200', 6),
2441
- })
2442
-
2443
- await actions.token.mintSync(clientWithAccount, {
2444
- token: address,
2445
- to: account2.address,
2446
- amount: parseUnits('200', 6),
2447
- })
2448
-
2449
- const receivedBurns: Array<{
2450
- args: actions.token.watchBurn.Args
2451
- log: actions.token.watchBurn.Log
2452
- }> = []
2453
-
2454
- // Start watching for burn events only from clientWithAccount.account
2455
- const unwatch = actions.token.watchBurn(clientWithAccount, {
2456
- token: address,
2457
- args: {
2458
- from: clientWithAccount.account.address,
2459
- },
2460
- onBurn: (args, log) => {
2461
- receivedBurns.push({ args, log })
2462
- },
2463
- })
2464
-
2465
- try {
2466
- // Burn from clientWithAccount.account (should be captured)
2467
- await actions.token.burnSync(clientWithAccount, {
2468
- token: address,
2469
- amount: parseUnits('50', 6),
2470
- })
2471
-
2472
- // Transfer gas to account2
2473
- await writeContractSync(clientWithAccount, {
2474
- abi: Abis.tip20,
2475
- address: addresses.alphaUsd,
2476
- functionName: 'transfer',
2477
- args: [account2.address, parseUnits('1', 6)],
2478
- })
2479
-
2480
- // Burn from account2 (should NOT be captured)
2481
- await actions.token.burnSync(clientWithAccount, {
2482
- account: account2,
2483
- token: address,
2484
- amount: parseUnits('25', 6),
2485
- })
2486
-
2487
- // Burn from clientWithAccount.account again (should be captured)
2488
- await actions.token.burnSync(clientWithAccount, {
2489
- token: address,
2490
- amount: parseUnits('75', 6),
2491
- })
2492
-
2493
- await setTimeout(500)
2494
-
2495
- // Should only receive 2 events (from clientWithAccount.account)
2496
- expect(receivedBurns).toHaveLength(2)
2497
-
2498
- expect(receivedBurns.at(0)!.args).toMatchInlineSnapshot(`
2499
- {
2500
- "amount": 50000000n,
2501
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2502
- }
2503
- `)
2504
- expect(receivedBurns.at(1)!.args).toMatchInlineSnapshot(`
2505
- {
2506
- "amount": 75000000n,
2507
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2508
- }
2509
- `)
2510
-
2511
- // Verify all received burns are from clientWithAccount.account
2512
- for (const burn of receivedBurns) {
2513
- expect(burn.args.from).toBe(clientWithAccount.account.address)
2514
- }
2515
- } finally {
2516
- if (unwatch) unwatch()
2517
- }
2518
- })
2519
- })
2520
-
2521
- describe('watchAdminRole', () => {
2522
- test('default', async () => {
2523
- // Create a new token for testing
2524
- const { token: address } = await actions.token.createSync(
2525
- clientWithAccount,
2526
- {
2527
- currency: 'USD',
2528
- name: 'Admin Role Watch Token',
2529
- symbol: 'ADMIN',
2530
- },
2531
- )
2532
-
2533
- const receivedAdminUpdates: Array<{
2534
- args: actions.token.watchAdminRole.Args
2535
- log: actions.token.watchAdminRole.Log
2536
- }> = []
2537
-
2538
- // Start watching for role admin updates
2539
- const unwatch = actions.token.watchAdminRole(clientWithAccount, {
2540
- token: address,
2541
- onRoleAdminUpdated: (args, log) => {
2542
- receivedAdminUpdates.push({ args, log })
2543
- },
2544
- })
2545
-
2546
- try {
2547
- // Set role admin for issuer role
2548
- const {
2549
- receipt: setRoleAdmin1Receipt,
2550
- role,
2551
- newAdminRole,
2552
- ...setRoleAdmin1Result
2553
- } = await actions.token.setRoleAdminSync(clientWithAccount, {
2554
- token: address,
2555
- role: 'issuer',
2556
- adminRole: 'pause',
2557
- })
2558
- expect(setRoleAdmin1Receipt).toBeDefined()
2559
- expect(setRoleAdmin1Result).toMatchInlineSnapshot(`
2560
- {
2561
- "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2562
- }
2563
- `)
2564
- expect(role).toBeDefined()
2565
- expect(newAdminRole).toBeDefined()
2566
-
2567
- // Set role admin for pause role
2568
- await actions.token.setRoleAdminSync(clientWithAccount, {
2569
- token: address,
2570
- role: 'pause',
2571
- adminRole: 'unpause',
2572
- })
2573
-
2574
- await setTimeout(500)
2575
-
2576
- expect(receivedAdminUpdates).toHaveLength(2)
2577
-
2578
- expect(receivedAdminUpdates.at(0)!.args.sender).toBe(
2579
- clientWithAccount.account.address,
2580
- )
2581
- expect(receivedAdminUpdates.at(1)!.args.sender).toBe(
2582
- clientWithAccount.account.address,
2583
- )
2584
- } finally {
2585
- if (unwatch) unwatch()
2586
- }
2587
- })
2588
- })
2589
-
2590
- describe('watchRole', () => {
2591
- test('default', async () => {
2592
- // Create a new token for testing
2593
- const { token: address } = await actions.token.createSync(
2594
- clientWithAccount,
2595
- {
2596
- currency: 'USD',
2597
- name: 'Role Watch Token',
2598
- symbol: 'ROLE',
2599
- },
2600
- )
2601
-
2602
- const receivedRoleUpdates: Array<{
2603
- args: actions.token.watchRole.Args
2604
- log: actions.token.watchRole.Log
2605
- }> = []
2606
-
2607
- // Start watching for role membership updates
2608
- const unwatch = actions.token.watchRole(clientWithAccount, {
2609
- token: address,
2610
- onRoleUpdated: (args, log) => {
2611
- receivedRoleUpdates.push({ args, log })
2612
- },
2613
- })
2614
-
2615
- try {
2616
- // Grant issuer role to account2
2617
- await actions.token.grantRolesSync(clientWithAccount, {
2618
- token: address,
2619
- roles: ['issuer'],
2620
- to: account2.address,
2621
- })
2622
-
2623
- // Grant pause role to account3
2624
- await actions.token.grantRolesSync(clientWithAccount, {
2625
- token: address,
2626
- roles: ['pause'],
2627
- to: account3.address,
2628
- })
2629
-
2630
- // Revoke issuer role from account2
2631
- await actions.token.revokeRolesSync(clientWithAccount, {
2632
- token: address,
2633
- roles: ['issuer'],
2634
- from: account2.address,
2635
- })
2636
-
2637
- await setTimeout(500)
2638
-
2639
- expect(receivedRoleUpdates).toHaveLength(3)
2640
-
2641
- // First event: grant issuer
2642
- expect(receivedRoleUpdates.at(0)!.args.type).toBe('granted')
2643
- expect(receivedRoleUpdates.at(0)!.args.account).toBe(account2.address)
2644
- expect(receivedRoleUpdates.at(0)!.args.hasRole).toBe(true)
2645
-
2646
- // Second event: grant pause
2647
- expect(receivedRoleUpdates.at(1)!.args.type).toBe('granted')
2648
- expect(receivedRoleUpdates.at(1)!.args.account).toBe(account3.address)
2649
- expect(receivedRoleUpdates.at(1)!.args.hasRole).toBe(true)
2650
-
2651
- // Third event: revoke issuer
2652
- expect(receivedRoleUpdates.at(2)!.args.type).toBe('revoked')
2653
- expect(receivedRoleUpdates.at(2)!.args.account).toBe(account2.address)
2654
- expect(receivedRoleUpdates.at(2)!.args.hasRole).toBe(false)
2655
- } finally {
2656
- if (unwatch) unwatch()
2657
- }
2658
- })
2659
-
2660
- test('behavior: filter by account address', async () => {
2661
- // Create a new token for testing
2662
- const { token: address } = await actions.token.createSync(
2663
- clientWithAccount,
2664
- {
2665
- currency: 'USD',
2666
- name: 'Filtered Role Token',
2667
- symbol: 'FROLE',
2668
- },
2669
- )
2670
-
2671
- const receivedRoleUpdates: Array<{
2672
- args: actions.token.watchRole.Args
2673
- log: actions.token.watchRole.Log
2674
- }> = []
2675
-
2676
- // Start watching for role updates only for account2
2677
- const unwatch = actions.token.watchRole(clientWithAccount, {
2678
- token: address,
2679
- args: {
2680
- account: account2.address,
2681
- },
2682
- onRoleUpdated: (args, log) => {
2683
- receivedRoleUpdates.push({ args, log })
2684
- },
2685
- })
2686
-
2687
- try {
2688
- // Grant issuer role to account2 (should be captured)
2689
- await actions.token.grantRolesSync(clientWithAccount, {
2690
- token: address,
2691
- roles: ['issuer'],
2692
- to: account2.address,
2693
- })
2694
-
2695
- // Grant pause role to account3 (should NOT be captured)
2696
- await actions.token.grantRolesSync(clientWithAccount, {
2697
- token: address,
2698
- roles: ['pause'],
2699
- to: account3.address,
2700
- })
2701
-
2702
- // Revoke issuer role from account2 (should be captured)
2703
- await actions.token.revokeRolesSync(clientWithAccount, {
2704
- token: address,
2705
- roles: ['issuer'],
2706
- from: account2.address,
2707
- })
2708
-
2709
- await setTimeout(500)
2710
-
2711
- // Should only receive 2 events (for account2)
2712
- expect(receivedRoleUpdates).toHaveLength(2)
2713
-
2714
- // First: grant to account2
2715
- expect(receivedRoleUpdates.at(0)!.args.type).toBe('granted')
2716
- expect(receivedRoleUpdates.at(0)!.args.account).toBe(account2.address)
2717
- expect(receivedRoleUpdates.at(0)!.args.hasRole).toBe(true)
2718
-
2719
- // Second: revoke from account2
2720
- expect(receivedRoleUpdates.at(1)!.args.type).toBe('revoked')
2721
- expect(receivedRoleUpdates.at(1)!.args.account).toBe(account2.address)
2722
- expect(receivedRoleUpdates.at(1)!.args.hasRole).toBe(false)
2723
-
2724
- // Verify all received events are for account2
2725
- for (const update of receivedRoleUpdates) {
2726
- expect(update.args.account).toBe(account2.address)
2727
- }
2728
- } finally {
2729
- if (unwatch) unwatch()
2730
- }
2731
- })
2732
- })
2733
-
2734
- describe('watchTransfer', () => {
2735
- beforeAll(async () => {
2736
- await fetch(`${rpcUrl}/restart`)
2737
- })
2738
-
2739
- test('default', async () => {
2740
- // Create a new token for testing
2741
- const { token: address } = await actions.token.createSync(
2742
- clientWithAccount,
2743
- {
2744
- currency: 'USD',
2745
- name: 'Transfer Watch Token',
2746
- symbol: 'XFER',
2747
- },
2748
- )
2749
-
2750
- // Grant issuer role to mint tokens
2751
- await actions.token.grantRolesSync(clientWithAccount, {
2752
- token: address,
2753
- roles: ['issuer'],
2754
- to: clientWithAccount.account.address,
2755
- })
2756
-
2757
- // Mint tokens to transfer
2758
- await actions.token.mintSync(clientWithAccount, {
2759
- token: address,
2760
- to: clientWithAccount.account.address,
2761
- amount: parseUnits('500', 6),
2762
- })
2763
-
2764
- const receivedTransfers: Array<{
2765
- args: actions.token.watchTransfer.Args
2766
- log: actions.token.watchTransfer.Log
2767
- }> = []
2768
-
2769
- // Start watching for transfer events
2770
- const unwatch = actions.token.watchTransfer(clientWithAccount, {
2771
- token: address,
2772
- onTransfer: (args, log) => {
2773
- receivedTransfers.push({ args, log })
2774
- },
2775
- })
2776
-
2777
- try {
2778
- // Transfer to account2
2779
- await actions.token.transferSync(clientWithAccount, {
2780
- token: address,
2781
- to: account2.address,
2782
- amount: parseUnits('100', 6),
2783
- })
2784
-
2785
- // Transfer to account3
2786
- await actions.token.transferSync(clientWithAccount, {
2787
- token: address,
2788
- to: account3.address,
2789
- amount: parseUnits('50', 6),
2790
- })
2791
-
2792
- await setTimeout(200)
2793
-
2794
- expect(receivedTransfers.length).toBeGreaterThanOrEqual(2)
2795
-
2796
- expect(receivedTransfers.at(0)!.args).toMatchInlineSnapshot(`
2797
- {
2798
- "amount": 100000000n,
2799
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2800
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2801
- }
2802
- `)
2803
- expect(receivedTransfers.at(1)!.args).toMatchInlineSnapshot(`
2804
- {
2805
- "amount": 50000000n,
2806
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2807
- "to": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46",
2808
- }
2809
- `)
2810
- } finally {
2811
- if (unwatch) unwatch()
2812
- }
2813
- })
2814
-
2815
- test('behavior: filter by to address', async () => {
2816
- // Create a new token for testing
2817
- const { token: address } = await actions.token.createSync(
2818
- clientWithAccount,
2819
- {
2820
- currency: 'USD',
2821
- name: 'Filtered Transfer Token',
2822
- symbol: 'FXFER',
2823
- },
2824
- )
2825
-
2826
- // Grant issuer role
2827
- await actions.token.grantRolesSync(clientWithAccount, {
2828
- token: address,
2829
- roles: ['issuer'],
2830
- to: clientWithAccount.account.address,
2831
- })
2832
-
2833
- // Mint tokens
2834
- await actions.token.mintSync(clientWithAccount, {
2835
- token: address,
2836
- to: clientWithAccount.account.address,
2837
- amount: parseUnits('500', 6),
2838
- })
2839
-
2840
- const receivedTransfers: Array<{
2841
- args: actions.token.watchTransfer.Args
2842
- log: actions.token.watchTransfer.Log
2843
- }> = []
2844
-
2845
- // Start watching for transfer events only to account2
2846
- const unwatch = actions.token.watchTransfer(clientWithAccount, {
2847
- token: address,
2848
- args: {
2849
- to: account2.address,
2850
- },
2851
- onTransfer: (args, log) => {
2852
- receivedTransfers.push({ args, log })
2853
- },
2854
- })
2855
-
2856
- try {
2857
- // Transfer to account2 (should be captured)
2858
- await actions.token.transferSync(clientWithAccount, {
2859
- token: address,
2860
- to: account2.address,
2861
- amount: parseUnits('100', 6),
2862
- })
2863
-
2864
- // Transfer to account3 (should NOT be captured)
2865
- await actions.token.transferSync(clientWithAccount, {
2866
- token: address,
2867
- to: account3.address,
2868
- amount: parseUnits('50', 6),
2869
- })
2870
-
2871
- // Transfer to account2 again (should be captured)
2872
- await actions.token.transferSync(clientWithAccount, {
2873
- token: address,
2874
- to: account2.address,
2875
- amount: parseUnits('75', 6),
2876
- })
2877
-
2878
- await setTimeout(500)
2879
-
2880
- // Should only receive 2 events (to account2)
2881
- expect(receivedTransfers).toHaveLength(2)
2882
-
2883
- expect(receivedTransfers.at(0)!.args).toMatchInlineSnapshot(`
2884
- {
2885
- "amount": 100000000n,
2886
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2887
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2888
- }
2889
- `)
2890
- expect(receivedTransfers.at(1)!.args).toMatchInlineSnapshot(`
2891
- {
2892
- "amount": 75000000n,
2893
- "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2894
- "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650",
2895
- }
2896
- `)
2897
-
2898
- // Verify all received transfers are to account2
2899
- for (const transfer of receivedTransfers) {
2900
- expect(transfer.args.to).toBe(account2.address)
2901
- }
2902
- } finally {
2903
- if (unwatch) unwatch()
2904
- }
2905
- })
2906
- })
2907
-
2908
- describe('watchUpdateQuoteToken', () => {
2909
- test('default', async () => {
2910
- // Create quote token
2911
- const { token: quoteTokenAddress } = await actions.token.createSync(
2912
- clientWithAccount,
2913
- {
2914
- currency: 'USD',
2915
- name: 'Watch Quote Token',
2916
- symbol: 'WLINK',
2917
- },
2918
- )
2919
-
2920
- // Create main token
2921
- const { token: address } = await actions.token.createSync(
2922
- clientWithAccount,
2923
- {
2924
- currency: 'USD',
2925
- name: 'Watch Main Token',
2926
- symbol: 'WMAIN',
2927
- },
2928
- )
2929
-
2930
- const receivedUpdates: Array<{
2931
- args: actions.token.watchUpdateQuoteToken.Args
2932
- log: actions.token.watchUpdateQuoteToken.Log
2933
- }> = []
2934
-
2935
- // Start watching for quote token update events
2936
- const unwatch = actions.token.watchUpdateQuoteToken(clientWithAccount, {
2937
- token: address,
2938
- onUpdateQuoteToken: (args, log) => {
2939
- receivedUpdates.push({ args, log })
2940
- },
2941
- })
2942
-
2943
- try {
2944
- // Step 1: Prepare update quote token (should emit NextQuoteTokenSet)
2945
- await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
2946
- token: address,
2947
- quoteToken: quoteTokenAddress,
2948
- })
2949
-
2950
- // Step 2: Finalize the update (should emit QuoteTokenUpdateFinalized)
2951
- await actions.token.updateQuoteTokenSync(clientWithAccount, {
2952
- token: address,
2953
- })
2954
-
2955
- await setTimeout(500)
2956
-
2957
- // Should receive 2 events: one for update, one for finalized
2958
- expect(receivedUpdates).toHaveLength(2)
2959
-
2960
- // First event: update proposed (not finalized)
2961
- expect(receivedUpdates.at(0)!.args.completed).toBe(false)
2962
- expect(receivedUpdates.at(0)!.args.nextQuoteToken).toBe(quoteTokenAddress)
2963
- expect(receivedUpdates.at(0)!.args.updater).toBe(
2964
- clientWithAccount.account.address,
2965
- )
2966
-
2967
- // Second event: update finalized
2968
- expect(receivedUpdates.at(1)!.args.completed).toBe(true)
2969
- expect(receivedUpdates.at(1)!.args.newQuoteToken).toBe(quoteTokenAddress)
2970
- expect(receivedUpdates.at(1)!.args.updater).toBe(
2971
- clientWithAccount.account.address,
2972
- )
2973
- } finally {
2974
- if (unwatch) unwatch()
2975
- }
2976
- })
2977
-
2978
- test('behavior: only proposed updates', async () => {
2979
- // Create quote token
2980
- const { token: quoteTokenAddress } = await actions.token.createSync(
2981
- clientWithAccount,
2982
- {
2983
- currency: 'USD',
2984
- name: 'Proposed Quote Token',
2985
- symbol: 'PLINK',
2986
- },
2987
- )
2988
-
2989
- // Create main token
2990
- const { token: address } = await actions.token.createSync(
2991
- clientWithAccount,
2992
- {
2993
- currency: 'USD',
2994
- name: 'Proposed Main Token',
2995
- symbol: 'PMAIN',
2996
- },
2997
- )
2998
-
2999
- const receivedUpdates: Array<{
3000
- args: actions.token.watchUpdateQuoteToken.Args
3001
- log: actions.token.watchUpdateQuoteToken.Log
3002
- }> = []
3003
-
3004
- // Start watching
3005
- const unwatch = actions.token.watchUpdateQuoteToken(clientWithAccount, {
3006
- token: address,
3007
- onUpdateQuoteToken: (args, log) => {
3008
- receivedUpdates.push({ args, log })
3009
- },
3010
- })
3011
-
3012
- try {
3013
- // Only update (don't finalize)
3014
- await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, {
3015
- token: address,
3016
- quoteToken: quoteTokenAddress,
3017
- })
3018
-
3019
- await setTimeout(500)
3020
-
3021
- // Should only receive 1 event (not finalized)
3022
- expect(receivedUpdates).toHaveLength(1)
3023
- expect(receivedUpdates.at(0)!.args.completed).toBe(false)
3024
- expect(receivedUpdates.at(0)!.args.nextQuoteToken).toBe(quoteTokenAddress)
3025
- } finally {
3026
- if (unwatch) unwatch()
3027
- }
3028
- })
3029
- })