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.
- package/CHANGELOG.md +61 -4
- package/README.md +3 -34
- package/dist/server/Handler.d.ts +14 -14
- package/dist/server/Handler.d.ts.map +1 -1
- package/dist/server/Handler.js +16 -17
- package/dist/server/Handler.js.map +1 -1
- package/dist/wagmi/Actions/amm.d.ts +51 -51
- package/dist/wagmi/Actions/amm.d.ts.map +1 -1
- package/dist/wagmi/Actions/amm.js +37 -37
- package/dist/wagmi/Actions/amm.js.map +1 -1
- package/dist/wagmi/Actions/dex.d.ts +129 -129
- package/dist/wagmi/Actions/dex.d.ts.map +1 -1
- package/dist/wagmi/Actions/dex.js +73 -73
- package/dist/wagmi/Actions/dex.js.map +1 -1
- package/dist/wagmi/Actions/faucet.d.ts +9 -9
- package/dist/wagmi/Actions/faucet.d.ts.map +1 -1
- package/dist/wagmi/Actions/faucet.js +7 -7
- package/dist/wagmi/Actions/faucet.js.map +1 -1
- package/dist/wagmi/Actions/fee.d.ts +17 -17
- package/dist/wagmi/Actions/fee.d.ts.map +1 -1
- package/dist/wagmi/Actions/fee.js +10 -10
- package/dist/wagmi/Actions/fee.js.map +1 -1
- package/dist/wagmi/Actions/nonce.d.ts +9 -79
- package/dist/wagmi/Actions/nonce.d.ts.map +1 -1
- package/dist/wagmi/Actions/nonce.js +7 -89
- package/dist/wagmi/Actions/nonce.js.map +1 -1
- package/dist/wagmi/Actions/policy.d.ts +69 -70
- package/dist/wagmi/Actions/policy.d.ts.map +1 -1
- package/dist/wagmi/Actions/policy.js +43 -43
- package/dist/wagmi/Actions/policy.js.map +1 -1
- package/dist/wagmi/Actions/reward.d.ts +51 -51
- package/dist/wagmi/Actions/reward.d.ts.map +1 -1
- package/dist/wagmi/Actions/reward.js +31 -31
- package/dist/wagmi/Actions/reward.js.map +1 -1
- package/dist/wagmi/Actions/token.d.ts +238 -238
- package/dist/wagmi/Actions/token.d.ts.map +1 -1
- package/dist/wagmi/Actions/token.js +136 -136
- package/dist/wagmi/Actions/token.js.map +1 -1
- package/dist/wagmi/Connector.d.ts +2 -1
- package/dist/wagmi/Connector.d.ts.map +1 -1
- package/dist/wagmi/Connector.js +83 -22
- package/dist/wagmi/Connector.js.map +1 -1
- package/dist/wagmi/Hooks/nonce.d.ts +1 -52
- package/dist/wagmi/Hooks/nonce.d.ts.map +1 -1
- package/dist/wagmi/Hooks/nonce.js +1 -70
- package/dist/wagmi/Hooks/nonce.js.map +1 -1
- package/dist/wagmi/Hooks/policy.d.ts +0 -1
- package/dist/wagmi/Hooks/policy.d.ts.map +1 -1
- package/dist/wagmi/Hooks/policy.js.map +1 -1
- package/dist/wagmi/KeyManager.d.ts +6 -3
- package/dist/wagmi/KeyManager.d.ts.map +1 -1
- package/dist/wagmi/KeyManager.js +9 -4
- package/dist/wagmi/KeyManager.js.map +1 -1
- package/package.json +2 -12
- package/src/server/Handler.test.ts +2 -2
- package/src/server/Handler.ts +16 -17
- package/src/wagmi/Actions/amm.ts +63 -63
- package/src/wagmi/Actions/dex.test.ts +1 -1
- package/src/wagmi/Actions/dex.ts +153 -153
- package/src/wagmi/Actions/faucet.ts +11 -11
- package/src/wagmi/Actions/fee.ts +20 -20
- package/src/wagmi/Actions/nonce.test.ts +1 -64
- package/src/wagmi/Actions/nonce.ts +10 -142
- package/src/wagmi/Actions/policy.ts +83 -85
- package/src/wagmi/Actions/reward.ts +64 -61
- package/src/wagmi/Actions/token.ts +287 -283
- package/src/wagmi/Connector.ts +105 -31
- package/src/wagmi/Hooks/dex.test.ts +1 -1
- package/src/wagmi/Hooks/fee.test.ts +0 -6
- package/src/wagmi/Hooks/nonce.test.ts +1 -66
- package/src/wagmi/Hooks/nonce.ts +1 -114
- package/src/wagmi/Hooks/policy.ts +0 -2
- package/src/wagmi/KeyManager.ts +18 -5
- package/dist/chains.d.ts +0 -73
- package/dist/chains.d.ts.map +0 -1
- package/dist/chains.js +0 -51
- package/dist/chains.js.map +0 -1
- package/dist/viem/Abis.d.ts +0 -2649
- package/dist/viem/Abis.d.ts.map +0 -1
- package/dist/viem/Abis.js +0 -1677
- package/dist/viem/Abis.js.map +0 -1
- package/dist/viem/Account.d.ts +0 -244
- package/dist/viem/Account.d.ts.map +0 -1
- package/dist/viem/Account.js +0 -382
- package/dist/viem/Account.js.map +0 -1
- package/dist/viem/Actions/account.d.ts +0 -40
- package/dist/viem/Actions/account.d.ts.map +0 -1
- package/dist/viem/Actions/account.js +0 -86
- package/dist/viem/Actions/account.js.map +0 -1
- package/dist/viem/Actions/amm.d.ts +0 -1991
- package/dist/viem/Actions/amm.d.ts.map +0 -1
- package/dist/viem/Actions/amm.js +0 -814
- package/dist/viem/Actions/amm.js.map +0 -1
- package/dist/viem/Actions/dex.d.ts +0 -3900
- package/dist/viem/Actions/dex.d.ts.map +0 -1
- package/dist/viem/Actions/dex.js +0 -1414
- package/dist/viem/Actions/dex.js.map +0 -1
- package/dist/viem/Actions/faucet.d.ts +0 -69
- package/dist/viem/Actions/faucet.d.ts.map +0 -1
- package/dist/viem/Actions/faucet.js +0 -73
- package/dist/viem/Actions/faucet.js.map +0 -1
- package/dist/viem/Actions/fee.d.ts +0 -360
- package/dist/viem/Actions/fee.d.ts.map +0 -1
- package/dist/viem/Actions/fee.js +0 -237
- package/dist/viem/Actions/fee.js.map +0 -1
- package/dist/viem/Actions/index.d.ts +0 -10
- package/dist/viem/Actions/index.d.ts.map +0 -1
- package/dist/viem/Actions/index.js +0 -10
- package/dist/viem/Actions/index.js.map +0 -1
- package/dist/viem/Actions/nonce.d.ts +0 -257
- package/dist/viem/Actions/nonce.d.ts.map +0 -1
- package/dist/viem/Actions/nonce.js +0 -228
- package/dist/viem/Actions/nonce.js.map +0 -1
- package/dist/viem/Actions/policy.d.ts +0 -1680
- package/dist/viem/Actions/policy.d.ts.map +0 -1
- package/dist/viem/Actions/policy.js +0 -875
- package/dist/viem/Actions/policy.js.map +0 -1
- package/dist/viem/Actions/reward.d.ts +0 -2422
- package/dist/viem/Actions/reward.d.ts.map +0 -1
- package/dist/viem/Actions/reward.js +0 -651
- package/dist/viem/Actions/reward.js.map +0 -1
- package/dist/viem/Actions/token.d.ts +0 -16007
- package/dist/viem/Actions/token.d.ts.map +0 -1
- package/dist/viem/Actions/token.js +0 -2936
- package/dist/viem/Actions/token.js.map +0 -1
- package/dist/viem/Addresses.d.ts +0 -9
- package/dist/viem/Addresses.d.ts.map +0 -1
- package/dist/viem/Addresses.js +0 -9
- package/dist/viem/Addresses.js.map +0 -1
- package/dist/viem/Chain.d.ts +0 -451
- package/dist/viem/Chain.d.ts.map +0 -1
- package/dist/viem/Chain.js +0 -96
- package/dist/viem/Chain.js.map +0 -1
- package/dist/viem/Decorator.d.ts +0 -2783
- package/dist/viem/Decorator.d.ts.map +0 -1
- package/dist/viem/Decorator.js +0 -137
- package/dist/viem/Decorator.js.map +0 -1
- package/dist/viem/Formatters.d.ts +0 -10
- package/dist/viem/Formatters.d.ts.map +0 -1
- package/dist/viem/Formatters.js +0 -104
- package/dist/viem/Formatters.js.map +0 -1
- package/dist/viem/P256.d.ts +0 -2
- package/dist/viem/P256.d.ts.map +0 -1
- package/dist/viem/P256.js +0 -2
- package/dist/viem/P256.js.map +0 -1
- package/dist/viem/Secp256k1.d.ts +0 -2
- package/dist/viem/Secp256k1.d.ts.map +0 -1
- package/dist/viem/Secp256k1.js +0 -2
- package/dist/viem/Secp256k1.js.map +0 -1
- package/dist/viem/Storage.d.ts +0 -24
- package/dist/viem/Storage.d.ts.map +0 -1
- package/dist/viem/Storage.js +0 -68
- package/dist/viem/Storage.js.map +0 -1
- package/dist/viem/TokenIds.d.ts +0 -2
- package/dist/viem/TokenIds.d.ts.map +0 -1
- package/dist/viem/TokenIds.js +0 -2
- package/dist/viem/TokenIds.js.map +0 -1
- package/dist/viem/Transaction.d.ts +0 -76
- package/dist/viem/Transaction.d.ts.map +0 -1
- package/dist/viem/Transaction.js +0 -176
- package/dist/viem/Transaction.js.map +0 -1
- package/dist/viem/Transport.d.ts +0 -33
- package/dist/viem/Transport.d.ts.map +0 -1
- package/dist/viem/Transport.js +0 -138
- package/dist/viem/Transport.js.map +0 -1
- package/dist/viem/WebAuthnP256.d.ts +0 -82
- package/dist/viem/WebAuthnP256.d.ts.map +0 -1
- package/dist/viem/WebAuthnP256.js +0 -97
- package/dist/viem/WebAuthnP256.js.map +0 -1
- package/dist/viem/WebCryptoP256.d.ts +0 -2
- package/dist/viem/WebCryptoP256.d.ts.map +0 -1
- package/dist/viem/WebCryptoP256.js +0 -2
- package/dist/viem/WebCryptoP256.js.map +0 -1
- package/dist/viem/index.d.ts +0 -26
- package/dist/viem/index.d.ts.map +0 -1
- package/dist/viem/index.js +0 -17
- package/dist/viem/index.js.map +0 -1
- package/dist/viem/internal/types.d.ts +0 -20
- package/dist/viem/internal/types.d.ts.map +0 -1
- package/dist/viem/internal/types.js +0 -2
- package/dist/viem/internal/types.js.map +0 -1
- package/dist/viem/internal/utils.d.ts +0 -14
- package/dist/viem/internal/utils.d.ts.map +0 -1
- package/dist/viem/internal/utils.js +0 -33
- package/dist/viem/internal/utils.js.map +0 -1
- package/src/chains.ts +0 -54
- package/src/viem/Abis.ts +0 -1688
- package/src/viem/Account.test.ts +0 -444
- package/src/viem/Account.ts +0 -601
- package/src/viem/Actions/account.test.ts +0 -414
- package/src/viem/Actions/account.ts +0 -106
- package/src/viem/Actions/amm.test.ts +0 -381
- package/src/viem/Actions/amm.ts +0 -1227
- package/src/viem/Actions/dex.test.ts +0 -1549
- package/src/viem/Actions/dex.ts +0 -2150
- package/src/viem/Actions/faucet.ts +0 -121
- package/src/viem/Actions/fee.test.ts +0 -259
- package/src/viem/Actions/fee.ts +0 -372
- package/src/viem/Actions/index.ts +0 -9
- package/src/viem/Actions/nonce.test.ts +0 -206
- package/src/viem/Actions/nonce.ts +0 -347
- package/src/viem/Actions/policy.test.ts +0 -534
- package/src/viem/Actions/policy.ts +0 -1335
- package/src/viem/Actions/reward.test.ts +0 -434
- package/src/viem/Actions/reward.ts +0 -944
- package/src/viem/Actions/token.test.ts +0 -3029
- package/src/viem/Actions/token.ts +0 -4458
- package/src/viem/Addresses.ts +0 -9
- package/src/viem/Chain.bench-d.ts +0 -12
- package/src/viem/Chain.test.ts +0 -168
- package/src/viem/Chain.ts +0 -157
- package/src/viem/Decorator.bench-d.ts +0 -11
- package/src/viem/Decorator.test.ts +0 -39
- package/src/viem/Decorator.ts +0 -3179
- package/src/viem/Formatters.ts +0 -164
- package/src/viem/P256.ts +0 -1
- package/src/viem/Secp256k1.ts +0 -1
- package/src/viem/Storage.ts +0 -110
- package/src/viem/TokenIds.ts +0 -1
- package/src/viem/Transaction.ts +0 -382
- package/src/viem/Transport.ts +0 -191
- package/src/viem/WebAuthnP256.ts +0 -146
- package/src/viem/WebCryptoP256.ts +0 -1
- package/src/viem/e2e.test.ts +0 -1602
- package/src/viem/index.ts +0 -30
- package/src/viem/internal/types.ts +0 -69
- package/src/viem/internal/utils.ts +0 -58
- 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
|
-
})
|