1
- import { Worker } from "near-workspaces" ;
1
+ import { Worker , NEAR } from "near-workspaces" ;
2
2
import test from "ava" ;
3
3
4
4
test . beforeEach ( async ( t ) => {
5
- // Init the worker and start a Sandbox server
6
5
const worker = await Worker . init ( ) ;
7
6
8
- // Prepare sandbox for tests, create accounts, deploy contracts, etx.
9
- const root = worker . rootAccount ;
7
+ const totalSupply = 1000 ;
8
+ const yoctoAccountStorage = "90" ;
10
9
11
- // Deploy the ft contract.
12
- const ft = await root . devDeploy ( "./build/fungible-token.wasm" ) ;
10
+ const root = worker . rootAccount ;
13
11
const xcc = await root . devDeploy ( "./build/fungible-token-helper.wasm" ) ;
12
+ const ft = await root . createSubAccount ( "ft" ) ;
13
+ await ft . deploy ( "./build/fungible-token.wasm" ) ;
14
+ await root . call ( ft , "init" , {
15
+ owner_id : root . accountId ,
16
+ total_supply : totalSupply . toString ( ) ,
17
+ } ) ;
18
+ const alice = await root . createSubAccount ( "alice" , {
19
+ initialBalance : NEAR . parse ( "10 N" ) . toJSON ( ) ,
20
+ } ) ;
14
21
15
- // Init the contracts
16
- await ft . call ( ft , "init" , { prefix : "a" , totalSupply : "1000" } ) ;
17
-
18
- // Create test accounts
19
- const ali = await root . createSubAccount ( "ali" ) ;
20
- const bob = await root . createSubAccount ( "bob" ) ;
21
-
22
- // Save state for test runs, it is unique for each test
23
22
t . context . worker = worker ;
24
- t . context . accounts = { root, ft, ali, bob, xcc } ;
23
+ t . context . accounts = { root, ft, alice, xcc } ;
24
+ t . context . variables = { totalSupply, yoctoAccountStorage } ;
25
25
} ) ;
26
26
27
27
test . afterEach . always ( async ( t ) => {
28
28
await t . context . worker . tearDown ( ) . catch ( ( error ) => {
29
- console . log ( "Failed tear down the worker:" , error ) ;
29
+ console . log ( "Failed to tear down the worker:" , error ) ;
30
30
} ) ;
31
31
} ) ;
32
32
33
+ test ( "should register account and pay for storage" , async ( t ) => {
34
+ const { ft, alice } = t . context . accounts ;
35
+ const { yoctoAccountStorage } = t . context . variables ;
36
+ const result = await alice . call (
37
+ ft ,
38
+ "storage_deposit" ,
39
+ { account_id : alice . accountId } ,
40
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
41
+ ) ;
42
+ const aliceAfterBalance = await alice . balance ( ) ;
43
+ const expected = {
44
+ message : `Account ${ alice . accountId } registered with storage deposit of ${ yoctoAccountStorage } ` ,
45
+ } ;
46
+ t . deepEqual ( result , expected ) ;
47
+ t . true (
48
+ aliceAfterBalance . total > NEAR . parse ( "9 N" ) . toJSON ( ) ,
49
+ "alice should have received a refund"
50
+ ) ;
51
+ } ) ;
52
+
53
+ test ( "should return message when account is already registered and not refund when no deposit is attached" , async ( t ) => {
54
+ const { ft, alice } = t . context . accounts ;
55
+ const { yoctoAccountStorage } = t . context . variables ;
56
+ const result = await alice . call (
57
+ ft ,
58
+ "storage_deposit" ,
59
+ { account_id : alice . accountId } ,
60
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
61
+ ) ;
62
+ const expected = {
63
+ message : `Account ${ alice . accountId } registered with storage deposit of ${ yoctoAccountStorage } ` ,
64
+ } ;
65
+ t . deepEqual ( result , expected ) ;
66
+ const result2 = await alice . call (
67
+ ft ,
68
+ "storage_deposit" ,
69
+ { account_id : alice . accountId } ,
70
+ { attachedDeposit : NEAR . parse ( "0 N" ) . toJSON ( ) }
71
+ ) ;
72
+ t . is ( result2 . message , "Account is already registered" ) ;
73
+ } ) ;
74
+
75
+ test ( "should return message and refund predecessor caller when trying to pay for storage for an account that is already registered" , async ( t ) => {
76
+ const { ft, alice } = t . context . accounts ;
77
+ const { yoctoAccountStorage } = t . context . variables ;
78
+ const result = await alice . call (
79
+ ft ,
80
+ "storage_deposit" ,
81
+ { account_id : alice . accountId } ,
82
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
83
+ ) ;
84
+ const expected = {
85
+ message : `Account ${ alice . accountId } registered with storage deposit of ${ yoctoAccountStorage } ` ,
86
+ } ;
87
+ t . deepEqual ( result , expected ) ;
88
+ const result2 = await alice . call (
89
+ ft ,
90
+ "storage_deposit" ,
91
+ { account_id : alice . accountId } ,
92
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
93
+ ) ;
94
+ t . is (
95
+ result2 . message ,
96
+ "Account is already registered, deposit refunded to predecessor"
97
+ ) ;
98
+ const aliceBalance = await alice . balance ( ) ;
99
+ t . is (
100
+ aliceBalance . total > NEAR . parse ( "9 N" ) ,
101
+ true ,
102
+ "alice should have received a refund"
103
+ ) ;
104
+ } ) ;
105
+
106
+ test ( "should return message when trying to pay for storage with less than the required amount and refund predecessor caller" , async ( t ) => {
107
+ const { ft, alice } = t . context . accounts ;
108
+ const { yoctoAccountStorage } = t . context . variables ;
109
+ const result = await alice . call (
110
+ ft ,
111
+ "storage_deposit" ,
112
+ { account_id : alice . accountId } ,
113
+ { attachedDeposit : NEAR . from ( "40" ) . toJSON ( ) }
114
+ ) ;
115
+ t . is (
116
+ result . message ,
117
+ `Not enough attached deposit to cover storage cost. Required: ${ yoctoAccountStorage } `
118
+ ) ;
119
+ } ) ;
120
+
121
+ test ( "should throw when trying to transfer for an unregistered account" , async ( t ) => {
122
+ const { ft, alice, root } = t . context . accounts ;
123
+ try {
124
+ await root . call (
125
+ ft ,
126
+ "ft_transfer" ,
127
+ { receiver_id : alice . accountId , amount : "1" } ,
128
+ { attachedDeposit : NEAR . from ( "1" ) . toJSON ( ) }
129
+ ) ;
130
+ } catch ( error ) {
131
+ t . true (
132
+ error . message . includes ( `Account ${ alice . accountId } is not registered` )
133
+ ) ;
134
+ }
135
+ } ) ;
136
+
33
137
test ( "Owner has all balance in the beginning" , async ( t ) => {
34
- const { ft } = t . context . accounts ;
35
- const result = await ft . view ( "ftBalanceOf " , { accountId : ft . accountId } ) ;
138
+ const { ft, root } = t . context . accounts ;
139
+ const result = await ft . view ( "ft_balance_of " , { account_id : root . accountId } ) ;
36
140
t . is ( result , "1000" ) ;
37
141
} ) ;
38
142
39
143
test ( "Can transfer if balance is sufficient" , async ( t ) => {
40
- const { ali, ft } = t . context . accounts ;
41
-
42
- await ft . call ( ft , "ftTransfer" , { receiverId : ali . accountId , amount : "100" } ) ;
43
- const aliBalance = await ft . view ( "ftBalanceOf" , { accountId : ali . accountId } ) ;
144
+ const { alice, ft, root } = t . context . accounts ;
145
+ await alice . call (
146
+ ft ,
147
+ "storage_deposit" ,
148
+ { account_id : alice . accountId } ,
149
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
150
+ ) ;
151
+ await root . call (
152
+ ft ,
153
+ "ft_transfer" ,
154
+ { receiver_id : alice . accountId , amount : "100" } ,
155
+ { attachedDeposit : NEAR . from ( "1" ) . toJSON ( ) }
156
+ ) ;
157
+ const aliBalance = await ft . view ( "ft_balance_of" , {
158
+ account_id : alice . accountId ,
159
+ } ) ;
44
160
t . is ( aliBalance , "100" ) ;
45
- const ownerBalance = await ft . view ( "ftBalanceOf " , {
46
- accountId : ft . accountId ,
161
+ const ownerBalance = await ft . view ( "ft_balance_of " , {
162
+ account_id : root . accountId ,
47
163
} ) ;
48
164
t . is ( ownerBalance , "900" ) ;
49
165
} ) ;
50
166
51
167
test ( "Cannot transfer if balance is not sufficient" , async ( t ) => {
52
- const { ali, bob, ft } = t . context . accounts ;
168
+ const { alice, root, ft } = t . context . accounts ;
169
+ await alice . call (
170
+ ft ,
171
+ "storage_deposit" ,
172
+ { account_id : alice . accountId } ,
173
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
174
+ ) ;
53
175
try {
54
- await ali . call ( ft , "ftTransfer" , {
55
- receiverId : bob . accountId ,
56
- amount : "100" ,
57
- } ) ;
176
+ await alice . call (
177
+ ft ,
178
+ "ft_transfer" ,
179
+ {
180
+ receiverId : root . accountId ,
181
+ amount : "100" ,
182
+ } ,
183
+ { attachedDeposit : NEAR . from ( "1" ) . toJSON ( ) }
184
+ ) ;
58
185
} catch ( e ) {
59
186
t . assert (
60
187
e
@@ -67,22 +194,30 @@ test("Cannot transfer if balance is not sufficient", async (t) => {
67
194
} ) ;
68
195
69
196
test ( "Cross contract transfer" , async ( t ) => {
70
- const { xcc, ft } = t . context . accounts ;
71
- await ft . call (
197
+ const { xcc, ft, root } = t . context . accounts ;
198
+ await xcc . call (
72
199
ft ,
73
- "ftTransferCall " ,
74
- { receiverId : xcc . accountId , amount : "900" , memo : null , msg : "test msg" } ,
75
- { gas : 200000000000000 }
200
+ "storage_deposit " ,
201
+ { account_id : xcc . accountId } ,
202
+ { attachedDeposit : NEAR . parse ( "1 N" ) . toJSON ( ) }
76
203
) ;
77
- const aliBalance = await ft . view ( "ftBalanceOf" , { accountId : xcc . accountId } ) ;
78
- t . is ( aliBalance , "900" ) ;
79
- const aliSubContractData = await xcc . view ( "getContractData" ) ;
204
+ await root . call (
205
+ ft ,
206
+ "ft_transfer_call" ,
207
+ { receiver_id : xcc . accountId , amount : "900" , memo : null , msg : "test msg" } ,
208
+ { gas : 200000000000000 , attachedDeposit : NEAR . from ( "1" ) . toJSON ( ) }
209
+ ) ;
210
+ const xccBalance = await ft . view ( "ft_balance_of" , {
211
+ account_id : xcc . accountId ,
212
+ } ) ;
213
+ t . is ( xccBalance , "900" ) ;
214
+ const aliSubContractData = await xcc . view ( "get_contract_data" ) ;
80
215
t . is (
81
216
aliSubContractData ,
82
- `[900 from ${ ft . accountId } to ${ xcc . accountId } ] test msg `
217
+ `[900 from ${ root . accountId } to ${ xcc . accountId } ] test msg `
83
218
) ;
84
- const ownerBalance = await ft . view ( "ftBalanceOf " , {
85
- accountId : ft . accountId ,
219
+ const ownerBalance = await ft . view ( "ft_balance_of " , {
220
+ account_id : root . accountId ,
86
221
} ) ;
87
222
t . is ( ownerBalance , "100" ) ;
88
223
} ) ;
0 commit comments