208 lines
6.9 KiB
JavaScript
208 lines
6.9 KiB
JavaScript
|
const anchor = require("@project-serum/anchor");
|
||
|
const { TOKEN_PROGRAM_ID, Token } = require("@solana/spl-token");
|
||
|
const assert = require("assert");
|
||
|
|
||
|
describe("escrow", () => {
|
||
|
const provider = anchor.Provider.env();
|
||
|
anchor.setProvider(provider);
|
||
|
|
||
|
const program = anchor.workspace.Escrow;
|
||
|
|
||
|
let mintA = null;
|
||
|
let mintB = null;
|
||
|
let initializerTokenAccountA = null;
|
||
|
let initializerTokenAccountB = null;
|
||
|
let takerTokenAccountA = null;
|
||
|
let takerTokenAccountB = null;
|
||
|
let pda = null;
|
||
|
|
||
|
const takerAmount = 1000;
|
||
|
const initializerAmount = 500;
|
||
|
|
||
|
const escrowAccount = anchor.web3.Keypair.generate();
|
||
|
const payer = anchor.web3.Keypair.generate();
|
||
|
const mintAuthority = anchor.web3.Keypair.generate();
|
||
|
|
||
|
it("Initialise escrow state", async () => {
|
||
|
// Airdropping tokens to a payer.
|
||
|
await provider.connection.confirmTransaction(
|
||
|
await provider.connection.requestAirdrop(payer.publicKey, 10000000000),
|
||
|
"confirmed"
|
||
|
);
|
||
|
|
||
|
mintA = await Token.createMint(
|
||
|
provider.connection,
|
||
|
payer,
|
||
|
mintAuthority.publicKey,
|
||
|
null,
|
||
|
0,
|
||
|
TOKEN_PROGRAM_ID
|
||
|
);
|
||
|
|
||
|
mintB = await Token.createMint(
|
||
|
provider.connection,
|
||
|
payer,
|
||
|
mintAuthority.publicKey,
|
||
|
null,
|
||
|
0,
|
||
|
TOKEN_PROGRAM_ID
|
||
|
);
|
||
|
|
||
|
initializerTokenAccountA = await mintA.createAccount(provider.wallet.publicKey);
|
||
|
takerTokenAccountA = await mintA.createAccount(provider.wallet.publicKey);
|
||
|
|
||
|
initializerTokenAccountB = await mintB.createAccount(provider.wallet.publicKey);
|
||
|
takerTokenAccountB = await mintB.createAccount(provider.wallet.publicKey);
|
||
|
|
||
|
await mintA.mintTo(
|
||
|
initializerTokenAccountA,
|
||
|
mintAuthority.publicKey,
|
||
|
[mintAuthority],
|
||
|
initializerAmount
|
||
|
);
|
||
|
|
||
|
await mintB.mintTo(
|
||
|
takerTokenAccountB,
|
||
|
mintAuthority.publicKey,
|
||
|
[mintAuthority],
|
||
|
takerAmount
|
||
|
);
|
||
|
|
||
|
let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
|
||
|
let _takerTokenAccountB = await mintB.getAccountInfo(takerTokenAccountB);
|
||
|
|
||
|
assert.ok(_initializerTokenAccountA.amount.toNumber() == initializerAmount);
|
||
|
assert.ok(_takerTokenAccountB.amount.toNumber() == takerAmount);
|
||
|
});
|
||
|
|
||
|
it("Initialize escrow", async () => {
|
||
|
await program.rpc.initializeEscrow(
|
||
|
new anchor.BN(initializerAmount),
|
||
|
new anchor.BN(takerAmount),
|
||
|
{
|
||
|
accounts: {
|
||
|
initializer: provider.wallet.publicKey,
|
||
|
initializerDepositTokenAccount: initializerTokenAccountA,
|
||
|
initializerReceiveTokenAccount: initializerTokenAccountB,
|
||
|
escrowAccount: escrowAccount.publicKey,
|
||
|
tokenProgram: TOKEN_PROGRAM_ID,
|
||
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||
|
},
|
||
|
instructions: [
|
||
|
await program.account.escrowAccount.createInstruction(escrowAccount),
|
||
|
],
|
||
|
signers: [escrowAccount],
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// Get the PDA that is assigned authority to token account.
|
||
|
const [_pda, _nonce] = await anchor.web3.PublicKey.findProgramAddress(
|
||
|
[Buffer.from(anchor.utils.bytes.utf8.encode("escrow"))],
|
||
|
program.programId
|
||
|
);
|
||
|
|
||
|
pda = _pda;
|
||
|
|
||
|
let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
|
||
|
|
||
|
let _escrowAccount = await program.account.escrowAccount.fetch(
|
||
|
escrowAccount.publicKey
|
||
|
);
|
||
|
|
||
|
// Check that the new owner is the PDA.
|
||
|
assert.ok(_initializerTokenAccountA.owner.equals(pda));
|
||
|
|
||
|
// Check that the values in the escrow account match what we expect.
|
||
|
assert.ok(_escrowAccount.initializerKey.equals(provider.wallet.publicKey));
|
||
|
assert.ok(_escrowAccount.initializerAmount.toNumber() == initializerAmount);
|
||
|
assert.ok(_escrowAccount.takerAmount.toNumber() == takerAmount);
|
||
|
assert.ok(
|
||
|
_escrowAccount.initializerDepositTokenAccount.equals(initializerTokenAccountA)
|
||
|
);
|
||
|
assert.ok(
|
||
|
_escrowAccount.initializerReceiveTokenAccount.equals(initializerTokenAccountB)
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it("Exchange escrow", async () => {
|
||
|
await program.rpc.exchange({
|
||
|
accounts: {
|
||
|
taker: provider.wallet.publicKey,
|
||
|
takerDepositTokenAccount: takerTokenAccountB,
|
||
|
takerReceiveTokenAccount: takerTokenAccountA,
|
||
|
pdaDepositTokenAccount: initializerTokenAccountA,
|
||
|
initializerReceiveTokenAccount: initializerTokenAccountB,
|
||
|
initializerMainAccount: provider.wallet.publicKey,
|
||
|
escrowAccount: escrowAccount.publicKey,
|
||
|
pdaAccount: pda,
|
||
|
tokenProgram: TOKEN_PROGRAM_ID,
|
||
|
},
|
||
|
});
|
||
|
|
||
|
let _takerTokenAccountA = await mintA.getAccountInfo(takerTokenAccountA);
|
||
|
let _takerTokenAccountB = await mintB.getAccountInfo(takerTokenAccountB);
|
||
|
let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
|
||
|
let _initializerTokenAccountB = await mintB.getAccountInfo(initializerTokenAccountB);
|
||
|
|
||
|
// Check that the initializer gets back ownership of their token account.
|
||
|
assert.ok(_takerTokenAccountA.owner.equals(provider.wallet.publicKey));
|
||
|
|
||
|
assert.ok(_takerTokenAccountA.amount.toNumber() == initializerAmount);
|
||
|
assert.ok(_initializerTokenAccountA.amount.toNumber() == 0);
|
||
|
assert.ok(_initializerTokenAccountB.amount.toNumber() == takerAmount);
|
||
|
assert.ok(_takerTokenAccountB.amount.toNumber() == 0);
|
||
|
});
|
||
|
|
||
|
let newEscrow = anchor.web3.Keypair.generate();
|
||
|
|
||
|
it("Initialize escrow and cancel escrow", async () => {
|
||
|
// Put back tokens into initializer token A account.
|
||
|
await mintA.mintTo(
|
||
|
initializerTokenAccountA,
|
||
|
mintAuthority.publicKey,
|
||
|
[mintAuthority],
|
||
|
initializerAmount
|
||
|
);
|
||
|
|
||
|
await program.rpc.initializeEscrow(
|
||
|
new anchor.BN(initializerAmount),
|
||
|
new anchor.BN(takerAmount),
|
||
|
{
|
||
|
accounts: {
|
||
|
initializer: provider.wallet.publicKey,
|
||
|
initializerDepositTokenAccount: initializerTokenAccountA,
|
||
|
initializerReceiveTokenAccount: initializerTokenAccountB,
|
||
|
escrowAccount: newEscrow.publicKey,
|
||
|
tokenProgram: TOKEN_PROGRAM_ID,
|
||
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||
|
},
|
||
|
instructions: [await program.account.escrowAccount.createInstruction(newEscrow)],
|
||
|
signers: [newEscrow],
|
||
|
}
|
||
|
);
|
||
|
|
||
|
let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
|
||
|
|
||
|
// Check that the new owner is the PDA.
|
||
|
assert.ok(_initializerTokenAccountA.owner.equals(pda));
|
||
|
|
||
|
// Cancel the escrow.
|
||
|
await program.rpc.cancelEscrow({
|
||
|
accounts: {
|
||
|
initializer: provider.wallet.publicKey,
|
||
|
pdaDepositTokenAccount: initializerTokenAccountA,
|
||
|
pdaAccount: pda,
|
||
|
escrowAccount: newEscrow.publicKey,
|
||
|
tokenProgram: TOKEN_PROGRAM_ID,
|
||
|
},
|
||
|
});
|
||
|
|
||
|
// Check the final owner should be the provider public key.
|
||
|
_initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
|
||
|
assert.ok(_initializerTokenAccountA.owner.equals(provider.wallet.publicKey));
|
||
|
|
||
|
// Check all the funds are still there.
|
||
|
assert.ok(_initializerTokenAccountA.amount.toNumber() == initializerAmount);
|
||
|
});
|
||
|
});
|