Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit da94833

Browse files
author
Joe C
authored
token metadata js: update test suites (#6015)
1 parent 47a646c commit da94833

File tree

2 files changed

+135
-182
lines changed

2 files changed

+135
-182
lines changed
Lines changed: 110 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
21
import { expect } from 'chai';
32

43
import {
@@ -7,7 +6,29 @@ import {
76
createRemoveKeyInstruction,
87
createUpdateAuthorityInstruction,
98
createUpdateFieldInstruction,
9+
getFieldCodec,
10+
getFieldConfig,
1011
} from '../src';
12+
import type { StructToDecoderTuple } from '@solana/codecs-data-structures';
13+
import { getBooleanDecoder, getBytesDecoder, getDataEnumCodec, getStructDecoder } from '@solana/codecs-data-structures';
14+
import { getStringDecoder } from '@solana/codecs-strings';
15+
import { splDiscriminate } from '@solana/spl-type-length-value';
16+
import { getU64Decoder } from '@solana/codecs-numbers';
17+
import type { Option } from '@solana/options';
18+
import { getOptionDecoder, some } from '@solana/options';
19+
import { PublicKey, type TransactionInstruction } from '@solana/web3.js';
20+
21+
function checkPackUnpack<T extends object>(
22+
instruction: TransactionInstruction,
23+
discriminator: Uint8Array,
24+
layout: StructToDecoderTuple<T>,
25+
values: T
26+
) {
27+
expect(instruction.data.subarray(0, 8)).to.deep.equal(discriminator);
28+
const decoder = getStructDecoder(layout);
29+
const unpacked = decoder.decode(instruction.data.subarray(8));
30+
expect(unpacked).to.deep.equal(values);
31+
}
1132

1233
describe('Token Metadata Instructions', () => {
1334
const programId = new PublicKey('22222222222222222222222222222222222222222222');
@@ -17,150 +38,119 @@ describe('Token Metadata Instructions', () => {
1738
const mintAuthority = new PublicKey('66666666666666666666666666666666666666666666');
1839

1940
it('Can create Initialize Instruction', () => {
20-
const instruction = createInitializeInstruction({
21-
programId,
22-
metadata,
23-
updateAuthority,
24-
mint,
25-
mintAuthority,
26-
name: 'My test token',
27-
symbol: 'TEST',
28-
uri: 'http://test.test',
29-
});
30-
31-
expect(instruction).to.deep.equal(
32-
new TransactionInstruction({
41+
const name = 'My test token';
42+
const symbol = 'TEST';
43+
const uri = 'http://test.test';
44+
checkPackUnpack(
45+
createInitializeInstruction({
3346
programId,
34-
keys: [
35-
{ isSigner: false, isWritable: true, pubkey: metadata },
36-
{ isSigner: false, isWritable: false, pubkey: updateAuthority },
37-
{ isSigner: false, isWritable: false, pubkey: mint },
38-
{ isSigner: true, isWritable: false, pubkey: mintAuthority },
39-
],
40-
data: Buffer.from([
41-
// Output of rust implementation
42-
210, 225, 30, 162, 88, 184, 77, 141, 13, 0, 0, 0, 77, 121, 32, 116, 101, 115, 116, 32, 116, 111,
43-
107, 101, 110, 4, 0, 0, 0, 84, 69, 83, 84, 16, 0, 0, 0, 104, 116, 116, 112, 58, 47, 47, 116, 101,
44-
115, 116, 46, 116, 101, 115, 116,
45-
]),
46-
})
47+
metadata,
48+
updateAuthority,
49+
mint,
50+
mintAuthority,
51+
name,
52+
symbol,
53+
uri,
54+
}),
55+
splDiscriminate('spl_token_metadata_interface:initialize_account'),
56+
[
57+
['name', getStringDecoder()],
58+
['symbol', getStringDecoder()],
59+
['uri', getStringDecoder()],
60+
],
61+
{ name, symbol, uri }
4762
);
4863
});
4964

5065
it('Can create Update Field Instruction', () => {
51-
const instruction = createUpdateFieldInstruction({
52-
programId,
53-
metadata,
54-
updateAuthority,
55-
field: 'MyTestField',
56-
value: 'http://test.uri',
57-
});
58-
59-
expect(instruction).to.deep.equal(
60-
new TransactionInstruction({
66+
const field = 'MyTestField';
67+
const value = 'http://test.uri';
68+
checkPackUnpack(
69+
createUpdateFieldInstruction({
6170
programId,
62-
keys: [
63-
{ isSigner: false, isWritable: true, pubkey: metadata },
64-
{ isSigner: true, isWritable: false, pubkey: updateAuthority },
65-
],
66-
data: Buffer.from([
67-
// Output of rust implementation
68-
221, 233, 49, 45, 181, 202, 220, 200, 3, 11, 0, 0, 0, 77, 121, 84, 101, 115, 116, 70, 105, 101, 108,
69-
100, 15, 0, 0, 0, 104, 116, 116, 112, 58, 47, 47, 116, 101, 115, 116, 46, 117, 114, 105,
70-
]),
71-
})
71+
metadata,
72+
updateAuthority,
73+
field,
74+
value,
75+
}),
76+
splDiscriminate('spl_token_metadata_interface:updating_field'),
77+
[
78+
['key', getDataEnumCodec(getFieldCodec())],
79+
['value', getStringDecoder()],
80+
],
81+
{ key: getFieldConfig(field), value }
7282
);
7383
});
7484

7585
it('Can create Update Field Instruction with Field Enum', () => {
76-
const instruction = createUpdateFieldInstruction({
77-
programId,
78-
metadata,
79-
updateAuthority,
80-
field: 'Name',
81-
value: 'http://test.uri',
82-
});
83-
84-
expect(instruction).to.deep.equal(
85-
new TransactionInstruction({
86+
const field = 'Name';
87+
const value = 'http://test.uri';
88+
checkPackUnpack(
89+
createUpdateFieldInstruction({
8690
programId,
87-
keys: [
88-
{ isSigner: false, isWritable: true, pubkey: metadata },
89-
{ isSigner: true, isWritable: false, pubkey: updateAuthority },
90-
],
91-
data: Buffer.from([
92-
// Output of rust implementation
93-
221, 233, 49, 45, 181, 202, 220, 200, 0, 15, 0, 0, 0, 104, 116, 116, 112, 58, 47, 47, 116, 101, 115,
94-
116, 46, 117, 114, 105,
95-
]),
96-
})
91+
metadata,
92+
updateAuthority,
93+
field,
94+
value,
95+
}),
96+
splDiscriminate('spl_token_metadata_interface:updating_field'),
97+
[
98+
['key', getDataEnumCodec(getFieldCodec())],
99+
['value', getStringDecoder()],
100+
],
101+
{ key: getFieldConfig(field), value }
97102
);
98103
});
99104

100105
it('Can create Remove Key Instruction', () => {
101-
const instruction = createRemoveKeyInstruction({
102-
programId,
103-
metadata,
104-
updateAuthority: updateAuthority,
105-
key: 'MyTestField',
106-
idempotent: true,
107-
});
108-
109-
expect(instruction).to.deep.equal(
110-
new TransactionInstruction({
106+
checkPackUnpack(
107+
createRemoveKeyInstruction({
111108
programId,
112-
keys: [
113-
{ isSigner: false, isWritable: true, pubkey: metadata },
114-
{ isSigner: true, isWritable: false, pubkey: updateAuthority },
115-
],
116-
data: Buffer.from([
117-
// Output of rust implementation
118-
234, 18, 32, 56, 89, 141, 37, 181, 1, 11, 0, 0, 0, 77, 121, 84, 101, 115, 116, 70, 105, 101, 108,
119-
100,
120-
]),
121-
})
109+
metadata,
110+
updateAuthority: updateAuthority,
111+
key: 'MyTestField',
112+
idempotent: true,
113+
}),
114+
splDiscriminate('spl_token_metadata_interface:remove_key_ix'),
115+
[
116+
['idempotent', getBooleanDecoder()],
117+
['key', getStringDecoder()],
118+
],
119+
{ idempotent: true, key: 'MyTestField' }
122120
);
123121
});
124122

125123
it('Can create Update Authority Instruction', () => {
126-
const instruction = createUpdateAuthorityInstruction({
127-
programId,
128-
metadata,
129-
oldAuthority: updateAuthority,
130-
newAuthority: PublicKey.default,
131-
});
132-
133-
expect(instruction).to.deep.equal(
134-
new TransactionInstruction({
124+
const newAuthority = PublicKey.default;
125+
checkPackUnpack(
126+
createUpdateAuthorityInstruction({
135127
programId,
136-
keys: [
137-
{ isSigner: false, isWritable: true, pubkey: metadata },
138-
{ isSigner: true, isWritable: false, pubkey: updateAuthority },
139-
],
140-
data: Buffer.from([
141-
// Output of rust implementation
142-
215, 228, 166, 228, 84, 100, 86, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
144-
]),
145-
})
128+
metadata,
129+
oldAuthority: updateAuthority,
130+
newAuthority,
131+
}),
132+
splDiscriminate('spl_token_metadata_interface:update_the_authority'),
133+
[['newAuthority', getBytesDecoder({ size: 32 })]],
134+
{ newAuthority: Uint8Array.from(newAuthority.toBuffer()) }
146135
);
147136
});
148-
it('Can create Emit Instruction', () => {
149-
const instruction = createEmitInstruction({
150-
programId,
151-
metadata,
152-
end: BigInt(10),
153-
});
154137

155-
expect(instruction).to.deep.equal(
156-
new TransactionInstruction({
138+
it('Can create Emit Instruction', () => {
139+
const start: Option<bigint> = some(0n);
140+
const end: Option<bigint> = some(10n);
141+
checkPackUnpack(
142+
createEmitInstruction({
157143
programId,
158-
keys: [{ isSigner: false, isWritable: false, pubkey: metadata }],
159-
data: Buffer.from([
160-
// Output of rust implementation
161-
250, 166, 180, 250, 13, 12, 184, 70, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0,
162-
]),
163-
})
144+
metadata,
145+
start: 0n,
146+
end: 10n,
147+
}),
148+
splDiscriminate('spl_token_metadata_interface:emitter'),
149+
[
150+
['start', getOptionDecoder(getU64Decoder())],
151+
['end', getOptionDecoder(getU64Decoder())],
152+
],
153+
{ start, end }
164154
);
165155
});
166156
});

token-metadata/js/test/state.test.ts

Lines changed: 25 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,36 @@ import { expect } from 'chai';
44
import type { TokenMetadata } from '../src/state';
55
import { unpack, pack } from '../src';
66

7+
function checkPackUnpack(tokenMetadata: TokenMetadata) {
8+
const packed = pack(tokenMetadata);
9+
const unpacked = unpack(packed);
10+
expect(unpacked).to.deep.equal(tokenMetadata);
11+
}
12+
713
describe('Token Metadata State', () => {
8-
it('Can pack and unpack as rust implementation', () => {
9-
const meta = {
14+
it('Can pack and unpack base token metadata', () => {
15+
checkPackUnpack({
1016
mint: PublicKey.default,
1117
name: 'name',
1218
symbol: 'symbol',
1319
uri: 'uri',
1420
additionalMetadata: [],
15-
};
16-
17-
// From rust implementation
18-
const bytes = Buffer.from([
19-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 110, 97,
21-
109, 101, 6, 0, 0, 0, 115, 121, 109, 98, 111, 108, 3, 0, 0, 0, 117, 114, 105, 0, 0, 0, 0,
22-
]);
21+
});
22+
});
2323

24-
expect(pack(meta)).to.deep.equal(bytes);
25-
expect(unpack(bytes)).to.deep.equal(meta);
24+
it('Can pack and unpack with updateAuthority', () => {
25+
checkPackUnpack({
26+
updateAuthority: new PublicKey('44444444444444444444444444444444444444444444'),
27+
mint: new PublicKey('55555555555555555555555555555555555555555555'),
28+
name: 'name',
29+
symbol: 'symbol',
30+
uri: 'uri',
31+
additionalMetadata: [],
32+
});
2633
});
2734

28-
it('Can pack and unpack as rust implementation with additionalMetadata', () => {
29-
const meta: TokenMetadata = {
35+
it('Can pack and unpack with additional metadata', () => {
36+
checkPackUnpack({
3037
mint: PublicKey.default,
3138
name: 'new_name',
3239
symbol: 'new_symbol',
@@ -35,43 +42,11 @@ describe('Token Metadata State', () => {
3542
['key1', 'value1'],
3643
['key2', 'value2'],
3744
],
38-
};
39-
// From rust implementation
40-
const bytes = Buffer.from([
41-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 110, 101,
43-
119, 95, 110, 97, 109, 101, 10, 0, 0, 0, 110, 101, 119, 95, 115, 121, 109, 98, 111, 108, 7, 0, 0, 0, 110,
44-
101, 119, 95, 117, 114, 105, 2, 0, 0, 0, 4, 0, 0, 0, 107, 101, 121, 49, 6, 0, 0, 0, 118, 97, 108, 117, 101,
45-
49, 4, 0, 0, 0, 107, 101, 121, 50, 6, 0, 0, 0, 118, 97, 108, 117, 101, 50,
46-
]);
47-
48-
expect(pack(meta)).to.deep.equal(bytes);
49-
expect(unpack(bytes)).to.deep.equal(meta);
50-
});
51-
52-
it('Can pack and unpack with mint and updateAuthority', () => {
53-
const meta = {
54-
updateAuthority: new PublicKey('44444444444444444444444444444444444444444444'),
55-
mint: new PublicKey('55555555555555555555555555555555555555555555'),
56-
name: 'name',
57-
symbol: 'symbol',
58-
uri: 'uri',
59-
additionalMetadata: [],
60-
};
61-
62-
const bytes = Buffer.from([
63-
45, 91, 65, 60, 101, 64, 222, 21, 12, 147, 115, 20, 77, 81, 51, 202, 76, 184, 48, 186, 15, 117, 103, 22,
64-
172, 234, 14, 80, 215, 148, 53, 229, 60, 121, 172, 80, 135, 1, 40, 28, 16, 196, 153, 112, 103, 22, 239, 184,
65-
102, 74, 235, 162, 191, 71, 52, 30, 59, 226, 189, 193, 31, 112, 71, 220, 4, 0, 0, 0, 110, 97, 109, 101, 6,
66-
0, 0, 0, 115, 121, 109, 98, 111, 108, 3, 0, 0, 0, 117, 114, 105, 0, 0, 0, 0,
67-
]);
68-
69-
expect(pack(meta)).to.deep.equal(bytes);
70-
expect(unpack(bytes)).to.deep.equal(meta);
45+
});
7146
});
7247

73-
it('Can pack and unpack with mint, updateAuthority and additional metadata', () => {
74-
const meta: TokenMetadata = {
48+
it('Can pack and unpack with updateAuthority and additional metadata', () => {
49+
checkPackUnpack({
7550
updateAuthority: new PublicKey('44444444444444444444444444444444444444444444'),
7651
mint: new PublicKey('55555555555555555555555555555555555555555555'),
7752
name: 'name',
@@ -81,18 +56,6 @@ describe('Token Metadata State', () => {
8156
['key1', 'value1'],
8257
['key2', 'value2'],
8358
],
84-
};
85-
86-
const bytes = Buffer.from([
87-
45, 91, 65, 60, 101, 64, 222, 21, 12, 147, 115, 20, 77, 81, 51, 202, 76, 184, 48, 186, 15, 117, 103, 22,
88-
172, 234, 14, 80, 215, 148, 53, 229, 60, 121, 172, 80, 135, 1, 40, 28, 16, 196, 153, 112, 103, 22, 239, 184,
89-
102, 74, 235, 162, 191, 71, 52, 30, 59, 226, 189, 193, 31, 112, 71, 220, 4, 0, 0, 0, 110, 97, 109, 101, 6,
90-
0, 0, 0, 115, 121, 109, 98, 111, 108, 3, 0, 0, 0, 117, 114, 105, 2, 0, 0, 0, 4, 0, 0, 0, 107, 101, 121, 49,
91-
6, 0, 0, 0, 118, 97, 108, 117, 101, 49, 4, 0, 0, 0, 107, 101, 121, 50, 6, 0, 0, 0, 118, 97, 108, 117, 101,
92-
50,
93-
]);
94-
95-
expect(pack(meta)).to.deep.equal(bytes);
96-
expect(unpack(bytes)).to.deep.equal(meta);
59+
});
9760
});
9861
});

0 commit comments

Comments
 (0)