multisig.js 4.1 KB

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