multisig.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 = anchor.web3.Keypair.generate();
  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 = anchor.web3.Keypair.generate();
  18. const ownerB = anchor.web3.Keypair.generate();
  19. const ownerC = anchor.web3.Keypair.generate();
  20. const ownerD = anchor.web3.Keypair.generate();
  21. const owners = [ownerA.publicKey, ownerB.publicKey, ownerC.publicKey];
  22. const threshold = new anchor.BN(2);
  23. await program.rpc.createMultisig(owners, threshold, nonce, {
  24. accounts: {
  25. multisig: multisig.publicKey,
  26. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  27. },
  28. instructions: [
  29. await program.account.multisig.createInstruction(
  30. multisig,
  31. multisigSize
  32. ),
  33. ],
  34. signers: [multisig],
  35. });
  36. let multisigAccount = await program.account.multisig(multisig.publicKey);
  37. assert.equal(multisigAccount.nonce, nonce);
  38. assert.ok(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(transaction.publicKey);
  75. assert.ok(txAccount.programId.equals(pid));
  76. assert.deepEqual(txAccount.accounts, accounts);
  77. assert.deepEqual(txAccount.data, data);
  78. assert.ok(txAccount.multisig.equals(multisig.publicKey));
  79. assert.equal(txAccount.didExecute, false);
  80. // Other owner approves transaction.
  81. await program.rpc.approve({
  82. accounts: {
  83. multisig: multisig.publicKey,
  84. transaction: transaction.publicKey,
  85. owner: ownerB.publicKey,
  86. },
  87. signers: [ownerB],
  88. });
  89. // Now that we've reached the threshold, send the transaction.
  90. await program.rpc.executeTransaction({
  91. accounts: {
  92. multisig: multisig.publicKey,
  93. multisigSigner,
  94. transaction: transaction.publicKey,
  95. },
  96. remainingAccounts: program.instruction.setOwners
  97. .accounts({
  98. multisig: multisig.publicKey,
  99. multisigSigner,
  100. })
  101. // Change the signer status on the vendor signer since it's signed by the program, not the client.
  102. .map((meta) =>
  103. meta.pubkey.equals(multisigSigner)
  104. ? { ...meta, isSigner: false }
  105. : meta
  106. )
  107. .concat({
  108. pubkey: program.programId,
  109. isWritable: false,
  110. isSigner: false,
  111. }),
  112. });
  113. multisigAccount = await program.account.multisig(multisig.publicKey);
  114. assert.equal(multisigAccount.nonce, nonce);
  115. assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
  116. assert.deepEqual(multisigAccount.owners, newOwners);
  117. });
  118. });