Update token js bindings

This commit is contained in:
Justin Starry 2020-08-29 01:04:37 +08:00 committed by Michael Vines
parent aa1489df2e
commit 3691b14a01
6 changed files with 552 additions and 431 deletions

View File

@ -188,7 +188,7 @@ The owner of the source Account must be present as a signer in the `Transfer`
instruction. instruction.
An Account's owner may transfer ownership of an account to another using the An Account's owner may transfer ownership of an account to another using the
`SetOwner` instruction. `SetAuthority` instruction.
It's important to note that the `InitializeAccount` instruction does not require It's important to note that the `InitializeAccount` instruction does not require
the Solana account being initialized also be a signer. The `InitializeAccount` the Solana account being initialized also be a signer. The `InitializeAccount`

View File

@ -12,11 +12,11 @@ import {
approveRevoke, approveRevoke,
invalidApprove, invalidApprove,
failOnApproveOverspend, failOnApproveOverspend,
setOwner, setAuthority,
mintTo, mintTo,
multisig, multisig,
burn, burn,
failOnCloseAccount, closeAccount,
nativeToken, nativeToken,
} from './token-test'; } from './token-test';
@ -27,6 +27,8 @@ async function main() {
await createMint(); await createMint();
console.log('Run test: createAccount'); console.log('Run test: createAccount');
await createAccount(); await createAccount();
console.log('Run test: mintTo');
await mintTo();
console.log('Run test: transfer'); console.log('Run test: transfer');
await transfer(); await transfer();
console.log('Run test: approveRevoke'); console.log('Run test: approveRevoke');
@ -35,16 +37,14 @@ async function main() {
await invalidApprove(); await invalidApprove();
console.log('Run test: failOnApproveOverspend'); console.log('Run test: failOnApproveOverspend');
await failOnApproveOverspend(); await failOnApproveOverspend();
console.log('Run test: setOwner'); console.log('Run test: setAuthority');
await setOwner(); await setAuthority();
console.log('Run test: mintTo');
await mintTo();
console.log('Run test: multisig');
await multisig();
console.log('Run test: burn'); console.log('Run test: burn');
await burn(); await burn();
console.log('Run test: failOnCloseAccount'); console.log('Run test: closeAccount');
await failOnCloseAccount(); await closeAccount();
console.log('Run test: multisig');
await multisig();
console.log('Run test: nativeToken'); console.log('Run test: nativeToken');
await nativeToken(); await nativeToken();
console.log('Success\n'); console.log('Success\n');

View File

@ -4,7 +4,7 @@ import fs from 'mz/fs';
import {Account, Connection, BpfLoader, PublicKey} from '@solana/web3.js'; import {Account, Connection, BpfLoader, PublicKey} from '@solana/web3.js';
import semver from 'semver'; import semver from 'semver';
import {Token, u64} from '../client/token'; import {Token} from '../client/token';
import {url} from '../url'; import {url} from '../url';
import {newAccountWithLamports} from '../client/util/new-account-with-lamports'; import {newAccountWithLamports} from '../client/util/new-account-with-lamports';
import {sleep} from '../client/util/sleep'; import {sleep} from '../client/util/sleep';
@ -13,20 +13,14 @@ import {Store} from '../client/util/store';
// Loaded token program's program id // Loaded token program's program id
let programId: PublicKey; let programId: PublicKey;
// A token created by the next test and used by all subsequent tests // Accounts setup in createMint and used by all subsequent tests
let mintOwner: Account; let testMintAuthority: Account;
let testToken: Token; let testToken: Token;
// Initial token account
// Accounts setup in createAccount and used by all subsequent tests
let testAccountOwner: Account; let testAccountOwner: Account;
let testAccount: PublicKey; let testAccount: PublicKey;
// A mintable token used by multiple tests
let mintableOwner: Account;
let testMintableToken: Token;
// Initial token account
let testMintableAccountOwner: Account;
let testMintableAccount: PublicKey;
function assert(condition, message) { function assert(condition, message) {
if (!condition) { if (!condition) {
console.log(Error().stack + ':token-test.js'); console.log(Error().stack + ':token-test.js');
@ -116,72 +110,88 @@ export async function createMint(): Promise<void> {
connection, connection,
100000000000 /* wag */, 100000000000 /* wag */,
); );
mintOwner = new Account(); testMintAuthority = new Account();
testAccountOwner = new Account(); testToken = await Token.createMint(
[testToken, testAccount] = await Token.createMint(
connection, connection,
payer, payer,
mintOwner.publicKey, testMintAuthority.publicKey,
testAccountOwner.publicKey, null,
new u64(10000),
2, 2,
programId, programId,
false,
); );
const mintInfo = await testToken.getMintInfo(); const mintInfo = await testToken.getMintInfo();
assert(mintInfo.decimals == 2); if (mintInfo.mintAuthority !== null) {
assert(mintInfo.owner == null); assert(mintInfo.mintAuthority.equals(testMintAuthority.publicKey));
} else {
const accountInfo = await testToken.getAccountInfo(testAccount); assert(mintInfo.mintAuthority !== null);
assert(accountInfo.mint.equals(testToken.publicKey)); }
assert(accountInfo.owner.equals(testAccountOwner.publicKey)); assert(mintInfo.supply.toNumber() === 0);
assert(accountInfo.amount.toNumber() == 10000); assert(mintInfo.decimals === 2);
assert(accountInfo.delegate == null); assert(mintInfo.isInitialized === true);
assert(accountInfo.delegatedAmount.toNumber() == 0); assert(mintInfo.freezeAuthority === null);
} }
export async function createAccount(): Promise<void> { export async function createAccount(): Promise<void> {
const destOwner = new Account(); testAccountOwner = new Account();
const account = await testToken.createAccount(destOwner.publicKey); testAccount = await testToken.createAccount(testAccountOwner.publicKey);
const accountInfo = await testToken.getAccountInfo(account); const accountInfo = await testToken.getAccountInfo(testAccount);
assert(accountInfo.mint.equals(testToken.publicKey)); assert(accountInfo.mint.equals(testToken.publicKey));
assert(accountInfo.owner.equals(destOwner.publicKey)); assert(accountInfo.owner.equals(testAccountOwner.publicKey));
assert(accountInfo.amount.toNumber() == 0); assert(accountInfo.amount.toNumber() === 0);
assert(accountInfo.delegate == null); assert(accountInfo.delegate === null);
assert(accountInfo.delegatedAmount.toNumber() === 0);
assert(accountInfo.isInitialized === true);
assert(accountInfo.isFrozen === false);
assert(accountInfo.isNative === false);
assert(accountInfo.rentExemptReserve === null);
assert(accountInfo.closeAuthority === null);
}
export async function mintTo(): Promise<void> {
await testToken.mintTo(testAccount, testMintAuthority, [], 1000);
const mintInfo = await testToken.getMintInfo();
assert(mintInfo.supply.toNumber() === 1000);
const accountInfo = await testToken.getAccountInfo(testAccount);
assert(accountInfo.amount.toNumber() === 1000);
} }
export async function transfer(): Promise<void> { export async function transfer(): Promise<void> {
const destOwner = new Account(); const destOwner = new Account();
const dest = await testToken.createAccount(destOwner.publicKey); const dest = await testToken.createAccount(destOwner.publicKey);
await testToken.transfer(testAccount, dest, testAccountOwner, [], 123); await testToken.transfer(testAccount, dest, testAccountOwner, [], 100);
await sleep(500);
const mintInfo = await testToken.getMintInfo();
assert(mintInfo.supply.toNumber() === 1000);
let destAccountInfo = await testToken.getAccountInfo(dest); let destAccountInfo = await testToken.getAccountInfo(dest);
assert(destAccountInfo.amount.toNumber() == 123); assert(destAccountInfo.amount.toNumber() === 100);
let testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.amount.toNumber() === 900);
} }
export async function approveRevoke(): Promise<void> { export async function approveRevoke(): Promise<void> {
if (programId == null) { const delegate = new Account().publicKey;
console.log('test skipped, requires "load token program" to succeed');
return; await testToken.approve(testAccount, delegate, testAccountOwner, [], 42);
}
const delegate = new PublicKey();
await testToken.approve(testAccount, delegate, testAccountOwner, [], 456);
let testAccountInfo = await testToken.getAccountInfo(testAccount); let testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.delegatedAmount.toNumber() == 456); assert(testAccountInfo.delegatedAmount.toNumber() === 42);
if (testAccountInfo.delegate === null) { if (testAccountInfo.delegate === null) {
throw new Error('deleage should not be null'); throw new Error('delegate should not be null');
} else { } else {
assert(testAccountInfo.delegate.equals(delegate)); assert(testAccountInfo.delegate.equals(delegate));
} }
await testToken.revoke(testAccount, testAccountOwner, []); await testToken.revoke(testAccount, testAccountOwner, []);
testAccountInfo = await testToken.getAccountInfo(testAccount); testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.delegatedAmount.toNumber() == 0); assert(testAccountInfo.delegatedAmount.toNumber() === 0);
if (testAccountInfo.delegate != null) { if (testAccountInfo.delegate !== null) {
throw new Error('delegate should be null'); throw new Error('delegate should be null');
} }
} }
@ -233,75 +243,31 @@ export async function failOnApproveOverspend(): Promise<void> {
assert(didThrow(testToken.transfer, [account1, account2, delegate, [], 1])); assert(didThrow(testToken.transfer, [account1, account2, delegate, [], 1]));
} }
export async function setOwner(): Promise<void> { export async function setAuthority(): Promise<void> {
const owner = new Account();
const newOwner = new Account(); const newOwner = new Account();
const owned = await testToken.createAccount(owner.publicKey); await testToken.setAuthority(
testAccount,
await testToken.setOwner(owned, newOwner.publicKey, owner, []); newOwner.publicKey,
assert(didThrow(testToken.setOwner, [owned, newOwner.publicKey, owner, []])); 'AccountOwner',
await testToken.setOwner(owned, owner.publicKey, newOwner, []); testAccountOwner,
} [],
export async function mintTo(): Promise<void> {
const connection = await getConnection();
const payer = await newAccountWithLamports(
connection,
100000000000 /* wag */,
); );
mintableOwner = new Account(); assert(
testMintableAccountOwner = new Account(); didThrow(testToken.setAuthority, [
[testMintableToken, testMintableAccount] = await Token.createMint( testAccountOwner,
connection, newOwner.publicKey,
payer, 'AccountOwner',
mintableOwner.publicKey, testAccountOwner,
testMintableAccountOwner.publicKey, [],
new u64(10000), ]),
2,
programId,
true,
); );
await testToken.setAuthority(
{ testAccount,
const mintInfo = await testMintableToken.getMintInfo(); testAccountOwner.publicKey,
assert(mintInfo.decimals == 2); 'AccountOwner',
if (mintInfo.owner === null) { newOwner,
throw new Error('owner should not be null'); [],
} else {
assert(mintInfo.owner.equals(mintableOwner.publicKey));
}
const accountInfo = await testMintableToken.getAccountInfo(
testMintableAccount,
);
assert(accountInfo.mint.equals(testMintableToken.publicKey));
assert(accountInfo.owner.equals(testMintableAccountOwner.publicKey));
assert(accountInfo.amount.toNumber() == 10000);
assert(accountInfo.delegate == null);
assert(accountInfo.delegatedAmount.toNumber() == 0);
}
const dest = await testMintableToken.createAccount(
testMintableAccountOwner.publicKey,
); );
await testMintableToken.mintTo(dest, mintableOwner, [], 42);
{
const mintInfo = await testMintableToken.getMintInfo();
assert(mintInfo.decimals == 2);
if (mintInfo.owner === null) {
throw new Error('owner should not be null');
} else {
assert(mintInfo.owner.equals(mintableOwner.publicKey));
}
const accountInfo = await testMintableToken.getAccountInfo(dest);
assert(accountInfo.mint.equals(testMintableToken.publicKey));
assert(accountInfo.owner.equals(testMintableAccountOwner.publicKey));
assert(accountInfo.amount.toNumber() == 42);
assert(accountInfo.delegate == null);
assert(accountInfo.delegatedAmount.toNumber() == 0);
}
} }
export async function burn(): Promise<void> { export async function burn(): Promise<void> {
@ -309,12 +275,65 @@ export async function burn(): Promise<void> {
const amount = accountInfo.amount.toNumber(); const amount = accountInfo.amount.toNumber();
await testToken.burn(testAccount, testAccountOwner, [], 1); await testToken.burn(testAccount, testAccountOwner, [], 1);
await sleep(500);
accountInfo = await testToken.getAccountInfo(testAccount); accountInfo = await testToken.getAccountInfo(testAccount);
assert(accountInfo.amount.toNumber() == amount - 1); assert(accountInfo.amount.toNumber() == amount - 1);
} }
export async function closeAccount(): Promise<void> {
const closeAuthority = new Account();
await testToken.setAuthority(
testAccount,
closeAuthority.publicKey,
'CloseAccount',
testAccountOwner,
[],
);
let accountInfo = await testToken.getAccountInfo(testAccount);
if (accountInfo.closeAuthority === null) {
assert(accountInfo.closeAuthority !== null);
} else {
assert(accountInfo.closeAuthority.equals(closeAuthority.publicKey));
}
const dest = await testToken.createAccount(new Account().publicKey);
const remaining = accountInfo.amount.toNumber();
// Check that accounts with non-zero token balance cannot be closed
assert(
didThrow(testToken.closeAccount, [testAccount, dest, closeAuthority, []]),
);
const connection = await getConnection();
let tokenRentExemptAmount;
let info = await connection.getAccountInfo(testAccount);
if (info != null) {
tokenRentExemptAmount = info.lamports;
} else {
throw new Error('Account not found');
}
// Transfer away all tokens
await testToken.transfer(testAccount, dest, testAccountOwner, [], remaining);
// Close for real
await testToken.closeAccount(testAccount, dest, closeAuthority, []);
info = await connection.getAccountInfo(testAccount);
assert(info === null);
let destInfo = await connection.getAccountInfo(dest);
if (destInfo !== null) {
assert(destInfo.lamports === 2 * tokenRentExemptAmount);
} else {
throw new Error('Account not found');
}
let destAccountInfo = await testToken.getAccountInfo(dest);
assert(destAccountInfo.amount.toNumber() === remaining);
}
export async function multisig(): Promise<void> { export async function multisig(): Promise<void> {
const m = 2; const m = 2;
const n = 5; const n = 5;
@ -326,7 +345,6 @@ export async function multisig(): Promise<void> {
let signerPublicKeys = []; let signerPublicKeys = [];
signerAccounts.forEach(account => signerPublicKeys.push(account.publicKey)); signerAccounts.forEach(account => signerPublicKeys.push(account.publicKey));
const multisig = await testToken.createMultisig(m, signerPublicKeys); const multisig = await testToken.createMultisig(m, signerPublicKeys);
const multisigInfo = await testToken.getMultisigInfo(multisig); const multisigInfo = await testToken.getMultisigInfo(multisig);
assert(multisigInfo.m === m); assert(multisigInfo.m === m);
assert(multisigInfo.n === n); assert(multisigInfo.n === n);
@ -338,13 +356,8 @@ export async function multisig(): Promise<void> {
const multisigOwnedAccount = await testToken.createAccount(multisig); const multisigOwnedAccount = await testToken.createAccount(multisig);
const finalDest = await testToken.createAccount(multisig); const finalDest = await testToken.createAccount(multisig);
await testToken.transfer(
testAccount, await testToken.mintTo(multisigOwnedAccount, testMintAuthority, [], 1000);
multisigOwnedAccount,
testAccountOwner,
[],
2,
);
// Transfer via multisig // Transfer via multisig
await testToken.transfer( await testToken.transfer(
@ -376,49 +389,13 @@ export async function multisig(): Promise<void> {
} }
} }
// MintTo via multisig // SetAuthority of account via multisig
{
let accountInfo = await testMintableToken.getAccountInfo(
testMintableAccount,
);
const initialAmount = accountInfo.amount.toNumber();
await testMintableToken.setOwner(
testMintableToken.publicKey,
multisig,
mintableOwner,
[],
);
await testMintableToken.mintTo(
testMintableAccount,
multisig,
signerAccounts,
42,
);
accountInfo = await testMintableToken.getAccountInfo(testMintableAccount);
assert(accountInfo.amount.toNumber() == initialAmount + 42);
}
// SetOwner of mint via multisig
{
await testMintableToken.setOwner(
testMintableToken.publicKey,
mintableOwner.publicKey,
multisig,
signerAccounts,
);
const mintInfo = await testMintableToken.getMintInfo();
assert(mintInfo.owner != null);
if (mintInfo.owner != null) {
assert(mintInfo.owner.equals(mintableOwner.publicKey));
}
}
// SetOwner of account via multisig
{ {
const newOwner = new PublicKey(); const newOwner = new PublicKey();
await testToken.setOwner( await testToken.setAuthority(
multisigOwnedAccount, multisigOwnedAccount,
newOwner, newOwner,
'AccountOwner',
multisig, multisig,
signerAccounts, signerAccounts,
); );
@ -427,45 +404,11 @@ export async function multisig(): Promise<void> {
} }
} }
export async function failOnCloseAccount(): Promise<void> {
const connection = await getConnection();
const owner = new Account();
const close = await testToken.createAccount(owner.publicKey);
let close_balance;
let info = await connection.getAccountInfo(close);
if (info != null) {
close_balance = info.lamports;
} else {
throw new Error('Account not found');
}
// Initialize destination account to isolate source of failure
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(0);
const dest = await newAccountWithLamports(connection, balanceNeeded);
info = await connection.getAccountInfo(dest.publicKey);
if (info != null) {
assert(info.lamports == balanceNeeded);
} else {
throw new Error('Account not found');
}
assert(didThrow(testToken.closeAccount, [close, dest.publicKey, owner, []]));
info = await connection.getAccountInfo(close);
if (info != null) {
assert(info.lamports == close_balance);
} else {
throw new Error('Account not found');
}
}
export async function nativeToken(): Promise<void> { export async function nativeToken(): Promise<void> {
const connection = await getConnection(); const connection = await getConnection();
const mintPublicKey = new PublicKey( const mintPublicKey = new PublicKey(
'So11111111111111111111111111111111111111111', 'So11111111111111111111111111111111111111112',
); );
const payer = await newAccountWithLamports( const payer = await newAccountWithLamports(
connection, connection,

View File

@ -11,6 +11,7 @@ import {
SystemProgram, SystemProgram,
Transaction, Transaction,
TransactionInstruction, TransactionInstruction,
SYSVAR_RENT_PUBKEY,
} from '@solana/web3.js'; } from '@solana/web3.js';
import type {Connection, TransactionSignature} from '@solana/web3.js'; import type {Connection, TransactionSignature} from '@solana/web3.js';
@ -56,14 +57,34 @@ function isAccount(accountOrPublicKey: any): boolean {
return 'publicKey' in accountOrPublicKey; return 'publicKey' in accountOrPublicKey;
} }
type AuthorityType =
| 'MintTokens'
| 'FreezeAccount'
| 'AccountOwner'
| 'CloseAccount';
const AuthorityTypeCodes = {
MintTokens: 0,
FreezeAccount: 1,
AccountOwner: 2,
CloseAccount: 3,
};
/** /**
* Information about the mint * Information about the mint
*/ */
type MintInfo = {| type MintInfo = {|
/** /**
* Owner of the mint, given authority to mint new tokens * Optional authority used to mint new tokens. The mint authority may only be provided during
* mint creation. If no mint authority is present then the mint has a fixed supply and no
* further tokens may be minted.
*/ */
owner: null | PublicKey, mintAuthority: null | PublicKey,
/**
* Total supply of tokens
*/
supply: u64,
/** /**
* Number of base 10 digits to the right of the decimal place * Number of base 10 digits to the right of the decimal place
@ -73,14 +94,22 @@ type MintInfo = {|
/** /**
* Is this mint initialized * Is this mint initialized
*/ */
initialized: boolean, isInitialized: boolean,
/**
* Optional authority to freeze token accounts
*/
freezeAuthority: null | PublicKey,
|}; |};
const MintLayout = BufferLayout.struct([ const MintLayout = BufferLayout.struct([
BufferLayout.u32('option'), BufferLayout.u32('mintAuthorityOption'),
Layout.publicKey('owner'), Layout.publicKey('mintAuthority'),
Layout.uint64('supply'),
BufferLayout.u8('decimals'), BufferLayout.u8('decimals'),
BufferLayout.u8('is_initialized'), BufferLayout.u8('isInitialized'),
BufferLayout.u32('freezeAuthorityOption'),
Layout.publicKey('freezeAuthority'),
BufferLayout.u16('padding'), BufferLayout.u16('padding'),
]); ]);
@ -118,10 +147,27 @@ type AccountInfo = {|
*/ */
isInitialized: boolean, isInitialized: boolean,
/**
* Is this account frozen
*/
isFrozen: boolean,
/** /**
* Is this a native token account * Is this a native token account
*/ */
isNative: boolean, isNative: boolean,
/**
* If this account is a native token, it must be rent-exempt. This
* value logs the rent-exempt reserve which must remain in the balance
* until the account is closed.
*/
rentExemptReserve: null | u64,
/**
* Optional authority to close the account
*/
closeAuthority: null | PublicKey,
|}; |};
/** /**
@ -131,12 +177,15 @@ const AccountLayout = BufferLayout.struct([
Layout.publicKey('mint'), Layout.publicKey('mint'),
Layout.publicKey('owner'), Layout.publicKey('owner'),
Layout.uint64('amount'), Layout.uint64('amount'),
BufferLayout.u32('option'), BufferLayout.u32('delegateOption'),
Layout.publicKey('delegate'), Layout.publicKey('delegate'),
BufferLayout.u8('is_initialized'), BufferLayout.u8('state'),
BufferLayout.u8('is_native'), BufferLayout.u32('isNativeOption'),
BufferLayout.u16('padding'), Layout.uint64('isNative'),
Layout.uint64('delegatedAmount'), Layout.uint64('delegatedAmount'),
BufferLayout.u32('closeAuthorityOption'),
Layout.publicKey('closeAuthority'),
BufferLayout.blob(11, 'padding'),
]); ]);
/** /**
@ -195,8 +244,6 @@ const MultisigLayout = BufferLayout.struct([
Layout.publicKey('signer11'), Layout.publicKey('signer11'),
]); ]);
type TokenAndPublicKey = [Token, PublicKey]; // This type exists to workaround an esdoc parse error
/** /**
* An ERC20-like Token * An ERC20-like Token
*/ */
@ -289,14 +336,11 @@ export class Token {
static async createMint( static async createMint(
connection: Connection, connection: Connection,
payer: Account, payer: Account,
mintOwner: PublicKey, mintAuthority: PublicKey,
accountOwner: PublicKey, freezeAuthority: PublicKey | null,
supply: u64,
decimals: number, decimals: number,
programId: PublicKey, programId: PublicKey,
is_owned: boolean = false, ): Promise<Token> {
): Promise<TokenAndPublicKey> {
let transaction;
const mintAccount = new Account(); const mintAccount = new Account();
const token = new Token( const token = new Token(
connection, connection,
@ -304,13 +348,13 @@ export class Token {
programId, programId,
payer, payer,
); );
const initialAccountPublicKey = await token.createAccount(accountOwner);
// Allocate memory for the account // Allocate memory for the account
const balanceNeeded = await Token.getMinBalanceRentForExemptMint( const balanceNeeded = await Token.getMinBalanceRentForExemptMint(
connection, connection,
); );
transaction = SystemProgram.createAccount({
const transaction = SystemProgram.createAccount({
fromPubkey: payer.publicKey, fromPubkey: payer.publicKey,
newAccountPubkey: mintAccount.publicKey, newAccountPubkey: mintAccount.publicKey,
lamports: balanceNeeded, lamports: balanceNeeded,
@ -318,42 +362,15 @@ export class Token {
programId, programId,
}); });
// Create the mint transaction.add(
let keys = [ Token.createInitMintInstruction(
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true}, programId,
]; mintAccount.publicKey,
if (supply.cmp(0) != 0) { decimals,
keys.push({ mintAuthority,
pubkey: initialAccountPublicKey, freezeAuthority,
isSigner: false, ),
isWritable: true, );
});
}
if (is_owned) {
keys.push({pubkey: mintOwner, isSigner: false, isWritable: false});
}
const commandDataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
Layout.uint64('supply'),
BufferLayout.u8('decimals'),
]);
let data = Buffer.alloc(1024);
{
const encodeLength = commandDataLayout.encode(
{
instruction: 0, // InitializeMint instruction
supply: supply.toBuffer(),
decimals,
},
data,
);
data = data.slice(0, encodeLength);
}
transaction.add({
keys,
programId,
data,
});
// Send the two instructions // Send the two instructions
await sendAndConfirmTransaction( await sendAndConfirmTransaction(
@ -364,7 +381,7 @@ export class Token {
mintAccount, mintAccount,
); );
return [token, initialAccountPublicKey]; return token;
} }
/** /**
@ -376,40 +393,29 @@ export class Token {
* @return Public key of the new empty account * @return Public key of the new empty account
*/ */
async createAccount(owner: PublicKey): Promise<PublicKey> { async createAccount(owner: PublicKey): Promise<PublicKey> {
const mintAccount = new Account();
let transaction;
// Allocate memory for the account // Allocate memory for the account
const balanceNeeded = await Token.getMinBalanceRentForExemptAccount( const balanceNeeded = await Token.getMinBalanceRentForExemptAccount(
this.connection, this.connection,
); );
transaction = SystemProgram.createAccount({
const newAccount = new Account();
const transaction = SystemProgram.createAccount({
fromPubkey: this.payer.publicKey, fromPubkey: this.payer.publicKey,
newAccountPubkey: mintAccount.publicKey, newAccountPubkey: newAccount.publicKey,
lamports: balanceNeeded, lamports: balanceNeeded,
space: AccountLayout.span, space: AccountLayout.span,
programId: this.programId, programId: this.programId,
}); });
// create the new account const mintPublicKey = this.publicKey;
const keys = [ transaction.add(
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true}, Token.createInitAccountInstruction(
{pubkey: this.publicKey, isSigner: false, isWritable: false}, this.programId,
{pubkey: owner, isSigner: false, isWritable: false}, mintPublicKey,
]; newAccount.publicKey,
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]); owner,
const data = Buffer.alloc(dataLayout.span); ),
dataLayout.encode(
{
instruction: 1, // InitializeAccount instruction
},
data,
); );
transaction.add({
keys,
programId: this.programId,
data,
});
// Send the two instructions // Send the two instructions
await sendAndConfirmTransaction( await sendAndConfirmTransaction(
@ -417,10 +423,10 @@ export class Token {
this.connection, this.connection,
transaction, transaction,
this.payer, this.payer,
mintAccount, newAccount,
); );
return mintAccount.publicKey; return newAccount.publicKey;
} }
/** /**
@ -428,7 +434,6 @@ export class Token {
* *
* This account may then be used for multisignature verification * This account may then be used for multisignature verification
* *
* @param owner User account that will own the multsig account
* @return Public key of the new multisig account * @return Public key of the new multisig account
*/ */
async createMultisig( async createMultisig(
@ -453,6 +458,7 @@ export class Token {
// create the new account // create the new account
let keys = [ let keys = [
{pubkey: multisigAccount.publicKey, isSigner: false, isWritable: true}, {pubkey: multisigAccount.publicKey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
]; ];
signers.forEach(signer => signers.forEach(signer =>
keys.push({pubkey: signer, isSigner: false, isWritable: false}), keys.push({pubkey: signer, isSigner: false, isWritable: false}),
@ -464,7 +470,7 @@ export class Token {
const data = Buffer.alloc(dataLayout.span); const data = Buffer.alloc(dataLayout.span);
dataLayout.encode( dataLayout.encode(
{ {
instruction: 2, // InitializeM<ultisig instruction instruction: 2, // InitializeMultisig instruction
m, m,
}, },
data, data,
@ -504,10 +510,20 @@ export class Token {
const data = Buffer.from(info.data); const data = Buffer.from(info.data);
const mintInfo = MintLayout.decode(data); const mintInfo = MintLayout.decode(data);
if (mintInfo.option === 0) {
mintInfo.owner = null; if (mintInfo.mintAuthorityOption === 0) {
mintInfo.mintAuthority = null;
} else { } else {
mintInfo.owner = new PublicKey(mintInfo.owner); mintInfo.mintAuthority = new PublicKey(mintInfo.mintAuthority);
}
mintInfo.supply = u64.fromBuffer(mintInfo.supply);
mintInfo.isInitialized = mintInfo.isInitialized != 0;
if (mintInfo.freezeAuthorityOption === 0) {
mintInfo.freezeAuthority = null;
} else {
mintInfo.freezeAuthority = new PublicKey(mintInfo.freezeAuthority);
} }
return mintInfo; return mintInfo;
} }
@ -534,9 +550,8 @@ export class Token {
accountInfo.mint = new PublicKey(accountInfo.mint); accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner); accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount); accountInfo.amount = u64.fromBuffer(accountInfo.amount);
accountInfo.isInitialized = accountInfo.isInitialized != 0;
accountInfo.isNative = accountInfo.isNative != 0; if (accountInfo.delegateOption === 0) {
if (accountInfo.option === 0) {
accountInfo.delegate = null; accountInfo.delegate = null;
accountInfo.delegatedAmount = new u64(); accountInfo.delegatedAmount = new u64();
} else { } else {
@ -544,6 +559,23 @@ export class Token {
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount); accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
} }
accountInfo.isInitialized = accountInfo.state === 1;
accountInfo.isFrozen = accountInfo.state === 2;
if (accountInfo.isNativeOption === 1) {
accountInfo.rentExemptReserve = u64.fromBuffer(accountInfo.isNative);
accountInfo.isNative = true;
} else {
accountInfo.rentExemptReserve = null;
accountInfo.isNative = false;
}
if (accountInfo.closeAuthorityOption === 0) {
accountInfo.closeAuthority = null;
} else {
accountInfo.closeAuthority = new PublicKey(accountInfo.closeAuthority);
}
if (!accountInfo.mint.equals(this.publicKey)) { if (!accountInfo.mint.equals(this.publicKey)) {
throw new Error( throw new Error(
`Invalid account mint: ${JSON.stringify( `Invalid account mint: ${JSON.stringify(
@ -712,37 +744,40 @@ export class Token {
} }
/** /**
* Assign a new owner to the account * Assign a new authority to the account
* *
* @param account Public key of the account * @param account Public key of the account
* @param newOwner New owner of the account * @param newAuthority New authority of the account
* @param owner Owner of the account * @param authorityType Type of authority to set
* @param multiSigners Signing accounts if `owner` is a multiSig * @param currentAuthority Current authority of the account
* @param multiSigners Signing accounts if `currentAuthority` is a multiSig
*/ */
async setOwner( async setAuthority(
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: any, authorityType: AuthorityType,
currentAuthority: any,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void> { ): Promise<void> {
let ownerPublicKey; let currentAuthorityPublicKey: PublicKey;
let signers; let signers;
if (isAccount(owner)) { if (isAccount(currentAuthority)) {
ownerPublicKey = owner.publicKey; currentAuthorityPublicKey = currentAuthority.publicKey;
signers = [owner]; signers = [currentAuthority];
} else { } else {
ownerPublicKey = owner; currentAuthorityPublicKey = currentAuthority;
signers = multiSigners; signers = multiSigners;
} }
await sendAndConfirmTransaction( await sendAndConfirmTransaction(
'SetOwner', 'SetAuthority',
this.connection, this.connection,
new Transaction().add( new Transaction().add(
Token.createSetOwnerInstruction( Token.createSetAuthorityInstruction(
this.programId, this.programId,
owned, account,
newOwner, newAuthority,
ownerPublicKey, authorityType,
currentAuthorityPublicKey,
multiSigners, multiSigners,
), ),
), ),
@ -754,7 +789,6 @@ export class Token {
/** /**
* Mint new tokens * Mint new tokens
* *
* @param mint Public key of the mint
* @param dest Public key of the account to mint to * @param dest Public key of the account to mint to
* @param authority Owner of the mint * @param authority Owner of the mint
* @param multiSigners Signing accounts if `authority` is a multiSig * @param multiSigners Signing accounts if `authority` is a multiSig
@ -797,23 +831,23 @@ export class Token {
* Burn tokens * Burn tokens
* *
* @param account Account to burn tokens from * @param account Account to burn tokens from
* @param authority Public key account owner * @param owner Public key account owner
* @param multiSigners Signing accounts if `authority` is a multiSig * @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount ammount to burn * @param amount amount to burn
*/ */
async burn( async burn(
account: PublicKey, account: PublicKey,
authority: any, owner: any,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): Promise<void> { ): Promise<void> {
let ownerPublicKey; let ownerPublicKey;
let signers; let signers;
if (isAccount(authority)) { if (isAccount(owner)) {
ownerPublicKey = authority.publicKey; ownerPublicKey = owner.publicKey;
signers = [authority]; signers = [owner];
} else { } else {
ownerPublicKey = authority; ownerPublicKey = owner;
signers = multiSigners; signers = multiSigners;
} }
await sendAndConfirmTransaction( await sendAndConfirmTransaction(
@ -822,6 +856,7 @@ export class Token {
new Transaction().add( new Transaction().add(
Token.createBurnInstruction( Token.createBurnInstruction(
this.programId, this.programId,
this.publicKey,
account, account,
ownerPublicKey, ownerPublicKey,
multiSigners, multiSigners,
@ -834,25 +869,26 @@ export class Token {
} }
/** /**
* Burn account * Close account
* *
* @param account Account to burn * @param account Account to close
* @param authority account owner * @param dest Account to receive the remaining balance of the closed account
* @param authority Account which is allowed to close the account
* @param multiSigners Signing accounts if `owner` is a multiSig * @param multiSigners Signing accounts if `owner` is a multiSig
*/ */
async closeAccount( async closeAccount(
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: any, authority: any,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void> { ): Promise<void> {
let ownerPublicKey; let authorityPublicKey;
let signers; let signers;
if (isAccount(owner)) { if (isAccount(authority)) {
ownerPublicKey = owner.publicKey; authorityPublicKey = authority.publicKey;
signers = [owner]; signers = [authority];
} else { } else {
ownerPublicKey = owner; authorityPublicKey = authority;
signers = multiSigners; signers = multiSigners;
} }
await sendAndConfirmTransaction( await sendAndConfirmTransaction(
@ -863,7 +899,7 @@ export class Token {
this.programId, this.programId,
account, account,
dest, dest,
ownerPublicKey, authorityPublicKey,
multiSigners, multiSigners,
), ),
), ),
@ -872,12 +908,96 @@ export class Token {
); );
} }
/**
* Construct an init mint instruction
*
* @param programId SPL Token program account
* @param mint Token mint account
* @param token New token account
* @param owner Owner of the new token account
*/
static createInitMintInstruction(
programId: PublicKey,
mint: PublicKey,
decimals: number,
mintAuthority: PublicKey,
freezeAuthority: PublicKey | null,
): TransactionInstruction {
let keys = [
{pubkey: mint, isSigner: false, isWritable: true},
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
];
const commandDataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
BufferLayout.u8('decimals'),
Layout.publicKey('mintAuthority'),
BufferLayout.u8('option'),
Layout.publicKey('freezeAuthority'),
]);
let data = Buffer.alloc(1024);
{
const encodeLength = commandDataLayout.encode(
{
instruction: 0, // InitializeMint instruction
decimals,
mintAuthority: mintAuthority.toBuffer(),
option: freezeAuthority === null ? 0 : 1,
freezeAuthority: (freezeAuthority || new PublicKey()).toBuffer(),
},
data,
);
data = data.slice(0, encodeLength);
}
return new TransactionInstruction({
keys,
programId,
data,
});
}
/**
* Construct an init account instruction
*
* @param programId SPL Token program account
* @param mint Token mint account
* @param account New account
* @param owner Owner of the new account
*/
static createInitAccountInstruction(
programId: PublicKey,
mint: PublicKey,
account: PublicKey,
owner: PublicKey,
): TransactionInstruction {
const keys = [
{pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: false},
{pubkey: owner, isSigner: false, isWritable: false},
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
];
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 1, // InitializeAccount instruction
},
data,
);
return new TransactionInstruction({
keys,
programId,
data,
});
}
/** /**
* Construct a Transfer instruction * Construct a Transfer instruction
* *
* @param source Source account * @param source Source account
* @param destination Destination account * @param destination Destination account
* @param authority Owner of the source account * @param owner Owner of the source account
* @param multiSigners Signing accounts if `authority` is a multiSig * @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount Number of tokens to transfer * @param amount Number of tokens to transfer
*/ */
@ -885,7 +1005,7 @@ export class Token {
programId: PublicKey, programId: PublicKey,
source: PublicKey, source: PublicKey,
destination: PublicKey, destination: PublicKey,
authority: any, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction { ): TransactionInstruction {
@ -907,14 +1027,14 @@ export class Token {
{pubkey: source, isSigner: false, isWritable: true}, {pubkey: source, isSigner: false, isWritable: true},
{pubkey: destination, isSigner: false, isWritable: true}, {pubkey: destination, isSigner: false, isWritable: true},
]; ];
if (isAccount(authority)) { if (multiSigners.length === 0) {
keys.push({ keys.push({
pubkey: authority.publicKey, pubkey: owner,
isSigner: true, isSigner: true,
isWritable: false, isWritable: false,
}); });
} else { } else {
keys.push({pubkey: authority, isSigner: false, isWritable: false}); keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>
keys.push({ keys.push({
pubkey: signer.publicKey, pubkey: signer.publicKey,
@ -943,7 +1063,7 @@ export class Token {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
delegate: PublicKey, delegate: PublicKey,
owner: any, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction { ): TransactionInstruction {
@ -965,8 +1085,8 @@ export class Token {
{pubkey: account, isSigner: false, isWritable: true}, {pubkey: account, isSigner: false, isWritable: true},
{pubkey: delegate, isSigner: false, isWritable: false}, {pubkey: delegate, isSigner: false, isWritable: false},
]; ];
if (isAccount(owner)) { if (multiSigners.length === 0) {
keys.push({pubkey: owner.publicKey, isSigner: true, isWritable: false}); keys.push({pubkey: owner, isSigner: true, isWritable: false});
} else { } else {
keys.push({pubkey: owner, isSigner: false, isWritable: false}); keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>
@ -997,7 +1117,7 @@ export class Token {
static createRevokeInstruction( static createRevokeInstruction(
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
owner: any, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction { ): TransactionInstruction {
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]); const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
@ -1011,8 +1131,8 @@ export class Token {
); );
let keys = [{pubkey: account, isSigner: false, isWritable: true}]; let keys = [{pubkey: account, isSigner: false, isWritable: true}];
if (isAccount(owner)) { if (multiSigners.length === 0) {
keys.push({pubkey: owner.publicKey, isSigner: true, isWritable: false}); keys.push({pubkey: owner, isSigner: true, isWritable: false});
} else { } else {
keys.push({pubkey: owner, isSigner: false, isWritable: false}); keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>
@ -1032,38 +1152,48 @@ export class Token {
} }
/** /**
* Construct a SetOwner instruction * Construct a SetAuthority instruction
* *
* @param account Public key of the account * @param account Public key of the account
* @param newOwner New owner of the account * @param newAuthority New authority of the account
* @param owner Owner of the account * @param authorityType Type of authority to set
* @param multiSigners Signing accounts if `owner` is a multiSig * @param currentAuthority Current authority of the specified type
* @param multiSigners Signing accounts if `currentAuthority` is a multiSig
*/ */
static createSetOwnerInstruction( static createSetAuthorityInstruction(
programId: PublicKey, programId: PublicKey,
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: any, authorityType: AuthorityType,
currentAuthority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction { ): TransactionInstruction {
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]); const commandDataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
BufferLayout.u8('authorityType'),
BufferLayout.u8('option'),
Layout.publicKey('newAuthority'),
]);
const data = Buffer.alloc(dataLayout.span); let data = Buffer.alloc(1024);
dataLayout.encode( {
{ const encodeLength = commandDataLayout.encode(
instruction: 6, // SetOwner instruction {
}, instruction: 6, // SetAuthority instruction
data, authorityType: AuthorityTypeCodes[authorityType],
); option: newAuthority === null ? 0 : 1,
newAuthority: (newAuthority || new PublicKey()).toBuffer(),
},
data,
);
data = data.slice(0, encodeLength);
}
let keys = [ let keys = [{pubkey: account, isSigner: false, isWritable: true}];
{pubkey: owned, isSigner: false, isWritable: true}, if (multiSigners.length === 0) {
{pubkey: newOwner, isSigner: false, isWritable: false}, keys.push({pubkey: currentAuthority, isSigner: true, isWritable: false});
];
if (isAccount(owner)) {
keys.push({pubkey: owner.publicKey, isSigner: true, isWritable: false});
} else { } else {
keys.push({pubkey: owner, isSigner: false, isWritable: false}); keys.push({pubkey: currentAuthority, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>
keys.push({ keys.push({
pubkey: signer.publicKey, pubkey: signer.publicKey,
@ -1084,16 +1214,15 @@ export class Token {
* Construct a MintTo instruction * Construct a MintTo instruction
* *
* @param dest Public key of the account to mint to * @param dest Public key of the account to mint to
* @param authority Owner of the mint * @param authority The mint authority
* @param multiSigners Signing accounts if `authority` is a multiSig * @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount amount to mint * @param amount amount to mint
*/ */
static createMintToInstruction( static createMintToInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey, mint: PublicKey,
dest: PublicKey, dest: PublicKey,
authority: any, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction { ): TransactionInstruction {
@ -1115,9 +1244,9 @@ export class Token {
{pubkey: mint, isSigner: false, isWritable: true}, {pubkey: mint, isSigner: false, isWritable: true},
{pubkey: dest, isSigner: false, isWritable: true}, {pubkey: dest, isSigner: false, isWritable: true},
]; ];
if (isAccount(authority)) { if (multiSigners.length === 0) {
keys.push({ keys.push({
pubkey: authority.publicKey, pubkey: authority,
isSigner: true, isSigner: true,
isWritable: false, isWritable: false,
}); });
@ -1142,15 +1271,17 @@ export class Token {
/** /**
* Construct a Burn instruction * Construct a Burn instruction
* *
* @param mint Mint for the account
* @param account Account to burn tokens from * @param account Account to burn tokens from
* @param authority Public key account owner * @param owner Owner of the account
* @param multiSigners Signing accounts if `authority` is a multiSig * @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount ammount to burn * @param amount amount to burn
*/ */
static createBurnInstruction( static createBurnInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey,
account: PublicKey, account: PublicKey,
authority: any, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction { ): TransactionInstruction {
@ -1168,15 +1299,18 @@ export class Token {
data, data,
); );
let keys = [{pubkey: account, isSigner: false, isWritable: true}]; let keys = [
if (isAccount(authority)) { {pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: true},
];
if (multiSigners.length === 0) {
keys.push({ keys.push({
pubkey: authority.publicKey, pubkey: owner,
isSigner: true, isSigner: true,
isWritable: false, isWritable: false,
}); });
} else { } else {
keys.push({pubkey: authority, isSigner: false, isWritable: false}); keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>
keys.push({ keys.push({
pubkey: signer.publicKey, pubkey: signer.publicKey,
@ -1204,7 +1338,7 @@ export class Token {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: any, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction { ): TransactionInstruction {
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]); const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
@ -1220,8 +1354,8 @@ export class Token {
{pubkey: account, isSigner: false, isWritable: true}, {pubkey: account, isSigner: false, isWritable: true},
{pubkey: dest, isSigner: false, isWritable: true}, {pubkey: dest, isSigner: false, isWritable: true},
]; ];
if (isAccount(owner)) { if (multiSigners.length === 0) {
keys.push({pubkey: owner.publicKey, isSigner: true, isWritable: false}); keys.push({pubkey: owner, isSigner: true, isWritable: false});
} else { } else {
keys.push({pubkey: owner, isSigner: false, isWritable: false}); keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer => multiSigners.forEach(signer =>

72
token/js/module.d.ts vendored
View File

@ -8,10 +8,17 @@ declare module '@solana/spl-token' {
toBuffer(): Buffer; toBuffer(): Buffer;
static fromBuffer(buffer: Buffer): u64; static fromBuffer(buffer: Buffer): u64;
} }
export type AuthorityType =
| 'MintTokens'
| 'FreezeAccount'
| 'AccountOwner'
| 'CloseAccount';
export type MintInfo = { export type MintInfo = {
owner: null | PublicKey, mintAuthority: null | PublicKey,
supply: u64,
decimals: number, decimals: number,
initialized: boolean, isInitialized: boolean,
freezeAuthority: null | PublicKey,
}; };
export type AccountInfo = { export type AccountInfo = {
mint: PublicKey, mint: PublicKey,
@ -20,7 +27,10 @@ declare module '@solana/spl-token' {
delegate: null | PublicKey, delegate: null | PublicKey,
delegatedAmount: u64, delegatedAmount: u64,
isInitialized: boolean, isInitialized: boolean,
isFrozen: boolean,
isNative: boolean, isNative: boolean,
rentExemptReserve: null | u64,
closeAuthority: null | PublicKey,
}; };
export type MultisigInfo = { export type MultisigInfo = {
m: number, m: number,
@ -38,7 +48,6 @@ declare module '@solana/spl-token' {
signer10: PublicKey, signer10: PublicKey,
signer11: PublicKey, signer11: PublicKey,
}; };
export type TokenAndPublicKey = [Token, PublicKey];
export class Token { export class Token {
constructor( constructor(
connection: Connection, connection: Connection,
@ -49,13 +58,11 @@ declare module '@solana/spl-token' {
static createMint( static createMint(
connection: Connection, connection: Connection,
payer: Account, payer: Account,
mintOwner: PublicKey, mintAuthority: PublicKey,
accountOwner: PublicKey, freezeAuthority: PublicKey | null,
supply: u64,
decimals: number, decimals: number,
programId: PublicKey, programId: PublicKey,
is_owned: boolean, ): Promise<Token>;
): Promise<TokenAndPublicKey>;
static getAccount(connection: Connection): Promise<Account>; static getAccount(connection: Connection): Promise<Account>;
createAccount(owner: PublicKey): Promise<PublicKey>; createAccount(owner: PublicKey): Promise<PublicKey>;
createMultisig(m: number, signers: Array<PublicKey>): Promise<PublicKey>; createMultisig(m: number, signers: Array<PublicKey>): Promise<PublicKey>;
@ -65,7 +72,7 @@ declare module '@solana/spl-token' {
transfer( transfer(
source: PublicKey, source: PublicKey,
destination: PublicKey, destination: PublicKey,
authority: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): Promise<TransactionSignature>; ): Promise<TransactionSignature>;
@ -81,10 +88,11 @@ declare module '@solana/spl-token' {
owner: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
setOwner( setAuthority(
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: Account | PublicKey, authorityType: AuthorityType,
currentAuthority: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
mintTo( mintTo(
@ -95,21 +103,34 @@ declare module '@solana/spl-token' {
): Promise<void>; ): Promise<void>;
burn( burn(
account: PublicKey, account: PublicKey,
authority: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): Promise<void>; ): Promise<void>;
closeAccount( closeAccount(
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: Account | PublicKey, authority: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
static createInitMintInstruction(
programId: PublicKey,
mint: PublicKey,
decimals: number,
mintAuthority: PublicKey,
freezeAuthority: PublicKey | null,
): TransactionInstruction;
static createInitAccountInstruction(
programId: PublicKey,
mint: PublicKey,
account: PublicKey,
owner: PublicKey,
): TransactionInstruction;
static createTransferInstruction( static createTransferInstruction(
programId: PublicKey, programId: PublicKey,
source: PublicKey, source: PublicKey,
destination: PublicKey, destination: PublicKey,
authority: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction; ): TransactionInstruction;
@ -117,35 +138,36 @@ declare module '@solana/spl-token' {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
delegate: PublicKey, delegate: PublicKey,
owner: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction; ): TransactionInstruction;
static createRevokeInstruction( static createRevokeInstruction(
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
owner: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction; ): TransactionInstruction;
static createSetOwnerInstruction( static createSetAuthorityInstruction(
programId: PublicKey, programId: PublicKey,
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction; ): TransactionInstruction;
static createMintToInstruction( static createMintToInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey, mint: PublicKey,
dest: PublicKey, dest: PublicKey,
authority: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction; ): TransactionInstruction;
static createBurnInstruction( static createBurnInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey,
account: PublicKey, account: PublicKey,
authority: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction; ): TransactionInstruction;
@ -153,7 +175,7 @@ declare module '@solana/spl-token' {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction; ): TransactionInstruction;
} }

View File

@ -11,10 +11,17 @@ declare module '@solana/spl-token' {
toBuffer(): Buffer; toBuffer(): Buffer;
static fromBuffer(buffer: Buffer): u64; static fromBuffer(buffer: Buffer): u64;
} }
declare export type AuthorityType =
| 'MintTokens'
| 'FreezeAccount'
| 'AccountOwner'
| 'CloseAccount';
declare export type MintInfo = {| declare export type MintInfo = {|
owner: null | PublicKey, mintAuthority: null | PublicKey,
supply: u64,
decimals: number, decimals: number,
initialized: boolean, isInitialized: boolean,
freezeAuthority: null | PublicKey,
|}; |};
declare export type AccountInfo = {| declare export type AccountInfo = {|
mint: PublicKey, mint: PublicKey,
@ -23,7 +30,10 @@ declare module '@solana/spl-token' {
delegate: null | PublicKey, delegate: null | PublicKey,
delegatedAmount: u64, delegatedAmount: u64,
isInitialized: boolean, isInitialized: boolean,
isFrozen: boolean,
isNative: boolean, isNative: boolean,
rentExemptReserve: null | u64,
closeAuthority: null | PublicKey,
|}; |};
declare export type MultisigInfo = {| declare export type MultisigInfo = {|
m: number, m: number,
@ -41,7 +51,6 @@ declare module '@solana/spl-token' {
signer10: PublicKey, signer10: PublicKey,
signer11: PublicKey, signer11: PublicKey,
|}; |};
declare export type TokenAndPublicKey = [Token, PublicKey];
declare export class Token { declare export class Token {
constructor( constructor(
connection: Connection, connection: Connection,
@ -52,13 +61,11 @@ declare module '@solana/spl-token' {
static createMint( static createMint(
connection: Connection, connection: Connection,
payer: Account, payer: Account,
mintOwner: PublicKey, mintAuthority: PublicKey,
accountOwner: PublicKey, freezeAuthority: PublicKey | null,
supply: u64,
decimals: number, decimals: number,
programId: PublicKey, programId: PublicKey,
is_owned: boolean, ): Promise<Token>;
): Promise<TokenAndPublicKey>;
static getAccount(connection: Connection): Promise<Account>; static getAccount(connection: Connection): Promise<Account>;
createAccount(owner: PublicKey): Promise<PublicKey>; createAccount(owner: PublicKey): Promise<PublicKey>;
createMultisig(m: number, signers: Array<PublicKey>): Promise<PublicKey>; createMultisig(m: number, signers: Array<PublicKey>): Promise<PublicKey>;
@ -68,7 +75,7 @@ declare module '@solana/spl-token' {
transfer( transfer(
source: PublicKey, source: PublicKey,
destination: PublicKey, destination: PublicKey,
authority: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): Promise<TransactionSignature>; ): Promise<TransactionSignature>;
@ -84,10 +91,11 @@ declare module '@solana/spl-token' {
owner: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
setOwner( setAuthority(
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: Account | PublicKey, authorityType: AuthorityType,
currentAuthority: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
mintTo( mintTo(
@ -98,21 +106,34 @@ declare module '@solana/spl-token' {
): Promise<void>; ): Promise<void>;
burn( burn(
account: PublicKey, account: PublicKey,
authority: Account | PublicKey, owner: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): Promise<void>; ): Promise<void>;
closeAccount( closeAccount(
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: Account | PublicKey, authority: Account | PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): Promise<void>; ): Promise<void>;
static createInitMintInstruction(
programId: PublicKey,
mint: PublicKey,
decimals: number,
mintAuthority: PublicKey,
freezeAuthority: PublicKey | null,
): TransactionInstruction;
static createInitAccountInstruction(
programId: PublicKey,
mint: PublicKey,
account: PublicKey,
owner: PublicKey,
): TransactionInstruction;
static createTransferInstruction( static createTransferInstruction(
programId: PublicKey, programId: PublicKey,
source: PublicKey, source: PublicKey,
destination: PublicKey, destination: PublicKey,
authority: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction; ): TransactionInstruction;
@ -120,35 +141,36 @@ declare module '@solana/spl-token' {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
delegate: PublicKey, delegate: PublicKey,
owner: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number | u64, amount: number | u64,
): TransactionInstruction; ): TransactionInstruction;
static createRevokeInstruction( static createRevokeInstruction(
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
owner: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction; ): TransactionInstruction;
static createSetOwnerInstruction( static createSetAuthorityInstruction(
programId: PublicKey, programId: PublicKey,
owned: PublicKey, account: PublicKey,
newOwner: PublicKey, newAuthority: PublicKey | null,
owner: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstruction; ): TransactionInstruction;
static createMintToInstruction( static createMintToInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey, mint: PublicKey,
dest: PublicKey, dest: PublicKey,
authority: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction; ): TransactionInstruction;
static createBurnInstruction( static createBurnInstruction(
programId: PublicKey, programId: PublicKey,
mint: PublicKey,
account: PublicKey, account: PublicKey,
authority: Account | PublicKey, owner: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
amount: number, amount: number,
): TransactionInstruction; ): TransactionInstruction;
@ -156,8 +178,8 @@ declare module '@solana/spl-token' {
programId: PublicKey, programId: PublicKey,
account: PublicKey, account: PublicKey,
dest: PublicKey, dest: PublicKey,
owner: Account | PublicKey, authority: PublicKey,
multiSigners: Array<Account>, multiSigners: Array<Account>,
): TransactionInstructio; ): TransactionInstruction;
} }
} }