134 lines
4.0 KiB
JavaScript
134 lines
4.0 KiB
JavaScript
const anchor = require("@project-serum/anchor");
|
|
const assert = require("assert");
|
|
|
|
describe("multisig", () => {
|
|
// Configure the client to use the local cluster.
|
|
anchor.setProvider(anchor.Provider.env());
|
|
|
|
const program = anchor.workspace.Multisig;
|
|
|
|
it("Tests the multisig program", async () => {
|
|
const multisig = new anchor.web3.Account();
|
|
const [
|
|
multisigSigner,
|
|
nonce,
|
|
] = await anchor.web3.PublicKey.findProgramAddress(
|
|
[multisig.publicKey.toBuffer()],
|
|
program.programId
|
|
);
|
|
const multisigSize = 200; // Big enough.
|
|
|
|
const ownerA = new anchor.web3.Account();
|
|
const ownerB = new anchor.web3.Account();
|
|
const ownerC = new anchor.web3.Account();
|
|
const ownerD = new anchor.web3.Account();
|
|
const owners = [ownerA.publicKey, ownerB.publicKey, ownerC.publicKey];
|
|
|
|
const threshold = new anchor.BN(2);
|
|
await program.rpc.createMultisig(owners, threshold, nonce, {
|
|
accounts: {
|
|
multisig: multisig.publicKey,
|
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
},
|
|
instructions: [
|
|
await program.account.multisig.createInstruction(
|
|
multisig,
|
|
multisigSize
|
|
),
|
|
],
|
|
signers: [multisig],
|
|
});
|
|
|
|
let multisigAccount = await program.account.multisig(multisig.publicKey);
|
|
|
|
assert.equal(multisigAccount.nonce, nonce);
|
|
assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
|
|
assert.deepEqual(multisigAccount.owners, owners);
|
|
|
|
const pid = program.programId;
|
|
const accounts = [
|
|
{
|
|
pubkey: multisig.publicKey,
|
|
isWritable: true,
|
|
isSigner: false,
|
|
},
|
|
{
|
|
pubkey: multisigSigner,
|
|
isWritable: false,
|
|
isSigner: true,
|
|
},
|
|
];
|
|
const newOwners = [ownerA.publicKey, ownerB.publicKey, ownerD.publicKey];
|
|
const data = program.coder.instruction.encode('set_owners', {
|
|
owners: newOwners,
|
|
});
|
|
|
|
const transaction = new anchor.web3.Account();
|
|
const txSize = 1000; // Big enough, cuz I'm lazy.
|
|
await program.rpc.createTransaction(pid, accounts, data, {
|
|
accounts: {
|
|
multisig: multisig.publicKey,
|
|
transaction: transaction.publicKey,
|
|
proposer: ownerA.publicKey,
|
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
},
|
|
instructions: [
|
|
await program.account.transaction.createInstruction(
|
|
transaction,
|
|
txSize
|
|
),
|
|
],
|
|
signers: [transaction, ownerA],
|
|
});
|
|
|
|
const txAccount = await program.account.transaction(transaction.publicKey);
|
|
|
|
assert.ok(txAccount.programId.equals(pid));
|
|
assert.deepEqual(txAccount.accounts, accounts);
|
|
assert.deepEqual(txAccount.data, data);
|
|
assert.ok(txAccount.multisig.equals(multisig.publicKey));
|
|
assert.equal(txAccount.didExecute, false);
|
|
|
|
// Other owner approves transactoin.
|
|
await program.rpc.approve({
|
|
accounts: {
|
|
multisig: multisig.publicKey,
|
|
transaction: transaction.publicKey,
|
|
owner: ownerB.publicKey,
|
|
},
|
|
signers: [ownerB],
|
|
});
|
|
|
|
// Now that we've reached the threshold, send the transactoin.
|
|
await program.rpc.executeTransaction({
|
|
accounts: {
|
|
multisig: multisig.publicKey,
|
|
multisigSigner,
|
|
transaction: transaction.publicKey,
|
|
},
|
|
remainingAccounts: program.instruction.setOwners
|
|
.accounts({
|
|
multisig: multisig.publicKey,
|
|
multisigSigner,
|
|
})
|
|
// Change the signer status on the vendor signer since it's signed by the program, not the client.
|
|
.map((meta) =>
|
|
meta.pubkey.equals(multisigSigner)
|
|
? { ...meta, isSigner: false }
|
|
: meta
|
|
)
|
|
.concat({
|
|
pubkey: program.programId,
|
|
isWritable: false,
|
|
isSigner: false,
|
|
}),
|
|
});
|
|
|
|
multisigAccount = await program.account.multisig(multisig.publicKey);
|
|
|
|
assert.equal(multisigAccount.nonce, nonce);
|
|
assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
|
|
assert.deepEqual(multisigAccount.owners, newOwners);
|
|
});
|
|
});
|