Skip to content

Commit 817cf74

Browse files
committed
feat: support user-supplied Token programs
1 parent c122749 commit 817cf74

File tree

3 files changed

+33
-25
lines changed

3 files changed

+33
-25
lines changed

module.flow.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ declare module '@solana/web3.js' {
119119
declare type TokenAndPublicKey = [Token, PublicKey];
120120

121121
declare export class Token {
122-
static programId: PublicKey;
122+
programId: PublicKey;
123123
token: PublicKey;
124124

125125
static createNewToken(

src/token-program.js

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ const TokenAccountInfoLayout = BufferLayout.struct([
134134

135135
type TokenAndPublicKey = [Token, PublicKey]; // This type exists to workaround an esdoc parse error
136136

137+
138+
/**
139+
* The built-in token program
140+
*/
141+
export const SYSTEM_TOKEN_PROGRAM_ID = new PublicKey('0x500000000000000000000000000000000000000000000000000000000000000');
142+
137143
/**
138144
* An ERC20-like Token
139145
*/
@@ -149,14 +155,20 @@ export class Token {
149155
*/
150156
token: PublicKey;
151157

158+
/**
159+
* Program Identifier for the Token program
160+
*/
161+
programId: PublicKey;
162+
152163
/**
153164
* Create a Token object attached to the specific token
154165
*
155166
* @param connection The connection to use
156167
* @param token Public key of the token
168+
* @param programId Optional token programId, uses the system programId by default
157169
*/
158-
constructor(connection: Connection, token: PublicKey) {
159-
Object.assign(this, {connection, token});
170+
constructor(connection: Connection, token: PublicKey, programId: PublicKey = SYSTEM_TOKEN_PROGRAM_ID) {
171+
Object.assign(this, {connection, token, programId});
160172
}
161173

162174
/**
@@ -168,6 +180,7 @@ export class Token {
168180
* @param name Descriptive name of this token
169181
* @param symbol Symbol for this token
170182
* @param decimals Location of the decimal place
183+
* @param programId Optional token programId, uses the system programId by default
171184
* @return Token object for the newly minted token, Public key of the Token Account holding the total supply of new tokens
172185
*/
173186
static async createNewToken(
@@ -177,6 +190,7 @@ export class Token {
177190
name: string,
178191
symbol: string,
179192
decimals: number,
193+
programId: PublicKey = SYSTEM_TOKEN_PROGRAM_ID,
180194
): Promise<TokenAndPublicKey> {
181195
const tokenAccount = new Account();
182196
const token = new Token(connection, tokenAccount.publicKey);
@@ -213,14 +227,14 @@ export class Token {
213227
tokenAccount.publicKey,
214228
1,
215229
1 + userdata.length,
216-
Token.programId,
230+
programId,
217231
);
218232
await sendAndConfirmTransaction(connection, owner, transaction);
219233

220234
transaction = new Transaction({
221235
fee: 0,
222236
keys: [tokenAccount.publicKey, initialAccountPublicKey],
223-
programId: Token.programId,
237+
programId,
224238
userdata,
225239
});
226240
await sendAndConfirmTransaction(connection, tokenAccount, transaction);
@@ -253,7 +267,7 @@ export class Token {
253267
tokenAccount.publicKey,
254268
1,
255269
1 + TokenAccountInfoLayout.span,
256-
Token.programId,
270+
this.programId,
257271
);
258272
await sendAndConfirmTransaction(this.connection, owner, transaction);
259273

@@ -265,7 +279,7 @@ export class Token {
265279
transaction = new Transaction({
266280
fee: 0,
267281
keys,
268-
programId: Token.programId,
282+
programId: this.programId,
269283
userdata,
270284
});
271285
await sendAndConfirmTransaction(this.connection, tokenAccount, transaction);
@@ -292,7 +306,7 @@ export class Token {
292306
*/
293307
async tokenInfo(): Promise<TokenInfo> {
294308
const accountInfo = await this.connection.getAccountInfo(this.token);
295-
if (!accountInfo.programId.equals(Token.programId)) {
309+
if (!accountInfo.programId.equals(this.programId)) {
296310
throw new Error(`Invalid token programId: ${JSON.stringify(accountInfo.programId)}`);
297311
}
298312

@@ -314,7 +328,7 @@ export class Token {
314328
*/
315329
async accountInfo(account: PublicKey): Promise<TokenAccountInfo> {
316330
const accountInfo = await this.connection.getAccountInfo(account);
317-
if (!accountInfo.programId.equals(Token.programId)) {
331+
if (!accountInfo.programId.equals(this.programId)) {
318332
throw new Error(`Invalid token account programId`);
319333
}
320334

@@ -384,7 +398,7 @@ export class Token {
384398
const transaction = new Transaction({
385399
fee: 0,
386400
keys,
387-
programId: Token.programId,
401+
programId: this.programId,
388402
userdata,
389403
});
390404
await sendAndConfirmTransaction(this.connection, owner, transaction);
@@ -422,7 +436,7 @@ export class Token {
422436
const transaction = new Transaction({
423437
fee: 0,
424438
keys: [owner.publicKey, source, delegate],
425-
programId: Token.programId,
439+
programId: this.programId,
426440
userdata,
427441
});
428442
await sendAndConfirmTransaction(this.connection, owner, transaction);
@@ -442,13 +456,6 @@ export class Token {
442456
): Promise<void> {
443457
return this.approve(owner, source, delegate, 0);
444458
}
445-
446-
/**
447-
* Program Identifier for the Token program
448-
*/
449-
static get programId(): PublicKey {
450-
return new PublicKey('0x500000000000000000000000000000000000000000000000000000000000000');
451-
}
452459
}
453460

454461

test/token-program.test.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Token,
77
TokenAmount,
88
} from '../src';
9+
import {SYSTEM_TOKEN_PROGRAM_ID} from '../src/token-program';
910
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
1011
import {url} from './url';
1112
import {newAccountWithTokens} from './new-account-with-tokens';
@@ -111,7 +112,7 @@ test('create new token', async () => {
111112
{
112113
error: null,
113114
result: {
114-
program_id: [...Token.programId.toBuffer()],
115+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
115116
tokens: 1,
116117
userdata: [
117118
1,
@@ -149,7 +150,7 @@ test('create new token', async () => {
149150
{
150151
error: null,
151152
result: {
152-
program_id: [...Token.programId.toBuffer()],
153+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
153154
tokens: 1,
154155
userdata: [
155156
2,
@@ -206,7 +207,7 @@ test('create new token account', async () => {
206207
{
207208
error: null,
208209
result: {
209-
program_id: [...Token.programId.toBuffer()],
210+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
210211
tokens: 1,
211212
userdata: [
212213
2,
@@ -263,7 +264,7 @@ test('transfer', async () => {
263264
{
264265
error: null,
265266
result: {
266-
program_id: [...Token.programId.toBuffer()],
267+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
267268
tokens: 1,
268269
userdata: [
269270
2,
@@ -305,7 +306,7 @@ test('transfer', async () => {
305306
{
306307
error: null,
307308
result: {
308-
program_id: [...Token.programId.toBuffer()],
309+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
309310
tokens: 1,
310311
userdata: [
311312
2,
@@ -371,7 +372,7 @@ test('approve/revoke', async () => {
371372
{
372373
error: null,
373374
result: {
374-
program_id: [...Token.programId.toBuffer()],
375+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
375376
tokens: 1,
376377
userdata: [
377378
2,
@@ -426,7 +427,7 @@ test('approve/revoke', async () => {
426427
{
427428
error: null,
428429
result: {
429-
program_id: [...Token.programId.toBuffer()],
430+
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
430431
tokens: 1,
431432
userdata: [
432433
2,

0 commit comments

Comments
 (0)