multisig.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. const anchor = require("@project-serum/anchor");
  2. const assert = require("assert");
  3. describe("multisig", () => {
  4. // Configure the client to use the local cluster.
  5. anchor.setProvider(anchor.Provider.env());
  6. const program = anchor.workspace.Multisig;
  7. it("Tests the multisig program", async () => {
  8. const multisig = new anchor.web3.Account();
  9. const [
  10. multisigSigner,
  11. nonce,
  12. ] = await anchor.web3.PublicKey.findProgramAddress(
  13. [multisig.publicKey.toBuffer()],
  14. program.programId
  15. );
  16. const multisigSize = 200; // Big enough.
  17. const ownerA = new anchor.web3.Account();
  18. const ownerB = new anchor.web3.Account();
  19. const ownerC = new anchor.web3.Account();
  20. const owners = [ownerA.publicKey, ownerB.publicKey, ownerC.publicKey];
  21. const threshold = new anchor.BN(2);
  22. await program.rpc.createMultisig(owners, threshold, nonce, {
  23. accounts: {
  24. multisig: multisig.publicKey,
  25. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  26. },
  27. instructions: [
  28. await program.account.multisig.createInstruction(
  29. multisig,
  30. multisigSize
  31. ),
  32. ],
  33. signers: [multisig],
  34. });
  35. let multisigAccount = await program.account.multisig(multisig.publicKey);
  36. assert.equal(multisigAccount.nonce, nonce);
  37. assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
  38. assert.deepEqual(multisigAccount.owners, owners);
  39. const pid = program.programId;
  40. const accounts = [
  41. {
  42. pubkey: multisig.publicKey,
  43. isWritable: true,
  44. isSigner: false,
  45. },
  46. {
  47. pubkey: multisigSigner,
  48. isWritable: false,
  49. isSigner: true,
  50. },
  51. ];
  52. const newOwners = [ownerA.publicKey, ownerB.publicKey];
  53. const data = program.coder.instruction.encode('set_owners', {
  54. owners: newOwners,
  55. });
  56. const transaction = new anchor.web3.Account();
  57. const txSize = 1000; // Big enough, cuz I'm lazy.
  58. await program.rpc.createTransaction(pid, accounts, data, {
  59. accounts: {
  60. multisig: multisig.publicKey,
  61. transaction: transaction.publicKey,
  62. proposer: ownerA.publicKey,
  63. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  64. },
  65. instructions: [
  66. await program.account.transaction.createInstruction(
  67. transaction,
  68. txSize
  69. ),
  70. ],
  71. signers: [transaction, ownerA],
  72. });
  73. const txAccount = await program.account.transaction(transaction.publicKey);
  74. assert.ok(txAccount.programId.equals(pid));
  75. assert.deepEqual(txAccount.accounts, accounts);
  76. assert.deepEqual(txAccount.data, data);
  77. assert.ok(txAccount.multisig.equals(multisig.publicKey));
  78. assert.equal(txAccount.didExecute, false);
  79. // Other owner approves transactoin.
  80. await program.rpc.approve({
  81. accounts: {
  82. multisig: multisig.publicKey,
  83. transaction: transaction.publicKey,
  84. owner: ownerB.publicKey,
  85. },
  86. signers: [ownerB],
  87. });
  88. // Now that we've reached the threshold, send the transactoin.
  89. await program.rpc.executeTransaction({
  90. accounts: {
  91. multisig: multisig.publicKey,
  92. multisigSigner,
  93. transaction: transaction.publicKey,
  94. },
  95. remainingAccounts: program.instruction.setOwners
  96. .accounts({
  97. multisig: multisig.publicKey,
  98. multisigSigner,
  99. })
  100. // Change the signer status on the vendor signer since it's signed by the program, not the client.
  101. .map((meta) =>
  102. meta.pubkey.equals(multisigSigner)
  103. ? { ...meta, isSigner: false }
  104. : meta
  105. )
  106. .concat({
  107. pubkey: program.programId,
  108. isWritable: false,
  109. isSigner: false,
  110. }),
  111. });
  112. multisigAccount = await program.account.multisig(multisig.publicKey);
  113. assert.equal(multisigAccount.nonce, nonce);
  114. assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
  115. assert.deepEqual(multisigAccount.owners, newOwners);
  116. });
  117. });