feat: support user-supplied Token programs

This commit is contained in:
Michael Vines 2018-10-18 09:28:21 -07:00
parent a9fc62d891
commit 00fd0fc435
3 changed files with 33 additions and 25 deletions

View File

@ -119,7 +119,7 @@ declare module '@solana/web3.js' {
declare type TokenAndPublicKey = [Token, PublicKey];
declare export class Token {
static programId: PublicKey;
programId: PublicKey;
token: PublicKey;
static createNewToken(

View File

@ -134,6 +134,12 @@ const TokenAccountInfoLayout = BufferLayout.struct([
type TokenAndPublicKey = [Token, PublicKey]; // This type exists to workaround an esdoc parse error
/**
* The built-in token program
*/
export const SYSTEM_TOKEN_PROGRAM_ID = new PublicKey('0x500000000000000000000000000000000000000000000000000000000000000');
/**
* An ERC20-like Token
*/
@ -149,14 +155,20 @@ export class Token {
*/
token: PublicKey;
/**
* Program Identifier for the Token program
*/
programId: PublicKey;
/**
* Create a Token object attached to the specific token
*
* @param connection The connection to use
* @param token Public key of the token
* @param programId Optional token programId, uses the system programId by default
*/
constructor(connection: Connection, token: PublicKey) {
Object.assign(this, {connection, token});
constructor(connection: Connection, token: PublicKey, programId: PublicKey = SYSTEM_TOKEN_PROGRAM_ID) {
Object.assign(this, {connection, token, programId});
}
/**
@ -168,6 +180,7 @@ export class Token {
* @param name Descriptive name of this token
* @param symbol Symbol for this token
* @param decimals Location of the decimal place
* @param programId Optional token programId, uses the system programId by default
* @return Token object for the newly minted token, Public key of the Token Account holding the total supply of new tokens
*/
static async createNewToken(
@ -177,6 +190,7 @@ export class Token {
name: string,
symbol: string,
decimals: number,
programId: PublicKey = SYSTEM_TOKEN_PROGRAM_ID,
): Promise<TokenAndPublicKey> {
const tokenAccount = new Account();
const token = new Token(connection, tokenAccount.publicKey);
@ -213,14 +227,14 @@ export class Token {
tokenAccount.publicKey,
1,
1 + userdata.length,
Token.programId,
programId,
);
await sendAndConfirmTransaction(connection, owner, transaction);
transaction = new Transaction({
fee: 0,
keys: [tokenAccount.publicKey, initialAccountPublicKey],
programId: Token.programId,
programId,
userdata,
});
await sendAndConfirmTransaction(connection, tokenAccount, transaction);
@ -253,7 +267,7 @@ export class Token {
tokenAccount.publicKey,
1,
1 + TokenAccountInfoLayout.span,
Token.programId,
this.programId,
);
await sendAndConfirmTransaction(this.connection, owner, transaction);
@ -265,7 +279,7 @@ export class Token {
transaction = new Transaction({
fee: 0,
keys,
programId: Token.programId,
programId: this.programId,
userdata,
});
await sendAndConfirmTransaction(this.connection, tokenAccount, transaction);
@ -292,7 +306,7 @@ export class Token {
*/
async tokenInfo(): Promise<TokenInfo> {
const accountInfo = await this.connection.getAccountInfo(this.token);
if (!accountInfo.programId.equals(Token.programId)) {
if (!accountInfo.programId.equals(this.programId)) {
throw new Error(`Invalid token programId: ${JSON.stringify(accountInfo.programId)}`);
}
@ -314,7 +328,7 @@ export class Token {
*/
async accountInfo(account: PublicKey): Promise<TokenAccountInfo> {
const accountInfo = await this.connection.getAccountInfo(account);
if (!accountInfo.programId.equals(Token.programId)) {
if (!accountInfo.programId.equals(this.programId)) {
throw new Error(`Invalid token account programId`);
}
@ -384,7 +398,7 @@ export class Token {
const transaction = new Transaction({
fee: 0,
keys,
programId: Token.programId,
programId: this.programId,
userdata,
});
await sendAndConfirmTransaction(this.connection, owner, transaction);
@ -422,7 +436,7 @@ export class Token {
const transaction = new Transaction({
fee: 0,
keys: [owner.publicKey, source, delegate],
programId: Token.programId,
programId: this.programId,
userdata,
});
await sendAndConfirmTransaction(this.connection, owner, transaction);
@ -442,13 +456,6 @@ export class Token {
): Promise<void> {
return this.approve(owner, source, delegate, 0);
}
/**
* Program Identifier for the Token program
*/
static get programId(): PublicKey {
return new PublicKey('0x500000000000000000000000000000000000000000000000000000000000000');
}
}

View File

@ -6,6 +6,7 @@ import {
Token,
TokenAmount,
} from '../src';
import {SYSTEM_TOKEN_PROGRAM_ID} from '../src/token-program';
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
import {url} from './url';
import {newAccountWithTokens} from './new-account-with-tokens';
@ -111,7 +112,7 @@ test('create new token', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
1,
@ -149,7 +150,7 @@ test('create new token', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,
@ -206,7 +207,7 @@ test('create new token account', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,
@ -263,7 +264,7 @@ test('transfer', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,
@ -305,7 +306,7 @@ test('transfer', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,
@ -371,7 +372,7 @@ test('approve/revoke', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,
@ -426,7 +427,7 @@ test('approve/revoke', async () => {
{
error: null,
result: {
program_id: [...Token.programId.toBuffer()],
program_id: [...SYSTEM_TOKEN_PROGRAM_ID.toBuffer()],
tokens: 1,
userdata: [
2,