Skip to content

Commit

Permalink
Expose Layouts and instruction creation functions to allow more flexi…
Browse files Browse the repository at this point in the history
…ble use of the Token and TokenSwap clients. (solana-labs#517)
  • Loading branch information
dankelleher authored Sep 23, 2020
1 parent 4c93e07 commit af98c77
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 56 deletions.
108 changes: 61 additions & 47 deletions token-swap/js/client/token-swap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@
import assert from 'assert';
import BN from 'bn.js';
import * as BufferLayout from 'buffer-layout';
import {
Account,
PublicKey,
SystemProgram,
Transaction,
TransactionInstruction,
} from '@solana/web3.js';
import type {Connection, TransactionSignature} from '@solana/web3.js';
import type { Connection, TransactionSignature } from '@solana/web3.js';
import { Account, PublicKey, SystemProgram, Transaction, TransactionInstruction, } from '@solana/web3.js';

import * as Layout from './layout';
import {sendAndConfirmTransaction} from './util/send-and-confirm-transaction';
import { sendAndConfirmTransaction } from './util/send-and-confirm-transaction';

/**
* Some amount of tokens
Expand Down Expand Up @@ -95,7 +89,7 @@ type TokenSwapInfo = {|
/**
* @private
*/
const TokenSwapLayout = BufferLayout.struct([
export const TokenSwapLayout = BufferLayout.struct([
BufferLayout.u8('isInitialized'),
BufferLayout.u8('nonce'),
Layout.publicKey('tokenAccountA'),
Expand Down Expand Up @@ -159,6 +153,55 @@ export class TokenSwap {
);
}


static createInitSwapInstruction(
tokenSwapAccount: Account,
authority: PublicKey,
nonce: number,
tokenAccountA: PublicKey,
tokenAccountB: PublicKey,
tokenPool: PublicKey,
tokenAccountPool: PublicKey,
tokenProgramId: PublicKey,
swapProgramId: PublicKey,
feeNumerator: number,
feeDenominator: number
):TransactionInstruction {
const keys = [
{ pubkey: tokenSwapAccount.publicKey, isSigner: false, isWritable: true },
{ pubkey: authority, isSigner: false, isWritable: false },
{ pubkey: tokenAccountA, isSigner: false, isWritable: false },
{ pubkey: tokenAccountB, isSigner: false, isWritable: false },
{ pubkey: tokenPool, isSigner: false, isWritable: true },
{ pubkey: tokenAccountPool, isSigner: false, isWritable: true },
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
];
const commandDataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
BufferLayout.nu64('feeNumerator'),
BufferLayout.nu64('feeDenominator'),
BufferLayout.u8('nonce'),
]);
let data = Buffer.alloc(1024);
{
const encodeLength = commandDataLayout.encode(
{
instruction: 0, // InitializeSwap instruction
feeNumerator,
feeDenominator,
nonce,
},
data,
);
data = data.slice(0, encodeLength);
}
return new TransactionInstruction({
keys,
programId: swapProgramId,
data,
});
}

/**
* Create a new Token Swap
*
Expand All @@ -173,7 +216,7 @@ export class TokenSwap {
* @param tokenProgramId The program id of the token program
* @param feeNumerator Numerator of the fee ratio
* @param feeDenominator Denominator of the fee ratio
* @param programId Program ID of the token-swap program
* @param swapProgramId Program ID of the token-swap program
* @return Token object for the newly minted token, Public key of the account holding the total supply of new tokens
*/
static async createTokenSwap(
Expand All @@ -189,13 +232,13 @@ export class TokenSwap {
nonce: number,
feeNumerator: number,
feeDenominator: number,
programId: PublicKey,
swapProgramId: PublicKey,
): Promise<TokenSwap> {
let transaction;
const tokenSwap = new TokenSwap(
connection,
tokenSwapAccount.publicKey,
programId,
swapProgramId,
payer,
);

Expand All @@ -210,43 +253,13 @@ export class TokenSwap {
newAccountPubkey: tokenSwapAccount.publicKey,
lamports: balanceNeeded,
space: TokenSwapLayout.span,
programId,
programId: swapProgramId,
}),
);

let keys = [
{pubkey: tokenSwapAccount.publicKey, isSigner: false, isWritable: true},
{pubkey: authority, isSigner: false, isWritable: false},
{pubkey: tokenAccountA, isSigner: false, isWritable: false},
{pubkey: tokenAccountB, isSigner: false, isWritable: false},
{pubkey: tokenPool, isSigner: false, isWritable: true},
{pubkey: tokenAccountPool, isSigner: false, isWritable: true},
{pubkey: tokenProgramId, isSigner: false, isWritable: false},
];
const commandDataLayout = BufferLayout.struct([
BufferLayout.u8('instruction'),
BufferLayout.nu64('feeNumerator'),
BufferLayout.nu64('feeDenominator'),
BufferLayout.u8('nonce'),
]);
let data = Buffer.alloc(1024);
{
const encodeLength = commandDataLayout.encode(
{
instruction: 0, // InitializeSwap instruction
feeNumerator,
feeDenominator,
nonce,
},
data,
);
data = data.slice(0, encodeLength);
}
transaction.add({
keys,
programId,
data,
});
const instruction = TokenSwap.createInitSwapInstruction(tokenSwapAccount, authority, nonce, tokenAccountA, tokenAccountB, tokenPool, tokenAccountPool, tokenProgramId, swapProgramId, feeNumerator, feeDenominator);

transaction.add(instruction);
await sendAndConfirmTransaction(
'createAccount and InitializeSwap',
connection,
Expand All @@ -258,6 +271,7 @@ export class TokenSwap {
return tokenSwap;
}


/**
* Retrieve tokenSwap information
*/
Expand Down
19 changes: 18 additions & 1 deletion token-swap/js/module.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
declare module '@solana/spl-token-swap' {
import { Buffer } from 'buffer';
import { Layout } from 'buffer-layout';
import { PublicKey, TransactionInstruction, TransactionSignature, Connection, Account } from "@solana/web3.js";
import BN from 'bn.js';

Expand All @@ -19,13 +20,29 @@ declare module '@solana/spl-token-swap' {
feeRatio: number,
};

export const TokenSwapLayout: Layout;

export class TokenSwap {
constructor(connection: Connection, tokenSwap: PublicKey, programId: PublicKey, payer: Account);

static getMinBalanceRentForExemptTokenSwap(
connection: Connection,
): Promise<number>;

static createInitSwapInstruction(
tokenSwapAccount: Account,
authority: PublicKey,
nonce: number,
tokenAccountA: PublicKey,
tokenAccountB: PublicKey,
tokenPool: PublicKey,
tokenAccountPool: PublicKey,
tokenProgramId: PublicKey,
swapProgramId: PublicKey,
feeNumerator: number,
feeDenominator: number
): TransactionInstruction;

static createTokenSwap(
connection: Connection,
payer: Account,
Expand All @@ -39,7 +56,7 @@ declare module '@solana/spl-token-swap' {
nonce: number,
feeNumerator: number,
feeDenominator: number,
programId: PublicKey,
swapProgramId: PublicKey,
): Promise<TokenSwap>

getInfo(): Promise<TokenSwapInfo>
Expand Down
16 changes: 16 additions & 0 deletions token-swap/js/module.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ declare module '@solana/spl-token-swap' {
feeRatio: number,
|};

declare export var TokenSwapLayout: Layout;

declare export class TokenSwap {
constructor(
connection: Connection,
Expand All @@ -34,6 +36,20 @@ declare module '@solana/spl-token-swap' {
connection: Connection,
): Promise<number>;

static createInitSwapInstruction(
programId: PublicKey,
tokenSwapAccount: Account,
authority: PublicKey,
nonce: number,
tokenAccountA: PublicKey,
tokenAccountB: PublicKey,
tokenPool: PublicKey,
tokenAccountPool: PublicKey,
tokenProgramId: PublicKey,
feeNumerator: number,
feeDenominator: number
): TransactionInstruction;

static createTokenSwap(
connection: Connection,
payer: Account,
Expand Down
10 changes: 5 additions & 5 deletions token/js/client/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
TransactionInstruction,
SYSVAR_RENT_PUBKEY,
} from '@solana/web3.js';
import type {Connection, TransactionSignature} from '@solana/web3.js';
import type {Connection, Commitment, TransactionSignature} from '@solana/web3.js';

import * as Layout from './layout';
import {sendAndConfirmTransaction} from './util/send-and-confirm-transaction';
Expand Down Expand Up @@ -107,7 +107,7 @@ type MintInfo = {|
freezeAuthority: null | PublicKey,
|};

const MintLayout = BufferLayout.struct([
export const MintLayout = BufferLayout.struct([
BufferLayout.u32('mintAuthorityOption'),
Layout.publicKey('mintAuthority'),
Layout.uint64('supply'),
Expand Down Expand Up @@ -177,7 +177,7 @@ type AccountInfo = {|
/**
* @private
*/
const AccountLayout = BufferLayout.struct([
export const AccountLayout = BufferLayout.struct([
Layout.publicKey('mint'),
Layout.publicKey('owner'),
Layout.uint64('amount'),
Expand Down Expand Up @@ -619,8 +619,8 @@ export class Token {
*
* @param account Public key of the account
*/
async getAccountInfo(account: PublicKey): Promise<AccountInfo> {
const info = await this.connection.getAccountInfo(account);
async getAccountInfo(account: PublicKey, commitment?: Commitment): Promise<AccountInfo> {
const info = await this.connection.getAccountInfo(account, commitment);
if (info === null) {
throw new Error('Failed to find account');
}
Expand Down
7 changes: 5 additions & 2 deletions token/js/module.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
declare module '@solana/spl-token' {
import { Buffer } from 'buffer';
import { PublicKey, TransactionInstruction, TransactionSignature, Connection, Account } from "@solana/web3.js";
import { Layout } from 'buffer-layout';
import { PublicKey, TransactionInstruction, TransactionSignature, Connection, Account } from '@solana/web3.js';
import BN from 'bn.js';

// === client/token.js ===
Expand All @@ -15,14 +16,16 @@ declare module '@solana/spl-token' {
| 'CloseAccount';

export const NATIVE_MINT: PublicKey;

export const MintLayout: Layout;
export type MintInfo = {
mintAuthority: null | PublicKey,
supply: u64,
decimals: number,
isInitialized: boolean,
freezeAuthority: null | PublicKey,
};

export const AccountLayout: Layout;
export type AccountInfo = {
mint: PublicKey,
owner: PublicKey,
Expand Down
3 changes: 2 additions & 1 deletion token/js/module.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

declare module '@solana/spl-token' {
// === client/token.js ===
declare export class u64 extends BN {
toBuffer(): Buffer;
static fromBuffer(buffer: Buffer): u64;
Expand All @@ -17,13 +16,15 @@ declare module '@solana/spl-token' {
| 'AccountOwner'
| 'CloseAccount';
declare export var NATIVE_MINT: PublicKey;
declare export var MintLayout: Layout;
declare export type MintInfo = {|
mintAuthority: null | PublicKey,
supply: u64,
decimals: number,
isInitialized: boolean,
freezeAuthority: null | PublicKey,
|};
declare export var AccountLayout: Layout;
declare export type AccountInfo = {|
mint: PublicKey,
owner: PublicKey,
Expand Down

0 comments on commit af98c77

Please sign in to comment.