Flesh out @solana/spl-token with token2 instructions (#410)

* Fix token-js docs

* Add Freeze/Thaw instructions

* Add v2 instructions

* Add new instructions to js test

* Bump @solana/spl-token to v0.0.8

* Fix didThrow and remove invalidApprove
This commit is contained in:
Tyera Eulberg 2020-09-10 11:17:45 -06:00 committed by GitHub
parent 708bb430ab
commit 7141298b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 785 additions and 54 deletions

View File

@ -9,13 +9,16 @@ import {
createMint,
createAccount,
transfer,
transfer2,
approveRevoke,
invalidApprove,
failOnApproveOverspend,
setAuthority,
mintTo,
mintTo2,
multisig,
burn,
burn2,
freezeThawAccount,
closeAccount,
nativeToken,
} from './token-test';
@ -29,18 +32,24 @@ async function main() {
await createAccount();
console.log('Run test: mintTo');
await mintTo();
console.log('Run test: mintTo2');
await mintTo2();
console.log('Run test: transfer');
await transfer();
console.log('Run test: transfer2');
await transfer2();
console.log('Run test: approveRevoke');
await approveRevoke();
console.log('Run test: invalidApprove');
await invalidApprove();
console.log('Run test: failOnApproveOverspend');
await failOnApproveOverspend();
console.log('Run test: setAuthority');
await setAuthority();
console.log('Run test: burn');
await burn();
console.log('Run test: burn2');
await burn2();
console.log('Run test: freezeThawAccount');
await freezeThawAccount();
console.log('Run test: closeAccount');
await closeAccount();
console.log('Run test: multisig');

View File

@ -28,9 +28,9 @@ function assert(condition, message) {
}
}
async function didThrow(func, args): Promise<boolean> {
async function didThrow(obj, func, args): Promise<boolean> {
try {
await func.apply(args);
await func.apply(testToken, args);
} catch (e) {
return true;
}
@ -125,7 +125,7 @@ export async function createMint(): Promise<void> {
connection,
payer,
testMintAuthority.publicKey,
null,
testMintAuthority.publicKey,
2,
programId,
);
@ -139,7 +139,11 @@ export async function createMint(): Promise<void> {
assert(mintInfo.supply.toNumber() === 0);
assert(mintInfo.decimals === 2);
assert(mintInfo.isInitialized === true);
assert(mintInfo.freezeAuthority === null);
if (mintInfo.freezeAuthority !== null) {
assert(mintInfo.freezeAuthority.equals(testMintAuthority.publicKey));
} else {
assert(mintInfo.freezeAuthority !== null);
}
}
export async function createAccount(): Promise<void> {
@ -168,6 +172,26 @@ export async function mintTo(): Promise<void> {
assert(accountInfo.amount.toNumber() === 1000);
}
export async function mintTo2(): Promise<void> {
assert(
await didThrow(testToken, testToken.mintTo2, [
testAccount,
testMintAuthority,
[],
1000,
1,
]),
);
await testToken.mintTo2(testAccount, testMintAuthority, [], 1000, 2);
const mintInfo = await testToken.getMintInfo();
assert(mintInfo.supply.toNumber() === 2000);
const accountInfo = await testToken.getAccountInfo(testAccount);
assert(accountInfo.amount.toNumber() === 2000);
}
export async function transfer(): Promise<void> {
const destOwner = new Account();
const dest = await testToken.createAccount(destOwner.publicKey);
@ -175,13 +199,40 @@ export async function transfer(): Promise<void> {
await testToken.transfer(testAccount, dest, testAccountOwner, [], 100);
const mintInfo = await testToken.getMintInfo();
assert(mintInfo.supply.toNumber() === 1000);
assert(mintInfo.supply.toNumber() === 2000);
let destAccountInfo = await testToken.getAccountInfo(dest);
assert(destAccountInfo.amount.toNumber() === 100);
let testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.amount.toNumber() === 900);
assert(testAccountInfo.amount.toNumber() === 1900);
}
export async function transfer2(): Promise<void> {
const destOwner = new Account();
const dest = await testToken.createAccount(destOwner.publicKey);
assert(
await didThrow(testToken, testToken.transfer2, [
testAccount,
dest,
testAccountOwner,
[],
100,
1,
]),
);
await testToken.transfer2(testAccount, dest, testAccountOwner, [], 100, 2);
const mintInfo = await testToken.getMintInfo();
assert(mintInfo.supply.toNumber() === 2000);
let destAccountInfo = await testToken.getAccountInfo(dest);
assert(destAccountInfo.amount.toNumber() === 100);
let testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.amount.toNumber() === 1800);
}
export async function approveRevoke(): Promise<void> {
@ -206,18 +257,6 @@ export async function approveRevoke(): Promise<void> {
}
}
export async function invalidApprove(): Promise<void> {
const owner = new Account();
const account1 = await testToken.createAccount(owner.publicKey);
const account2 = await testToken.createAccount(owner.publicKey);
const delegate = new Account();
// account2 is not a delegate account of account1
assert(didThrow(testToken.approve, [account1, account2, owner, [], 123]));
// account1Delegate is not a delegate account of account2
assert(didThrow(testToken.approve, [account2, delegate, owner, [], 123]));
}
export async function failOnApproveOverspend(): Promise<void> {
const owner = new Account();
const account1 = await testToken.createAccount(owner.publicKey);
@ -232,7 +271,7 @@ export async function failOnApproveOverspend(): Promise<void> {
assert(account1Info.amount.toNumber() == 10);
assert(account1Info.delegatedAmount.toNumber() == 2);
if (account1Info.delegate === null) {
throw new Error('deleage should not be null');
throw new Error('delegate should not be null');
} else {
assert(account1Info.delegate.equals(delegate.publicKey));
}
@ -250,7 +289,15 @@ export async function failOnApproveOverspend(): Promise<void> {
assert(account1Info.delegate === null);
assert(account1Info.delegatedAmount.toNumber() == 0);
assert(didThrow(testToken.transfer, [account1, account2, delegate, [], 1]));
assert(
await didThrow(testToken, testToken.transfer, [
account1,
account2,
delegate,
[],
1,
]),
);
}
export async function setAuthority(): Promise<void> {
@ -263,8 +310,8 @@ export async function setAuthority(): Promise<void> {
[],
);
assert(
didThrow(testToken.setAuthority, [
testAccountOwner,
await didThrow(testToken, testToken.setAuthority, [
testAccount,
newOwner.publicKey,
'AccountOwner',
testAccountOwner,
@ -290,6 +337,53 @@ export async function burn(): Promise<void> {
assert(accountInfo.amount.toNumber() == amount - 1);
}
export async function burn2(): Promise<void> {
let accountInfo = await testToken.getAccountInfo(testAccount);
const amount = accountInfo.amount.toNumber();
assert(
await didThrow(testToken, testToken.burn2, [
testAccount,
testAccountOwner,
[],
1,
1,
]),
);
await testToken.burn2(testAccount, testAccountOwner, [], 1, 2);
accountInfo = await testToken.getAccountInfo(testAccount);
assert(accountInfo.amount.toNumber() == amount - 1);
}
export async function freezeThawAccount(): Promise<void> {
let accountInfo = await testToken.getAccountInfo(testAccount);
const amount = accountInfo.amount.toNumber();
await testToken.freezeAccount(testAccount, testMintAuthority, []);
const destOwner = new Account();
const dest = await testToken.createAccount(destOwner.publicKey);
assert(
await didThrow(testToken, testToken.transfer, [
testAccount,
dest,
testAccountOwner,
[],
100,
]),
);
await testToken.thawAccount(testAccount, testMintAuthority, []);
await testToken.transfer(testAccount, dest, testAccountOwner, [], 100);
let testAccountInfo = await testToken.getAccountInfo(testAccount);
assert(testAccountInfo.amount.toNumber() === amount - 100);
}
export async function closeAccount(): Promise<void> {
const closeAuthority = new Account();
@ -312,7 +406,12 @@ export async function closeAccount(): Promise<void> {
// Check that accounts with non-zero token balance cannot be closed
assert(
didThrow(testToken.closeAccount, [testAccount, dest, closeAuthority, []]),
await didThrow(testToken, testToken.closeAccount, [
testAccount,
dest,
closeAuthority,
[],
]),
);
const connection = await getConnection();

View File

@ -324,12 +324,12 @@ export class Token {
* Creates and initializes a token.
*
* @param connection The connection to use
* @param owner User account that will own the returned account
* @param supply Initial supply to mint
* @param payer Fee payer for transaction
* @param mintAuthority Account or multisig that will control minting
* @param freezeAuthority Optional account or multisig that can freeze token accounts
* @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 account
* holding the total amount of new tokens
* @return Token object for the newly minted token
*/
static async createMint(
connection: Connection,
@ -432,6 +432,8 @@ export class Token {
*
* This account may then be used for multisignature verification
*
* @param m Number of required signatures
* @param signers Full set of signers
* @return Public key of the new multisig account
*/
async createMultisig(
@ -623,24 +625,24 @@ export class Token {
*
* @param source Source account
* @param destination Destination account
* @param authority Owner of the source account
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Number of tokens to transfer
*/
async transfer(
source: PublicKey,
destination: PublicKey,
authority: any,
owner: any,
multiSigners: Array<Account>,
amount: number | u64,
): Promise<TransactionSignature> {
let ownerPublicKey;
let signers;
if (isAccount(authority)) {
ownerPublicKey = authority.publicKey;
signers = [authority];
if (isAccount(owner)) {
ownerPublicKey = owner.publicKey;
signers = [owner];
} else {
ownerPublicKey = authority;
ownerPublicKey = owner;
signers = multiSigners;
}
return await sendAndConfirmTransaction(
@ -788,9 +790,9 @@ export class Token {
* Mint new tokens
*
* @param dest Public key of the account to mint to
* @param authority Owner of the mint
* @param authority Minting authority
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount ammount to mint
* @param amount Amount to mint
*/
async mintTo(
dest: PublicKey,
@ -829,9 +831,9 @@ export class Token {
* Burn tokens
*
* @param account Account to burn tokens from
* @param owner Public key account owner
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount amount to burn
* @param owner Account owner
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Amount to burn
*/
async burn(
account: PublicKey,
@ -871,8 +873,8 @@ export class Token {
*
* @param account Account to close
* @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 authority Authority which is allowed to close the account
* @param multiSigners Signing accounts if `authority` is a multiSig
*/
async closeAccount(
account: PublicKey,
@ -906,13 +908,273 @@ export class Token {
);
}
/**
* Freeze account
*
* @param account Account to freeze
* @param authority The mint freeze authority
* @param multiSigners Signing accounts if `authority` is a multiSig
*/
async freezeAccount(
account: PublicKey,
authority: any,
multiSigners: Array<Account>,
): Promise<void> {
let authorityPublicKey;
let signers;
if (isAccount(authority)) {
authorityPublicKey = authority.publicKey;
signers = [authority];
} else {
authorityPublicKey = authority;
signers = multiSigners;
}
await sendAndConfirmTransaction(
'FreezeAccount',
this.connection,
new Transaction().add(
Token.createFreezeAccountInstruction(
this.programId,
account,
this.publicKey,
authorityPublicKey,
multiSigners,
),
),
this.payer,
...signers,
);
}
/**
* Thaw account
*
* @param account Account to thaw
* @param authority The mint freeze authority
* @param multiSigners Signing accounts if `authority` is a multiSig
*/
async thawAccount(
account: PublicKey,
authority: any,
multiSigners: Array<Account>,
): Promise<void> {
let authorityPublicKey;
let signers;
if (isAccount(authority)) {
authorityPublicKey = authority.publicKey;
signers = [authority];
} else {
authorityPublicKey = authority;
signers = multiSigners;
}
await sendAndConfirmTransaction(
'ThawAccount',
this.connection,
new Transaction().add(
Token.createThawAccountInstruction(
this.programId,
account,
this.publicKey,
authorityPublicKey,
multiSigners,
),
),
this.payer,
...signers,
);
}
/**
* Transfer tokens to another account, asserting the token mint and decimals
*
* @param source Source account
* @param destination Destination account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Number of tokens to transfer
* @param decimals Number of decimals in transfer amount
*/
async transfer2(
source: PublicKey,
destination: PublicKey,
owner: any,
multiSigners: Array<Account>,
amount: number | u64,
decimals: number,
): Promise<TransactionSignature> {
let ownerPublicKey;
let signers;
if (isAccount(owner)) {
ownerPublicKey = owner.publicKey;
signers = [owner];
} else {
ownerPublicKey = owner;
signers = multiSigners;
}
return await sendAndConfirmTransaction(
'Transfer2',
this.connection,
new Transaction().add(
Token.createTransfer2Instruction(
this.programId,
source,
this.publicKey,
destination,
ownerPublicKey,
multiSigners,
amount,
decimals,
),
),
this.payer,
...signers,
);
}
/**
* Grant a third-party permission to transfer up the specified number of tokens from an account,
* asserting the token mint and decimals
*
* @param account Public key of the account
* @param delegate Account authorized to perform a transfer tokens from the source account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Maximum number of tokens the delegate may transfer
* @param decimals Number of decimals in approve amount
*/
async approve2(
account: PublicKey,
delegate: PublicKey,
owner: any,
multiSigners: Array<Account>,
amount: number | u64,
decimals: number,
): Promise<void> {
let ownerPublicKey;
let signers;
if (isAccount(owner)) {
ownerPublicKey = owner.publicKey;
signers = [owner];
} else {
ownerPublicKey = owner;
signers = multiSigners;
}
await sendAndConfirmTransaction(
'Approve2',
this.connection,
new Transaction().add(
Token.createApprove2Instruction(
this.programId,
account,
this.publicKey,
delegate,
ownerPublicKey,
multiSigners,
amount,
decimals,
),
),
this.payer,
...signers,
);
}
/**
* Mint new tokens, asserting the token mint and decimals
*
* @param dest Public key of the account to mint to
* @param authority Minting authority
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount Amount to mint
* @param decimals Number of decimals in amount to mint
*/
async mintTo2(
dest: PublicKey,
authority: any,
multiSigners: Array<Account>,
amount: number,
decimals: number,
): Promise<void> {
let ownerPublicKey;
let signers;
if (isAccount(authority)) {
ownerPublicKey = authority.publicKey;
signers = [authority];
} else {
ownerPublicKey = authority;
signers = multiSigners;
}
await sendAndConfirmTransaction(
'MintTo2',
this.connection,
new Transaction().add(
Token.createMintTo2Instruction(
this.programId,
this.publicKey,
dest,
ownerPublicKey,
multiSigners,
amount,
decimals,
),
),
this.payer,
...signers,
);
}
/**
* Burn tokens, asserting the token mint and decimals
*
* @param account Account to burn tokens from
* @param owner Account owner
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Amount to burn
* @param decimals Number of decimals in amount to burn
*/
async burn2(
account: PublicKey,
owner: any,
multiSigners: Array<Account>,
amount: number,
decimals: number,
): Promise<void> {
let ownerPublicKey;
let signers;
if (isAccount(owner)) {
ownerPublicKey = owner.publicKey;
signers = [owner];
} else {
ownerPublicKey = owner;
signers = multiSigners;
}
await sendAndConfirmTransaction(
'Burn2',
this.connection,
new Transaction().add(
Token.createBurn2Instruction(
this.programId,
this.publicKey,
account,
ownerPublicKey,
multiSigners,
amount,
decimals,
),
),
this.payer,
...signers,
);
}
/**
* 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
* @param decimals Number of decimals in token account amounts
* @param mintAuthority Minting authority
* @param freezeAuthority Optional authority that can freeze token accounts
*/
static createInitMintInstruction(
programId: PublicKey,
@ -993,6 +1255,7 @@ export class Token {
/**
* Construct a Transfer instruction
*
* @param programId SPL Token program account
* @param source Source account
* @param destination Destination account
* @param owner Owner of the source account
@ -1051,6 +1314,7 @@ export class Token {
/**
* Construct an Approve instruction
*
* @param programId SPL Token program account
* @param account Public key of the account
* @param delegate Account authorized to perform a transfer of tokens from the source account
* @param owner Owner of the source account
@ -1104,13 +1368,12 @@ export class Token {
}
/**
* Construct an Approve instruction
* Construct a Revoke instruction
*
* @param programId SPL Token program account
* @param account Public key of the account
* @param delegate Account authorized to perform a transfer of tokens from the source account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Maximum number of tokens the delegate may transfer
*/
static createRevokeInstruction(
programId: PublicKey,
@ -1152,6 +1415,7 @@ export class Token {
/**
* Construct a SetAuthority instruction
*
* @param programId SPL Token program account
* @param account Public key of the account
* @param newAuthority New authority of the account
* @param authorityType Type of authority to set
@ -1211,10 +1475,12 @@ export class Token {
/**
* Construct a MintTo instruction
*
* @param programId SPL Token program account
* @param mint Public key of the mint
* @param dest Public key of the account to mint to
* @param authority The mint authority
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount amount to mint
* @param amount Amount to mint
*/
static createMintToInstruction(
programId: PublicKey,
@ -1269,6 +1535,7 @@ export class Token {
/**
* Construct a Burn instruction
*
* @param programId SPL Token program account
* @param mint Mint for the account
* @param account Account to burn tokens from
* @param owner Owner of the account
@ -1326,10 +1593,12 @@ export class Token {
}
/**
* Construct a Burn instruction
* Construct a Close instruction
*
* @param account Account to burn tokens from
* @param owner account owner
* @param programId SPL Token program account
* @param account Account to close
* @param dest Account to receive the remaining balance of the closed account
* @param authority Account Close authority
* @param multiSigners Signing accounts if `owner` is a multiSig
*/
static createCloseAccountInstruction(
@ -1371,4 +1640,358 @@ export class Token {
data,
});
}
/**
* Construct a Freeze instruction
*
* @param programId SPL Token program account
* @param account Account to freeze
* @param mint Mint account
* @param authority Mint freeze authority
* @param multiSigners Signing accounts if `owner` is a multiSig
*/
static createFreezeAccountInstruction(
programId: PublicKey,
account: PublicKey,
mint: PublicKey,
authority: PublicKey,
multiSigners: Array<Account>,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 10, // FreezeAccount instruction
},
data,
);
let keys = [
{pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: false},
];
if (multiSigners.length === 0) {
keys.push({pubkey: authority, isSigner: true, isWritable: false});
} else {
keys.push({pubkey: authority, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
/**
* Construct a Thaw instruction
*
* @param programId SPL Token program account
* @param account Account to thaw
* @param mint Mint account
* @param authority Mint freeze authority
* @param multiSigners Signing accounts if `owner` is a multiSig
*/
static createThawAccountInstruction(
programId: PublicKey,
account: PublicKey,
mint: PublicKey,
authority: PublicKey,
multiSigners: Array<Account>,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 11, // ThawAccount instruction
},
data,
);
let keys = [
{pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: false},
];
if (multiSigners.length === 0) {
keys.push({pubkey: authority, isSigner: true, isWritable: false});
} else {
keys.push({pubkey: authority, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
/**
* Construct a Transfer2 instruction
*
* @param programId SPL Token program account
* @param source Source account
* @param mint Mint account
* @param destination Destination account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount Number of tokens to transfer
* @param decimals Number of decimals in transfer amount
*/
static createTransfer2Instruction(
programId: PublicKey,
source: PublicKey,
mint: PublicKey,
destination: PublicKey,
owner: PublicKey,
multiSigners: Array<Account>,
amount: number | u64,
decimals: number,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
Layout.uint64('amount'),
BufferLayout.u8('decimals'),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 12, // Transfer2 instruction
amount: new u64(amount).toBuffer(),
decimals,
},
data,
);
let keys = [
{pubkey: source, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: false},
{pubkey: destination, isSigner: false, isWritable: true},
];
if (multiSigners.length === 0) {
keys.push({
pubkey: owner,
isSigner: true,
isWritable: false,
});
} else {
keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
/**
* Construct an Approve2 instruction
*
* @param programId SPL Token program account
* @param account Public key of the account
* @param mint Mint account
* @param delegate Account authorized to perform a transfer of tokens from the source account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Maximum number of tokens the delegate may transfer
* @param decimals Number of decimals in approve amount
*/
static createApprove2Instruction(
programId: PublicKey,
account: PublicKey,
mint: PublicKey,
delegate: PublicKey,
owner: PublicKey,
multiSigners: Array<Account>,
amount: number | u64,
decimals: number,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
Layout.uint64('amount'),
BufferLayout.u8('decimals'),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 13, // Approve2 instruction
amount: new u64(amount).toBuffer(),
decimals,
},
data,
);
let keys = [
{pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: false},
{pubkey: delegate, isSigner: false, isWritable: false},
];
if (multiSigners.length === 0) {
keys.push({pubkey: owner, isSigner: true, isWritable: false});
} else {
keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
/**
* Construct a MintTo2 instruction
*
* @param programId SPL Token program account
* @param mint Public key of the mint
* @param dest Public key of the account to mint to
* @param authority The mint authority
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount Amount to mint
* @param decimals Number of decimals in amount to mint
*/
static createMintTo2Instruction(
programId: PublicKey,
mint: PublicKey,
dest: PublicKey,
authority: PublicKey,
multiSigners: Array<Account>,
amount: number,
decimals: number,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
Layout.uint64('amount'),
BufferLayout.u8('decimals'),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 14, // MintTo2 instruction
amount: new u64(amount).toBuffer(),
decimals,
},
data,
);
let keys = [
{pubkey: mint, isSigner: false, isWritable: true},
{pubkey: dest, isSigner: false, isWritable: true},
];
if (multiSigners.length === 0) {
keys.push({
pubkey: authority,
isSigner: true,
isWritable: false,
});
} else {
keys.push({pubkey: authority, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
/**
* Construct a Burn2 instruction
*
* @param programId SPL Token program account
* @param mint Mint for the account
* @param account Account to burn tokens from
* @param owner Owner of the account
* @param multiSigners Signing accounts if `authority` is a multiSig
* @param amount amount to burn
*/
static createBurn2Instruction(
programId: PublicKey,
mint: PublicKey,
account: PublicKey,
owner: PublicKey,
multiSigners: Array<Account>,
amount: number,
decimals: number,
): TransactionInstruction {
const dataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
Layout.uint64('amount'),
BufferLayout.u8('decimals'),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
instruction: 15, // Burn2 instruction
amount: new u64(amount).toBuffer(),
decimals,
},
data,
);
let keys = [
{pubkey: account, isSigner: false, isWritable: true},
{pubkey: mint, isSigner: false, isWritable: true},
];
if (multiSigners.length === 0) {
keys.push({
pubkey: owner,
isSigner: true,
isWritable: false,
});
} else {
keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
return new TransactionInstruction({
keys,
programId: programId,
data,
});
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@solana/spl-token",
"version": "0.0.7",
"version": "0.0.8",
"description": "SPL Token JavaScript API",
"license": "MIT",
"author": "Solana Maintainers <maintainers@solana.com>",