multisig.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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("Is initialized!", 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({
  54. setOwners: {
  55. owners: newOwners,
  56. },
  57. });
  58. const transaction = new anchor.web3.Account();
  59. const txSize = 1000; // Big enough, cuz I'm lazy.
  60. await program.rpc.createTransaction(pid, accounts, data, {
  61. accounts: {
  62. multisig: multisig.publicKey,
  63. transaction: transaction.publicKey,
  64. proposer: ownerA.publicKey,
  65. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  66. },
  67. instructions: [
  68. await program.account.transaction.createInstruction(
  69. transaction,
  70. txSize
  71. ),
  72. ],
  73. signers: [transaction, ownerA],
  74. });
  75. const txAccount = await program.account.transaction(transaction.publicKey);
  76. assert.ok(txAccount.programId.equals(pid));
  77. assert.deepEqual(txAccount.accounts, accounts);
  78. assert.deepEqual(txAccount.data, data);
  79. assert.ok(txAccount.multisig.equals(multisig.publicKey));
  80. assert.equal(txAccount.didExecute, false);
  81. // Other owner approves transactoin.
  82. await program.rpc.approve({
  83. accounts: {
  84. multisig: multisig.publicKey,
  85. transaction: transaction.publicKey,
  86. owner: ownerB.publicKey,
  87. },
  88. signers: [ownerB],
  89. });
  90. // Now that we've reached the threshold, send the transactoin.
  91. await program.rpc.executeTransaction({
  92. accounts: {
  93. multisig: multisig.publicKey,
  94. multisigSigner,
  95. transaction: transaction.publicKey,
  96. },
  97. remainingAccounts: program.instruction.setOwners
  98. .accounts({
  99. multisig: multisig.publicKey,
  100. multisigSigner,
  101. })
  102. // Change the signer status on the vendor signer since it's signed by the program, not the client.
  103. .map((meta) =>
  104. meta.pubkey.equals(multisigSigner)
  105. ? { ...meta, isSigner: false }
  106. : meta
  107. )
  108. .concat({
  109. pubkey: program.programId,
  110. isWritable: false,
  111. isSigner: false,
  112. }),
  113. });
  114. multisigAccount = await program.account.multisig(multisig.publicKey);
  115. assert.equal(multisigAccount.nonce, nonce);
  116. assert.ok(multisigAccount.threshold.eq(new anchor.BN(2)));
  117. assert.deepEqual(multisigAccount.owners, newOwners);
  118. });
  119. });