|
1 | 1 | import { |
2 | 2 | address, |
3 | 3 | appendTransactionMessageInstruction, |
| 4 | + appendTransactionMessageInstructions, |
| 5 | + generateKeyPairSigner, |
4 | 6 | getUtf8Encoder, |
5 | 7 | pipe, |
6 | 8 | } from '@solana/web3.js'; |
7 | 9 | import test from 'ava'; |
8 | | -import { fetchMaybeMetadata, getCloseInstruction } from '../src'; |
| 10 | +import { |
| 11 | + fetchMaybeMetadata, |
| 12 | + getCloseInstruction, |
| 13 | + getSetAuthorityInstruction, |
| 14 | +} from '../src'; |
9 | 15 | import { |
10 | 16 | createCanonicalBuffer, |
11 | 17 | createCanonicalMetadata, |
@@ -53,11 +59,95 @@ test('it can close canonical metadata accounts', async (t) => { |
53 | 59 | t.false(account.exists); |
54 | 60 | }); |
55 | 61 |
|
56 | | -test.todo('the set authority of a canonical metadata can close the account'); |
| 62 | +test('the set authority of a canonical metadata can close the account', async (t) => { |
| 63 | + // Given the following authority and deployed program. |
| 64 | + const client = createDefaultSolanaClient(); |
| 65 | + const [authority, explicitAuthority] = await Promise.all([ |
| 66 | + generateKeyPairSignerWithSol(client), |
| 67 | + generateKeyPairSigner(), |
| 68 | + ]); |
| 69 | + const [program, programData] = await createDeployedProgram(client, authority); |
| 70 | + |
| 71 | + // And the following initialized canonical metadata account. |
| 72 | + const [metadata] = await createCanonicalMetadata(client, { |
| 73 | + authority, |
| 74 | + program, |
| 75 | + programData, |
| 76 | + seed: 'dummy', |
| 77 | + data: getUtf8Encoder().encode('Hello, World!'), |
| 78 | + }); |
| 79 | + |
| 80 | + // And given an explicit authority is set on the metadata account. |
| 81 | + const setAuthorityIx = getSetAuthorityInstruction({ |
| 82 | + account: metadata, |
| 83 | + authority, |
| 84 | + newAuthority: explicitAuthority.address, |
| 85 | + program, |
| 86 | + programData, |
| 87 | + }); |
| 88 | + |
| 89 | + // When the explicit authority closes the metadata account. |
| 90 | + const closeIx = getCloseInstruction({ |
| 91 | + account: metadata, |
| 92 | + authority: explicitAuthority, |
| 93 | + destination: explicitAuthority.address, |
| 94 | + }); |
| 95 | + await pipe( |
| 96 | + await createDefaultTransaction(client, authority), |
| 97 | + (tx) => appendTransactionMessageInstructions([setAuthorityIx, closeIx], tx), |
| 98 | + (tx) => signAndSendTransaction(client, tx) |
| 99 | + ); |
| 100 | + |
| 101 | + // Then we expect the metadata account to no longer exist. |
| 102 | + const account = await fetchMaybeMetadata(client.rpc, metadata); |
| 103 | + t.false(account.exists); |
| 104 | +}); |
| 105 | + |
| 106 | +test('the current upgrade authority of program can close its canonical metadata account even when an authority is set on the account', async (t) => { |
| 107 | + // Given the following authority and deployed program. |
| 108 | + const client = createDefaultSolanaClient(); |
| 109 | + const [authority, explicitAuthority] = await Promise.all([ |
| 110 | + generateKeyPairSignerWithSol(client), |
| 111 | + generateKeyPairSigner(), |
| 112 | + ]); |
| 113 | + const [program, programData] = await createDeployedProgram(client, authority); |
| 114 | + |
| 115 | + // And the following initialized canonical metadata account. |
| 116 | + const [metadata] = await createCanonicalMetadata(client, { |
| 117 | + authority, |
| 118 | + program, |
| 119 | + programData, |
| 120 | + seed: 'dummy', |
| 121 | + data: getUtf8Encoder().encode('Hello, World!'), |
| 122 | + }); |
57 | 123 |
|
58 | | -test.todo( |
59 | | - 'the current upgrade authority of program can close its canonical metadata account even when an authority is set on the account' |
60 | | -); |
| 124 | + // And given an explicit authority is set on the metadata account. |
| 125 | + const setAuthorityIx = getSetAuthorityInstruction({ |
| 126 | + account: metadata, |
| 127 | + authority, |
| 128 | + newAuthority: explicitAuthority.address, |
| 129 | + program, |
| 130 | + programData, |
| 131 | + }); |
| 132 | + |
| 133 | + // When the program authority closes the metadata account. |
| 134 | + const closeIx = getCloseInstruction({ |
| 135 | + account: metadata, |
| 136 | + authority, |
| 137 | + destination: authority.address, |
| 138 | + program, |
| 139 | + programData, |
| 140 | + }); |
| 141 | + await pipe( |
| 142 | + await createDefaultTransaction(client, authority), |
| 143 | + (tx) => appendTransactionMessageInstructions([setAuthorityIx, closeIx], tx), |
| 144 | + (tx) => signAndSendTransaction(client, tx) |
| 145 | + ); |
| 146 | + |
| 147 | + // Then we expect the metadata account to no longer exist. |
| 148 | + const account = await fetchMaybeMetadata(client.rpc, metadata); |
| 149 | + t.false(account.exists); |
| 150 | +}); |
61 | 151 |
|
62 | 152 | test('it can close non-canonical metadata accounts', async (t) => { |
63 | 153 | // Given the following authority and deployed program. |
@@ -125,14 +215,6 @@ test('it can close canonical buffers', async (t) => { |
125 | 215 | t.false(account.exists); |
126 | 216 | }); |
127 | 217 |
|
128 | | -test.todo( |
129 | | - 'the authority that created a canonical buffer can close it even if the upgrade authority of the program changed' |
130 | | -); |
131 | | - |
132 | | -test.todo( |
133 | | - 'the current upgrade authority of program can close its canonical metadata account even if created by a different previous authority' |
134 | | -); |
135 | | - |
136 | 218 | test('it can close non-canonical buffers', async (t) => { |
137 | 219 | // Given the following authority and deployed program. |
138 | 220 | const client = createDefaultSolanaClient(); |
|
0 commit comments