forked from joe-p/arc59
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharc59.test.ts
181 lines (142 loc) · 5.56 KB
/
arc59.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import { describe, test, expect, beforeAll, beforeEach } from '@jest/globals';
import { algorandFixture } from '@algorandfoundation/algokit-utils/testing';
import * as algokit from '@algorandfoundation/algokit-utils';
import algosdk from 'algosdk';
import { Arc59Client } from '../contracts/clients/Arc59Client';
const fixture = algorandFixture();
algokit.Config.configure({ populateAppCallResources: true });
async function sendAsset(
appClient: Arc59Client,
assetId: bigint,
sender: string,
signer: algosdk.Account,
receiver: string,
algorand: algokit.AlgorandClient
) {
const arc59RouterAddress = (await appClient.appClient.getAppReference()).appAddress;
const [itxns, mbr, routerOptedIn, receiverOptedIn] = (
await appClient.arc59GetSendAssetInfo({ asset: assetId, receiver })
).return!;
if (receiverOptedIn) {
await algorand.send.assetTransfer({
sender,
receiver,
assetId,
amount: 1n,
});
return;
}
const composer = appClient.compose();
if (mbr) {
const mbrPayment = await algorand.transactions.payment({
sender,
receiver: arc59RouterAddress,
amount: algokit.microAlgos(Number(mbr)),
});
composer.addTransaction({ transaction: mbrPayment, signer });
}
const axfer = await algorand.transactions.assetTransfer({
sender,
receiver: arc59RouterAddress,
assetId,
amount: 1n,
});
// If the router is not opted in, call arc59OptRouterIn to do so
if (!routerOptedIn) composer.arc59OptRouterIn({ asa: assetId });
// Disable resource population to ensure that our manually defined resources are correct
algokit.Config.configure({ populateAppCallResources: false });
/** The box of the receiver's pubkey will always be needed */
const boxes = [algosdk.decodeAddress(receiver).publicKey];
/** The address of the receiver's inbox */
const inboxAddress = (await appClient.compose().arc59GetInbox({ receiver }, { boxes }).simulate()).returns[0];
await composer
.arc59SendAsset(
{ axfer, receiver },
{
sendParams: { fee: algokit.microAlgos(1000 + 1000 * Number(itxns)) },
boxes, // The receiver's pubkey
// Always good to include both accounts here, even if we think only the receiver is needed. This is to help protect against race conditions within a block.
accounts: [receiver, inboxAddress],
// Even though the asset is available in the group, we need to explicitly define it here because we will be checking the asset balance of the receiver
assets: [Number(assetId)],
}
)
.execute();
algokit.Config.configure({ populateAppCallResources: true });
}
describe('Arc59', () => {
let appClient: Arc59Client;
let assetOne: bigint;
let assetTwo: bigint;
let alice: algosdk.Account;
let bob: algosdk.Account;
beforeEach(fixture.beforeEach);
beforeAll(async () => {
await fixture.beforeEach();
const { testAccount } = fixture.context;
const { algorand } = fixture;
appClient = new Arc59Client(
{
sender: testAccount,
resolveBy: 'id',
id: 0,
},
algorand.client.algod
);
const oneResult = await algorand.send.assetCreate({
sender: testAccount.addr,
unitName: 'one',
total: 100n,
});
assetOne = BigInt(oneResult.confirmation.assetIndex!);
const twoResult = await algorand.send.assetCreate({
sender: testAccount.addr,
unitName: 'two',
total: 100n,
});
assetTwo = BigInt(twoResult.confirmation.assetIndex!);
alice = testAccount;
await appClient.create.createApplication({});
await appClient.appClient.fundAppAccount({ amount: algokit.microAlgos(100_000) });
});
test('routerOptIn', async () => {
await appClient.appClient.fundAppAccount({ amount: algokit.microAlgos(100_000) });
await appClient.arc59OptRouterIn({ asa: assetOne }, { sendParams: { fee: algokit.microAlgos(2_000) } });
});
test('Brand new account getSendAssetInfo', async () => {
const res = await appClient.arc59GetSendAssetInfo({ asset: assetOne, receiver: algosdk.generateAccount().addr });
const itxns = res.return![0];
const mbr = res.return![1];
expect(itxns).toBe(5n);
expect(mbr).toBe(228_100n);
});
test('Brand new account sendAsset', async () => {
const { algorand } = fixture;
const { testAccount } = fixture.context;
bob = testAccount;
await sendAsset(appClient, assetOne, alice.addr, alice, bob.addr, algorand);
});
test('Existing inbox sendAsset (existing asset)', async () => {
const { algorand } = fixture;
await sendAsset(appClient, assetOne, alice.addr, alice, bob.addr, algorand);
});
test('Existing inbox sendAsset (new asset)', async () => {
const { algorand } = fixture;
await sendAsset(appClient, assetTwo, alice.addr, alice, bob.addr, algorand);
});
test('claim', async () => {
const { algorand } = fixture;
await algorand.send.assetOptIn({ assetId: assetOne, sender: bob.addr });
await appClient.arc59Claim({ asa: assetOne }, { sender: bob, sendParams: { fee: algokit.algos(0.003) } });
const bobAssetInfo = await algorand.account.getAssetInformation(bob.addr, assetOne);
expect(bobAssetInfo.balance).toBe(2n);
});
test('reject', async () => {
const { algorand } = fixture;
const newAsset = BigInt(
(await algorand.send.assetCreate({ sender: alice.addr, total: 1n })).confirmation.assetIndex!
);
await sendAsset(appClient, newAsset, alice.addr, alice, bob.addr, algorand);
await appClient.arc59Reject({ asa: newAsset }, { sender: bob, sendParams: { fee: algokit.algos(0.003) } });
});
});