sol-spltoken 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sol-spltoken might be problematic. Click here for more details.

@@ -0,0 +1,173 @@
1
+ import type { StructToEncoderTuple } from '@solana/codecs-data-structures';
2
+ import { getBooleanEncoder, getBytesEncoder, getDataEnumCodec, getStructEncoder } from '@solana/codecs-data-structures';
3
+ import { getU64Encoder } from '@solana/codecs-numbers';
4
+ import { getStringEncoder } from '@solana/codecs-strings';
5
+ import { getOptionEncoder } from '@solana/options';
6
+ import { splDiscriminate } from '@solana/spl-type-length-value';
7
+ import type { PublicKey } from '@solana/web3.js';
8
+ import { TransactionInstruction } from '@solana/web3.js';
9
+
10
+ import type { Field } from './field.js';
11
+ import { getFieldCodec, getFieldConfig } from './field.js';
12
+
13
+ function packInstruction<T extends object>(
14
+ layout: StructToEncoderTuple<T>,
15
+ discriminator: Uint8Array,
16
+ values: T
17
+ ): Buffer {
18
+ const encoder = getStructEncoder(layout);
19
+ const data = encoder.encode(values);
20
+ return Buffer.concat([discriminator, data]);
21
+ }
22
+
23
+ /**
24
+ * Initializes a TLV entry with the basic token-metadata fields.
25
+ *
26
+ * Assumes that the provided mint is an SPL token mint, that the metadata
27
+ * account is allocated and assigned to the program, and that the metadata
28
+ * account has enough lamports to cover the rent-exempt reserve.
29
+ */
30
+ export interface InitializeInstructionArgs {
31
+ programId: PublicKey;
32
+ metadata: PublicKey;
33
+ updateAuthority: PublicKey;
34
+ mint: PublicKey;
35
+ mintAuthority: PublicKey;
36
+ name: string;
37
+ symbol: string;
38
+ uri: string;
39
+ }
40
+
41
+ export function createInitializeInstruction(args: InitializeInstructionArgs): TransactionInstruction {
42
+ const { programId, metadata, updateAuthority, mint, mintAuthority, name, symbol, uri } = args;
43
+ return new TransactionInstruction({
44
+ programId,
45
+ keys: [
46
+ { isSigner: false, isWritable: true, pubkey: metadata },
47
+ { isSigner: false, isWritable: false, pubkey: updateAuthority },
48
+ { isSigner: false, isWritable: false, pubkey: mint },
49
+ { isSigner: true, isWritable: false, pubkey: mintAuthority },
50
+ ],
51
+ data: packInstruction(
52
+ [
53
+ ['name', getStringEncoder()],
54
+ ['symbol', getStringEncoder()],
55
+ ['uri', getStringEncoder()],
56
+ ],
57
+ splDiscriminate('spl_token_metadata_interface:initialize_account'),
58
+ { name, symbol, uri }
59
+ ),
60
+ });
61
+ }
62
+
63
+ /**
64
+ * If the field does not exist on the account, it will be created.
65
+ * If the field does exist, it will be overwritten.
66
+ */
67
+ export interface UpdateFieldInstruction {
68
+ programId: PublicKey;
69
+ metadata: PublicKey;
70
+ updateAuthority: PublicKey;
71
+ field: Field | string;
72
+ value: string;
73
+ }
74
+
75
+ export function createUpdateFieldInstruction(args: UpdateFieldInstruction): TransactionInstruction {
76
+ const { programId, metadata, updateAuthority, field, value } = args;
77
+ return new TransactionInstruction({
78
+ programId,
79
+ keys: [
80
+ { isSigner: false, isWritable: true, pubkey: metadata },
81
+ { isSigner: true, isWritable: false, pubkey: updateAuthority },
82
+ ],
83
+ data: packInstruction(
84
+ [
85
+ ['field', getDataEnumCodec(getFieldCodec())],
86
+ ['value', getStringEncoder()],
87
+ ],
88
+ splDiscriminate('spl_token_metadata_interface:updating_field'),
89
+ { field: getFieldConfig(field), value }
90
+ ),
91
+ });
92
+ }
93
+
94
+ export interface RemoveKeyInstructionArgs {
95
+ programId: PublicKey;
96
+ metadata: PublicKey;
97
+ updateAuthority: PublicKey;
98
+ key: string;
99
+ idempotent: boolean;
100
+ }
101
+
102
+ export function createRemoveKeyInstruction(args: RemoveKeyInstructionArgs) {
103
+ const { programId, metadata, updateAuthority, key, idempotent } = args;
104
+ return new TransactionInstruction({
105
+ programId,
106
+ keys: [
107
+ { isSigner: false, isWritable: true, pubkey: metadata },
108
+ { isSigner: true, isWritable: false, pubkey: updateAuthority },
109
+ ],
110
+ data: packInstruction(
111
+ [
112
+ ['idempotent', getBooleanEncoder()],
113
+ ['key', getStringEncoder()],
114
+ ],
115
+ splDiscriminate('spl_token_metadata_interface:remove_key_ix'),
116
+ { idempotent, key }
117
+ ),
118
+ });
119
+ }
120
+
121
+ export interface UpdateAuthorityInstructionArgs {
122
+ programId: PublicKey;
123
+ metadata: PublicKey;
124
+ oldAuthority: PublicKey;
125
+ newAuthority: PublicKey | null;
126
+ }
127
+
128
+ export function createUpdateAuthorityInstruction(args: UpdateAuthorityInstructionArgs): TransactionInstruction {
129
+ const { programId, metadata, oldAuthority, newAuthority } = args;
130
+
131
+ const newAuthorityBuffer = Buffer.alloc(32);
132
+ if (newAuthority) {
133
+ newAuthorityBuffer.set(newAuthority.toBuffer());
134
+ } else {
135
+ newAuthorityBuffer.fill(0);
136
+ }
137
+
138
+ return new TransactionInstruction({
139
+ programId,
140
+ keys: [
141
+ { isSigner: false, isWritable: true, pubkey: metadata },
142
+ { isSigner: true, isWritable: false, pubkey: oldAuthority },
143
+ ],
144
+ data: packInstruction(
145
+ [['newAuthority', getBytesEncoder({ size: 32 })]],
146
+ splDiscriminate('spl_token_metadata_interface:update_the_authority'),
147
+ { newAuthority: newAuthorityBuffer }
148
+ ),
149
+ });
150
+ }
151
+
152
+ export interface EmitInstructionArgs {
153
+ programId: PublicKey;
154
+ metadata: PublicKey;
155
+ start?: bigint;
156
+ end?: bigint;
157
+ }
158
+
159
+ export function createEmitInstruction(args: EmitInstructionArgs): TransactionInstruction {
160
+ const { programId, metadata, start, end } = args;
161
+ return new TransactionInstruction({
162
+ programId,
163
+ keys: [{ isSigner: false, isWritable: false, pubkey: metadata }],
164
+ data: packInstruction(
165
+ [
166
+ ['start', getOptionEncoder(getU64Encoder())],
167
+ ['end', getOptionEncoder(getU64Encoder())],
168
+ ],
169
+ splDiscriminate('spl_token_metadata_interface:emitter'),
170
+ { start: start ?? null, end: end ?? null }
171
+ ),
172
+ });
173
+ }
package/src/state.ts ADDED
@@ -0,0 +1,72 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { getArrayCodec, getBytesCodec, getStructCodec, getTupleCodec } from '@solana/codecs-data-structures';
3
+ import { getStringCodec } from '@solana/codecs-strings';
4
+
5
+ export const TOKEN_METADATA_DISCRIMINATOR = Buffer.from([112, 132, 90, 90, 11, 88, 157, 87]);
6
+
7
+ const tokenMetadataCodec = getStructCodec([
8
+ ['updateAuthority', getBytesCodec({ size: 32 })],
9
+ ['mint', getBytesCodec({ size: 32 })],
10
+ ['name', getStringCodec()],
11
+ ['symbol', getStringCodec()],
12
+ ['uri', getStringCodec()],
13
+ ['additionalMetadata', getArrayCodec(getTupleCodec([getStringCodec(), getStringCodec()]))],
14
+ ]);
15
+
16
+ export interface TokenMetadata {
17
+ // The authority that can sign to update the metadata
18
+ updateAuthority?: PublicKey;
19
+ // The associated mint, used to counter spoofing to be sure that metadata belongs to a particular mint
20
+ mint: PublicKey;
21
+ // The longer name of the token
22
+ name: string;
23
+ // The shortened symbol for the token
24
+ symbol: string;
25
+ // The URI pointing to richer metadata
26
+ uri: string;
27
+ // Any additional metadata about the token as key-value pairs
28
+ additionalMetadata: [string, string][];
29
+ }
30
+
31
+ // Checks if all elements in the array are 0
32
+ function isNonePubkey(buffer: Uint8Array): boolean {
33
+ for (let i = 0; i < buffer.length; i++) {
34
+ if (buffer[i] !== 0) {
35
+ return false;
36
+ }
37
+ }
38
+ return true;
39
+ }
40
+
41
+ // Pack TokenMetadata into byte slab
42
+ export const pack = (meta: TokenMetadata): Uint8Array => {
43
+ // If no updateAuthority given, set it to the None/Zero PublicKey for encoding
44
+ const updateAuthority = meta.updateAuthority ?? PublicKey.default;
45
+ return tokenMetadataCodec.encode({
46
+ ...meta,
47
+ updateAuthority: updateAuthority.toBuffer(),
48
+ mint: meta.mint.toBuffer(),
49
+ });
50
+ };
51
+
52
+ // unpack byte slab into TokenMetadata
53
+ export function unpack(buffer: Buffer | Uint8Array): TokenMetadata {
54
+ const data = tokenMetadataCodec.decode(buffer);
55
+
56
+ return isNonePubkey(data.updateAuthority)
57
+ ? {
58
+ mint: new PublicKey(data.mint),
59
+ name: data.name,
60
+ symbol: data.symbol,
61
+ uri: data.uri,
62
+ additionalMetadata: data.additionalMetadata,
63
+ }
64
+ : {
65
+ updateAuthority: new PublicKey(data.updateAuthority),
66
+ mint: new PublicKey(data.mint),
67
+ name: data.name,
68
+ symbol: data.symbol,
69
+ uri: data.uri,
70
+ additionalMetadata: data.additionalMetadata,
71
+ };
72
+ }