@solana/spl-token#AccountLayout TypeScript Examples
The following examples show how to use
@solana/spl-token#AccountLayout.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts From protocol-v1 with Apache License 2.0 | 6 votes |
export function parseTokenAccount(data: Buffer): AccountInfo {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
// eslint-disable-next-line new-cap
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #2
Source File: index.ts From zo-client with Apache License 2.0 | 6 votes |
export async function createTokenAccountIxs(
vault: Keypair,
provider: Provider,
mint: PublicKey,
owner: PublicKey,
): Promise<TransactionInstruction[]> {
return [
SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: vault.publicKey,
space: AccountLayout.span,
lamports: await Token.getMinBalanceRentForExemptAccount(
provider.connection,
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
mint,
vault.publicKey,
owner,
),
];
}
Example #3
Source File: instructions.ts From serum-ts with Apache License 2.0 | 6 votes |
export function parseTokenAccount(data: Buffer): AccountInfo {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
// eslint-disable-next-line new-cap
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #4
Source File: accountParser.ts From jet-engine with GNU Affero General Public License v3.0 | 6 votes |
parseTokenAccount = (info: AccountInfo<Buffer>, address: PublicKey): Account => {
if (!info) throw new TokenAccountNotFoundError()
if (!info.owner.equals(TOKEN_PROGRAM_ID)) throw new TokenInvalidAccountOwnerError()
if (info.data.length != ACCOUNT_SIZE) throw new TokenInvalidAccountSizeError()
const rawAccount = AccountLayout.decode(info.data)
return {
address,
mint: rawAccount.mint,
owner: rawAccount.owner,
amount: rawAccount.amount,
delegate: rawAccount.delegateOption ? rawAccount.delegate : null,
delegatedAmount: rawAccount.delegatedAmount,
isInitialized: rawAccount.state !== AccountState.Uninitialized,
isFrozen: rawAccount.state === AccountState.Frozen,
isNative: !!rawAccount.isNativeOption,
rentExemptReserve: rawAccount.isNativeOption ? rawAccount.isNative : null,
closeAuthority: rawAccount.closeAuthorityOption ? rawAccount.closeAuthority : null
}
}
Example #5
Source File: accounts.ts From metaplex with Apache License 2.0 | 6 votes |
deserializeAccount = (data: Buffer) => {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #6
Source File: account.ts From metaplex with Apache License 2.0 | 6 votes |
export function createUninitializedAccount(
instructions: TransactionInstruction[],
payer: PublicKey,
amount: number,
signers: Keypair[],
) {
const account = Keypair.generate();
instructions.push(
SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: account.publicKey,
lamports: amount,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
signers.push(account);
return account.publicKey;
}
Example #7
Source File: index.ts From serum-ts with Apache License 2.0 | 6 votes |
export function parseTokenAccount(data: Buffer): AccountInfo {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
// eslint-disable-next-line new-cap
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #8
Source File: TokenAccountParser.ts From port-sdk with MIT License | 6 votes |
function deserialize(data: Buffer): AccountInfo {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
// eslint-disable-next-line new-cap
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #9
Source File: deserialize.ts From metaplex with Apache License 2.0 | 6 votes |
deserializeAccount = (data: Buffer) => {
const accountInfo = AccountLayout.decode(data);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = null;
accountInfo.delegatedAmount = new u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount);
}
accountInfo.isInitialized = accountInfo.state !== 0;
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);
}
return accountInfo;
}
Example #10
Source File: TokenAccount.ts From port-sdk with MIT License | 6 votes |
public static fromRaw(raw: RawData): TokenAccount {
const buffer = Buffer.from(raw.account.data);
const accountInfo = AccountLayout.decode(buffer);
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
return new TokenAccount(
TokenAccountId.of(raw.pubkey),
WalletId.of(accountInfo.owner),
MintId.of(accountInfo.mint),
Lamport.of(accountInfo.amount)
);
}
Example #11
Source File: accounts.ts From metaplex with Apache License 2.0 | 6 votes |
getCreatorTokenAccount = async (
walletKey: PublicKey,
connection: Connection,
mintKey: PublicKey,
totalClaim: number,
) => {
const [creatorTokenKey] = await PublicKey.findProgramAddress(
[walletKey.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintKey.toBuffer()],
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
);
const creatorTokenAccount = await connection.getAccountInfo(creatorTokenKey);
if (creatorTokenAccount === null) {
throw new Error(`Could not fetch creator token account`);
}
if (creatorTokenAccount.data.length !== AccountLayout.span) {
throw new Error(
`Invalid token account size ${creatorTokenAccount.data.length}`,
);
}
const creatorTokenInfo = AccountLayout.decode(
Buffer.from(creatorTokenAccount.data),
);
if (new BN(creatorTokenInfo.amount, 8, 'le').toNumber() < totalClaim) {
throw new Error(`Creator token account does not have enough tokens`);
}
return creatorTokenKey;
}
Example #12
Source File: getCreateTokenAccounts.ts From metaplex with Apache License 2.0 | 6 votes |
getCreateTokenAccounts = ({
cardsToAdd,
connection,
walletPublicKey,
}: GetCreateTokenAccounts): Promise<TransactionInstruction[]> =>
Promise.all(
cardsToAdd.map(({ toAccount }) =>
getCreateAccount({
connection,
walletPublicKey,
newAccountPubkey: toAccount.publicKey,
space: AccountLayout.span,
programId: programIds().token,
}),
),
)
Example #13
Source File: pools.ts From serum-ts with Apache License 2.0 | 5 votes |
createTokenAccount = (
owner: PublicKey,
payer: PublicKey,
mint: PublicKey,
lamports: number,
) => {
const account = new Account();
const instructions: TransactionInstruction[] = [];
const cleanUpInstructions: TransactionInstruction[] = [];
const space = AccountLayout.span as number;
instructions.push(
SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: account.publicKey,
lamports,
space,
programId: TOKEN_PROGRAM_ID,
}),
);
instructions.push(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
mint,
account.publicKey,
owner,
),
);
if (mint.equals(WRAPPED_SOL_MINT)) {
cleanUpInstructions.push(
Token.createCloseAccountInstruction(
TOKEN_PROGRAM_ID,
account.publicKey,
payer,
owner,
[],
),
);
}
return { account, instructions, cleanUpInstructions };
}
Example #14
Source File: helpers.ts From psyoptions with Apache License 2.0 | 5 votes |
initNewTokenAccount = async (
connection: Connection,
/** The owner for the new mint account */
owner: PublicKey,
/** The SPL Token Mint address */
mint: PublicKey,
wallet: Keypair
) => {
const tokenAccount = new Keypair();
const transaction = new Transaction();
const assetPoolRentBalance =
await connection.getMinimumBalanceForRentExemption(AccountLayout.span);
transaction.add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: tokenAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
mint,
tokenAccount.publicKey,
owner
)
);
await sendAndConfirmTransaction(
connection,
transaction,
[wallet, tokenAccount],
{
commitment: "confirmed",
}
);
return {
tokenAccount,
};
}
Example #15
Source File: index.tsx From metaplex with Apache License 2.0 | 5 votes |
async function calculateTotalCostOfRedeemingOtherPeoplesBids(
connection: Connection,
auctionView: AuctionView,
bids: ParsedAccount<BidderMetadata>[],
bidRedemptions: Record<string, ParsedAccount<BidRedemptionTicket>>,
): Promise<number> {
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const metadataRentExempt = await connection.getMinimumBalanceForRentExemption(
MAX_METADATA_LEN,
);
const editionRentExempt = await connection.getMinimumBalanceForRentExemption(
MAX_EDITION_LEN,
);
const prizeTrackingTicketExempt =
await connection.getMinimumBalanceForRentExemption(
MAX_PRIZE_TRACKING_TICKET_SIZE,
);
const eligibleParticipations =
await findEligibleParticipationBidsForRedemption(
auctionView,
bids,
bidRedemptions,
);
const max = auctionView.auction.info.bidState.max.toNumber();
let totalWinnerItems = 0;
for (let i = 0; i < max; i++) {
const winner = auctionView.auction.info.bidState.getWinnerAt(i);
if (!winner) {
break;
} else {
const bid = bids.find(b => b.info.bidderPubkey === winner);
if (bid) {
for (
let j = 0;
j < auctionView.auctionManager.safetyDepositBoxesExpected.toNumber();
j++
) {
totalWinnerItems += auctionView.auctionManager
.getAmountForWinner(i, j)
.toNumber();
}
}
}
}
return (
(mintRentExempt +
accountRentExempt +
metadataRentExempt +
editionRentExempt +
prizeTrackingTicketExempt) *
(eligibleParticipations.length + totalWinnerItems)
);
}
Example #16
Source File: mockAccounts.ts From protocol-v1 with Apache License 2.0 | 5 votes |
export async function mockUserUSDCAccount(
fakeUSDCMint,
usdcMintAmount,
provider,
owner?: PublicKey
): Promise<Keypair> {
const userUSDCAccount = anchor.web3.Keypair.generate();
const fakeUSDCTx = new Transaction();
if (owner === undefined) {
owner = provider.wallet.publicKey;
}
const createUSDCTokenAccountIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: userUSDCAccount.publicKey,
lamports: await Token.getMinBalanceRentForExemptAccount(
provider.connection
),
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
});
fakeUSDCTx.add(createUSDCTokenAccountIx);
const initUSDCTokenAccountIx = Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
userUSDCAccount.publicKey,
owner
);
fakeUSDCTx.add(initUSDCTokenAccountIx);
const mintToUserAccountTx = await Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
userUSDCAccount.publicKey,
provider.wallet.publicKey,
[],
usdcMintAmount.toNumber()
);
fakeUSDCTx.add(mintToUserAccountTx);
const _fakeUSDCTxResult = await sendAndConfirmTransaction(
provider.connection,
fakeUSDCTx,
[provider.wallet.payer, userUSDCAccount],
{
skipPreflight: false,
commitment: 'recent',
preflightCommitment: 'recent',
}
);
return userUSDCAccount;
}
Example #17
Source File: testHelpers.ts From protocol-v1 with Apache License 2.0 | 5 votes |
export async function mockUserUSDCAccount(
fakeUSDCMint: Keypair,
usdcMintAmount: BN,
provider: Provider,
owner?: PublicKey
): Promise<Keypair> {
const userUSDCAccount = anchor.web3.Keypair.generate();
const fakeUSDCTx = new Transaction();
if (owner === undefined) {
owner = provider.wallet.publicKey;
}
const createUSDCTokenAccountIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: userUSDCAccount.publicKey,
lamports: await Token.getMinBalanceRentForExemptAccount(
provider.connection
),
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
});
fakeUSDCTx.add(createUSDCTokenAccountIx);
const initUSDCTokenAccountIx = Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
userUSDCAccount.publicKey,
owner
);
fakeUSDCTx.add(initUSDCTokenAccountIx);
const mintToUserAccountTx = await Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
userUSDCAccount.publicKey,
provider.wallet.publicKey,
[],
usdcMintAmount.toNumber()
);
fakeUSDCTx.add(mintToUserAccountTx);
const _fakeUSDCTxResult = await sendAndConfirmTransaction(
provider.connection,
fakeUSDCTx,
// @ts-ignore
[provider.wallet.payer, userUSDCAccount],
{
skipPreflight: false,
commitment: 'recent',
preflightCommitment: 'recent',
}
);
return userUSDCAccount;
}
Example #18
Source File: account.ts From metaplex with Apache License 2.0 | 5 votes |
export function ensureWrappedAccount(
instructions: TransactionInstruction[],
cleanupInstructions: TransactionInstruction[],
toCheck: TokenAccount | undefined,
payer: PublicKey,
amount: number,
signers: Keypair[],
) {
if (toCheck && !toCheck.info.isNative) {
return toCheck.pubkey;
}
const TOKEN_PROGRAM_ID = programIds().token;
const account = Keypair.generate();
instructions.push(
SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: account.publicKey,
lamports: amount,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
instructions.push(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
WRAPPED_SOL_MINT,
account.publicKey,
payer,
),
);
cleanupInstructions.push(
Token.createCloseAccountInstruction(
TOKEN_PROGRAM_ID,
account.publicKey,
payer,
payer,
[],
),
);
signers.push(account);
return account.publicKey.toBase58();
}
Example #19
Source File: Port.ts From port-sdk with MIT License | 4 votes |
public async createReserve({
provider,
reserveConfig,
transferAuthority,
sourceTokenWallet,
initialLiquidity,
oracle,
price,
}: {
provider: Provider;
reserveConfig: ReserveConfigProto;
transferAuthority: PublicKey;
sourceTokenWallet: PublicKey;
initialLiquidity: number | BN;
oracle?: PublicKey;
price?: BN;
}): Promise<[TransactionEnvelope[], PublicKey]> {
invariant(!!oracle !== !!price, "Oracle and price can't both be present");
const [createReserveAccountIx, reservePubKey] = await this.createAccount({
provider,
space: ReserveLayout.span,
owner: PORT_LENDING,
});
const [collateralMintIx, collateralMintPubKey] = await this.createAccount({
provider,
space: MintLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [liquiditySupplyIx, liquiditySupplyPubKey] = await this.createAccount(
{
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
}
);
const [collateralSupplyIx, collateralSupplyPubKey] =
await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [userCollateralIx, userCollateralPubKey] = await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [feeReceiverIx, feeReceiverPubkey] = await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const tokenAccount = await getTokenAccount(provider, sourceTokenWallet);
const initReserveIx = initReserveInstruction(
initialLiquidity,
oracle ? 0 : 1, // price Option
price ?? new BN(1),
reserveConfig,
sourceTokenWallet,
collateralSupplyPubKey,
reservePubKey,
tokenAccount.mint,
liquiditySupplyPubKey,
feeReceiverPubkey,
oracle ?? Keypair.generate().publicKey,
collateralMintPubKey,
userCollateralPubKey,
this.lendingMarket,
(await this.getLendingMarketAuthority())[0],
provider.wallet.publicKey,
transferAuthority
);
let tx1 = new TransactionEnvelope(provider, []);
tx1 = tx1.combine(createReserveAccountIx);
tx1 = tx1.combine(collateralMintIx);
tx1 = tx1.combine(liquiditySupplyIx);
tx1 = tx1.combine(collateralSupplyIx);
tx1 = tx1.combine(userCollateralIx);
let tx2 = new TransactionEnvelope(provider, []);
tx2 = tx2.combine(feeReceiverIx);
tx2 = tx2.addInstructions(initReserveIx);
return [[tx1, tx2], reservePubKey];
}
Example #20
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
/**
* Note: for seed param, this must be <= 32 characters for the txn to succeed
*/
static async makeInitializePoolTransaction<T extends PublicKey | Account>(
connection: Connection,
tokenSwapProgram: PublicKey,
owner: T,
componentMints: PublicKey[],
sourceTokenAccounts: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number; // note this is raw amount, not decimal
}[],
options: PoolConfig,
liquidityTokenPrecision = DEFAULT_LIQUIDITY_TOKEN_PRECISION,
accounts?: {
liquidityTokenMint?: Account;
tokenSwapPoolAddress?: Account;
},
seed?: string,
): Promise<{
initializeAccountsTransaction: Transaction;
initializeAccountsSigners: Account[];
initializePoolTransaction: Transaction;
initializePoolSigners: Account[];
}> {
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
const initializeAccountsInstructions: TransactionInstruction[] = [];
const initializeAccountsSigners: Account[] = [];
const liquidityTokenMintAccount = accounts?.liquidityTokenMint
? accounts.liquidityTokenMint
: new Account();
initializeAccountsInstructions.push(
SystemProgram.createAccount({
fromPubkey: ownerAddress,
newAccountPubkey: liquidityTokenMintAccount.publicKey,
lamports: await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
),
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
initializeAccountsSigners.push(liquidityTokenMintAccount);
let tokenSwapAccountPubkey;
let tokenSwapAccountSigner;
if (accounts?.tokenSwapPoolAddress) {
tokenSwapAccountPubkey = accounts.tokenSwapPoolAddress.publicKey;
tokenSwapAccountSigner = accounts.tokenSwapPoolAddress;
} else if (seed) {
// Only works when owner is of type Account
tokenSwapAccountSigner = owner;
tokenSwapAccountPubkey = await PublicKey.createWithSeed(ownerAddress, seed, tokenSwapProgram);
} else {
tokenSwapAccountSigner = new Account();
tokenSwapAccountPubkey = tokenSwapAccountSigner.pubkey;
}
const [authority, nonce] = await PublicKey.findProgramAddress(
[tokenSwapAccountPubkey.toBuffer()],
tokenSwapProgram,
);
// create mint for pool liquidity token
initializeAccountsInstructions.push(
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
liquidityTokenMintAccount.publicKey,
liquidityTokenPrecision,
// pass control of liquidity mint to swap program
authority,
// swap program can freeze liquidity token mint
null,
),
);
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const holdingAccounts: { [mint: string]: Account } = {};
componentMints.forEach(mint => {
const {
account,
instructions: createHoldingTokenAccountInstructions,
} = createTokenAccount(authority, ownerAddress, mint, accountRentExempt);
initializeAccountsInstructions.push(
...createHoldingTokenAccountInstructions,
);
initializeAccountsSigners.push(account);
holdingAccounts[mint.toBase58()] = account;
});
const {
account: depositorAccount,
instructions: createLPTokenAccountInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
liquidityTokenMintAccount.publicKey,
accountRentExempt,
);
initializeAccountsSigners.push(depositorAccount);
initializeAccountsInstructions.push(...createLPTokenAccountInstructions);
const {
account: feeAccount,
instructions: createFeeAccountInstructions,
} = createTokenAccount(
SWAP_PROGRAM_OWNER_FEE_ADDRESS,
ownerAddress,
liquidityTokenMintAccount.publicKey,
accountRentExempt,
);
initializeAccountsSigners.push(feeAccount);
initializeAccountsInstructions.push(...createFeeAccountInstructions);
const initializeAccountsTransaction = new Transaction();
initializeAccountsTransaction.add(...initializeAccountsInstructions);
// break up these into two transactions because it does not fit in a single transaction
const initializePoolSigners: Account[] = [];
const initializePoolInstructions: TransactionInstruction[] = [];
const cleanupInstructions: TransactionInstruction[] = [];
let initializeTokenSwapAccountInstruction;
if (seed) {
initializeTokenSwapAccountInstruction = SystemProgram.createAccountWithSeed({
fromPubkey: ownerAddress,
basePubkey: ownerAddress,
newAccountPubkey: tokenSwapAccountPubkey,
seed: seed,
lamports: await connection.getMinimumBalanceForRentExemption(
getLayoutForProgramId(tokenSwapProgram).span
),
space: getLayoutForProgramId(tokenSwapProgram).span,
programId: tokenSwapProgram,
});
} else {
initializeTokenSwapAccountInstruction = SystemProgram.createAccount({
fromPubkey: ownerAddress,
newAccountPubkey: tokenSwapAccountPubkey,
lamports: await connection.getMinimumBalanceForRentExemption(
getLayoutForProgramId(tokenSwapProgram).span,
),
space: getLayoutForProgramId(tokenSwapProgram).span,
programId: tokenSwapProgram,
})
}
initializePoolInstructions.push(initializeTokenSwapAccountInstruction);
sourceTokenAccounts.forEach(({ mint, tokenAccount, amount }) => {
let wrappedAccount: PublicKey;
if (mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
amount + accountRentExempt,
);
wrappedAccount = account.publicKey;
initializePoolSigners.push(account);
initializePoolInstructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
wrappedAccount = tokenAccount;
}
initializePoolInstructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
wrappedAccount,
holdingAccounts[mint.toBase58()].publicKey,
ownerAddress,
[],
amount,
),
);
});
initializePoolInstructions.push(
createInitSwapInstruction(
tokenSwapAccountPubkey,
authority,
holdingAccounts[sourceTokenAccounts[0].mint.toBase58()].publicKey,
holdingAccounts[sourceTokenAccounts[1].mint.toBase58()].publicKey,
liquidityTokenMintAccount.publicKey,
feeAccount.publicKey,
depositorAccount.publicKey,
TOKEN_PROGRAM_ID,
tokenSwapProgram,
nonce,
options,
),
);
initializePoolSigners.push(tokenSwapAccountSigner);
const initializePoolTransaction = new Transaction();
initializePoolTransaction.add(
...initializePoolInstructions,
...cleanupInstructions,
);
return {
initializeAccountsTransaction,
initializeAccountsSigners,
initializePoolTransaction,
initializePoolSigners,
};
}
Example #21
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
async makeSwapTransaction<T extends PublicKey | Account>(
connection: Connection,
owner: T,
tokenIn: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number;
},
tokenOut: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number;
},
slippage: number,
hostFeeAccount?: PublicKey,
): Promise<{ transaction: Transaction; signers: Account[]; payer: T }> {
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
const [poolMint, inMint, outMint] = await Promise.all([
this.getCachedMintAccount(connection, this._poolTokenMint, 3600_000),
this.getCachedMintAccount(connection, tokenIn.mint, 3600_000),
this.getCachedMintAccount(connection, tokenOut.mint, 3600_000),
]);
const amountIn = Math.floor(tokenIn.amount * Math.pow(10, inMint.decimals));
const minAmountOut = Math.floor(
tokenOut.amount * Math.pow(10, outMint.decimals) * (1 - slippage),
);
const holdingA =
this._tokenMints[0].toBase58() === tokenIn.mint.toBase58()
? this._holdingAccounts[0]
: this._holdingAccounts[1];
const holdingB = holdingA.equals(this._holdingAccounts[0])
? this._holdingAccounts[1]
: this._holdingAccounts[0];
if (!poolMint.mintAuthority || !this._feeAccount) {
throw new Error('Mint doesnt have authority');
}
const authority = poolMint.mintAuthority;
const instructions: TransactionInstruction[] = [];
const cleanupInstructions: TransactionInstruction[] = [];
const signers: Account[] = [];
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
let fromAccount: PublicKey;
if (tokenIn.mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
amountIn + accountRentExempt,
);
fromAccount = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
fromAccount = tokenIn.tokenAccount;
}
let toAccount: PublicKey;
if (tokenOut.mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
accountRentExempt,
);
toAccount = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
toAccount = tokenOut.tokenAccount;
}
// create approval for transfer transactions
const transferAuthority = approveTransfer(
instructions,
cleanupInstructions,
fromAccount,
ownerAddress,
amountIn,
this.isLatest ? undefined : authority,
);
if (this.isLatest) {
signers.push(transferAuthority);
}
// swap
instructions.push(
swapInstruction(
this._poolAccount,
authority,
transferAuthority.publicKey,
fromAccount,
holdingA,
holdingB,
toAccount,
this._poolTokenMint,
this._feeAccount,
this._programId,
TOKEN_PROGRAM_ID,
amountIn,
minAmountOut,
hostFeeAccount,
),
);
instructions.push(...cleanupInstructions);
const transaction = new Transaction();
transaction.add(...instructions);
return { transaction, signers, payer: owner };
}
Example #22
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
async makeAddSingleSidedLiquidityTransaction<T extends PublicKey>(
connection: Connection,
owner: T,
sourceTokenAccount: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number; // note this is raw amount, not decimal
},
poolTokenAccount?: PublicKey,
): Promise<{ transaction: Transaction; signers: Account[]; payer: T }> {
assert(this._decoded.curve.constantPrice, 'Only implemented for constant price pools');
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
const instructions: TransactionInstruction[] = [];
const cleanupInstructions: TransactionInstruction[] = [];
const signers: Account[] = [];
const poolMint = await this.getCachedMintAccount(
connection,
this._poolTokenMint,
0,
);
if (!poolMint.mintAuthority) {
throw new Error('Mint doesnt have authority');
}
const authority = poolMint.mintAuthority;
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const accountA = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[0],
);
const accountB = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[1],
);
const reserve0 = accountA.info.amount.toNumber();
const reserve1 = accountB.info.amount.toNumber();
const supply = poolMint.supply.toNumber();
const tokenBPrice = this._decoded.curve.constantPrice.token_b_price
let price;
if (sourceTokenAccount.mint.equals(this.tokenMints[1])) {
price = tokenBPrice;
} else {
price = 1;
}
const sourceAmountPostFees = sourceTokenAccount.amount - (
Math.max(1, sourceTokenAccount.amount / 2) *
this._decoded.fees.tradeFeeNumerator / this._decoded.fees.tradeFeeDenominator
)
const liquidity = Math.floor((sourceAmountPostFees * price * supply) / (reserve0 + reserve1 * tokenBPrice));
let fromKey: PublicKey;
if (sourceTokenAccount.mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
sourceTokenAccount.amount + accountRentExempt,
);
fromKey = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
fromKey = sourceTokenAccount.tokenAccount;
}
let toAccount: PublicKey;
if (!poolTokenAccount) {
const {
account,
instructions: createToAccountInstructions,
cleanUpInstructions: cleanupCreateToAccountInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
this._poolTokenMint,
accountRentExempt,
);
toAccount = account.publicKey;
signers.push(account);
instructions.push(...createToAccountInstructions);
cleanupInstructions.push(...cleanupCreateToAccountInstructions);
} else {
toAccount = poolTokenAccount;
}
const transferAuthority = approveTransfer(
instructions,
cleanupInstructions,
fromKey,
ownerAddress,
sourceTokenAccount.amount,
this.isLatest ? undefined : authority,
);
if (this.isLatest) {
signers.push(transferAuthority);
}
instructions.push(
depositExactOneInstruction(
this._poolAccount,
authority,
transferAuthority.publicKey,
sourceTokenAccount.tokenAccount,
this._holdingAccounts[0],
this._holdingAccounts[1],
this._poolTokenMint,
toAccount,
this._programId,
TOKEN_PROGRAM_ID,
sourceTokenAccount.amount,
liquidity,
this.isLatest,
),
);
const transaction = new Transaction();
transaction.add(...instructions);
transaction.add(...cleanupInstructions);
return { transaction, signers, payer: owner };
}
Example #23
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
async makeAddLiquidityTransaction<T extends PublicKey | Account>(
connection: Connection,
owner: T,
sourceTokenAccounts: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number; // note this is raw amount, not decimal
}[],
poolTokenAccount?: PublicKey,
slippageTolerance = 0.005, // allow slippage of this much between setting input amounts and on chain transaction
): Promise<{ transaction: Transaction; signers: Account[]; payer: T }> {
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
const poolMint = await this.getCachedMintAccount(
connection,
this._poolTokenMint,
360000,
);
if (!poolMint.mintAuthority) {
throw new Error('Mint doesnt have authority');
}
if (!this._feeAccount) {
throw new Error('Invald fee account');
}
const accountA = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[0],
);
const accountB = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[1],
);
const reserve0 = accountA.info.amount.toNumber();
const reserve1 = accountB.info.amount.toNumber();
const [fromA, fromB] = accountA.info.mint.equals(
sourceTokenAccounts[0].mint,
)
? [sourceTokenAccounts[0], sourceTokenAccounts[1]]
: [sourceTokenAccounts[1], sourceTokenAccounts[0]];
if (!fromA.tokenAccount || !fromB.tokenAccount) {
throw new Error('Missing account info.');
}
const supply = poolMint.supply.toNumber();
const authority = poolMint.mintAuthority;
// Uniswap whitepaper: https://uniswap.org/whitepaper.pdf
// see: https://uniswap.org/docs/v2/advanced-topics/pricing/
// as well as native uniswap v2 oracle: https://uniswap.org/docs/v2/core-concepts/oracles/
const amount0 = fromA.amount;
const amount1 = fromB.amount;
const liquidity = Math.min(
(amount0 * (1 - slippageTolerance) * supply) / reserve0,
(amount1 * (1 - slippageTolerance) * supply) / reserve1,
);
const instructions: TransactionInstruction[] = [];
const cleanupInstructions: TransactionInstruction[] = [];
const signers: Account[] = [];
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
let fromKeyA: PublicKey;
if (fromA.mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
fromA.amount + accountRentExempt,
);
fromKeyA = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
fromKeyA = fromA.tokenAccount;
}
let fromKeyB: PublicKey;
if (fromB.mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
fromB.amount + accountRentExempt,
);
fromKeyB = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
fromKeyB = fromB.tokenAccount;
}
let toAccount: PublicKey;
if (!poolTokenAccount) {
const {
account,
instructions: createToAccountInstructions,
cleanUpInstructions: cleanupCreateToAccountInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
this._poolTokenMint,
accountRentExempt,
);
toAccount = account.publicKey;
signers.push(account);
instructions.push(...createToAccountInstructions);
cleanupInstructions.push(...cleanupCreateToAccountInstructions);
} else {
toAccount = poolTokenAccount;
}
// create approval for transfer transactions
const transferAuthority = approveTransfer(
instructions,
cleanupInstructions,
fromKeyA,
ownerAddress,
amount0,
this.isLatest ? undefined : authority,
);
if (this.isLatest) {
signers.push(transferAuthority);
}
approveTransfer(
instructions,
cleanupInstructions,
fromKeyB,
ownerAddress,
amount1,
this.isLatest ? transferAuthority.publicKey : authority,
);
instructions.push(
depositInstruction(
this._poolAccount,
authority,
transferAuthority.publicKey,
fromKeyA,
fromKeyB,
this._holdingAccounts[0],
this._holdingAccounts[1],
this._poolTokenMint,
toAccount,
this._programId,
TOKEN_PROGRAM_ID,
liquidity,
amount0,
amount1,
),
);
const transaction = new Transaction();
transaction.add(...instructions);
transaction.add(...cleanupInstructions);
return { transaction, signers, payer: owner };
}
Example #24
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
async makeRemoveLiquidityTransaction<T extends PublicKey | Account>(
connection: Connection,
owner: T,
liquidityAmount: number,
poolAccount: TokenAccount,
tokenAccounts: TokenAccount[],
): Promise<{ transaction: Transaction; signers: Account[]; payer: T }> {
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
// TODO get min amounts based on total supply and liquidity
const minAmount0 = 0;
const minAmount1 = 0;
const poolMint = await this.getCachedMintAccount(
connection,
this._poolTokenMint,
3600000,
);
const accountA = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[0],
3600000,
);
const accountB = await this.getCachedTokenAccount(
connection,
this._holdingAccounts[1],
3600000,
);
if (!poolMint.mintAuthority) {
throw new Error('Mint doesnt have authority');
}
const authority = poolMint.mintAuthority;
const signers: Account[] = [];
const instructions: TransactionInstruction[] = [];
const cleanUpInstructions: TransactionInstruction[] = [];
let tokenAccountA: PublicKey | undefined;
let tokenAccountB: PublicKey | undefined;
if (accountA.info.mint.equals(WRAPPED_SOL_MINT)) {
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
accountRentExempt,
);
tokenAccountA = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanUpInstructions.push(...removeWrappedSolInstructions)
} else {
tokenAccountA = tokenAccounts.find(a =>
a.info.mint.equals(accountA.info.mint),
)?.pubkey;
}
if (accountB.info.mint.equals(WRAPPED_SOL_MINT)) {
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
accountRentExempt,
);
tokenAccountB = account.publicKey;
signers.push(account);
instructions.push(...createWrappedSolInstructions);
cleanUpInstructions.push(...removeWrappedSolInstructions)
} else {
tokenAccountB = tokenAccounts.find(a =>
a.info.mint.equals(accountB.info.mint),
)?.pubkey;
}
assert(
!!tokenAccountA,
`Token account for mint ${accountA.info.mint.toBase58()} not provided`,
);
assert(
!!tokenAccountB,
`Token account for mint ${accountB.info.mint.toBase58()} not provided`,
);
const transferAuthority = approveTransfer(
instructions,
cleanUpInstructions,
poolAccount.pubkey,
ownerAddress,
liquidityAmount,
this.isLatest ? undefined : authority,
);
if (this.isLatest) {
signers.push(transferAuthority);
}
instructions.push(
withdrawInstruction(
this._poolAccount,
authority,
transferAuthority.publicKey,
this._poolTokenMint,
this._feeAccount,
poolAccount.pubkey,
this._holdingAccounts[0],
this._holdingAccounts[1],
tokenAccountA,
tokenAccountB,
this._programId,
TOKEN_PROGRAM_ID,
liquidityAmount,
minAmount0,
minAmount1,
),
);
const transaction = new Transaction();
transaction.add(...instructions, ...cleanUpInstructions);
return { transaction, signers, payer: owner };
}
Example #25
Source File: accounts.tsx From metaplex with Apache License 2.0 | 4 votes |
export function AccountsProvider({
children = null,
}: {
children: React.ReactNode;
}) {
const connection = useConnection();
const { publicKey } = useWallet();
const [tokenAccounts, setTokenAccounts] = useState<TokenAccount[]>([]);
const [userAccounts, setUserAccounts] = useState<TokenAccount[]>([]);
const { nativeAccount } = UseNativeAccount();
const walletKey = publicKey?.toBase58();
const selectUserAccounts = useCallback(() => {
return cache
.byParser(TokenAccountParser)
.map(id => cache.get(id))
.filter(a => a && a.info.owner.toBase58() === walletKey)
.map(a => a as TokenAccount);
}, [walletKey, nativeAccount]);
useEffect(() => {
const accounts = selectUserAccounts().filter(
a => a !== undefined,
) as TokenAccount[];
setUserAccounts(accounts);
}, [nativeAccount, tokenAccounts, selectUserAccounts]);
useEffect(() => {
const subs: number[] = [];
cache.emitter.onCache(args => {
if (args.isNew && args.isActive) {
const id = args.id;
const deserialize = args.parser;
connection.onAccountChange(new PublicKey(id), info => {
cache.add(id, info, deserialize);
});
}
});
return () => {
subs.forEach(id => connection.removeAccountChangeListener(id));
};
}, [connection]);
useEffect(() => {
if (!connection || !publicKey) {
setTokenAccounts([]);
} else {
precacheUserTokenAccounts(connection, publicKey).then(() => {
setTokenAccounts(selectUserAccounts());
});
// This can return different types of accounts: token-account, mint, multisig
// TODO: web3.js expose ability to filter.
// this should use only filter syntax to only get accounts that are owned by user
const tokenSubID = connection.onProgramAccountChange(
programIds().token,
info => {
// TODO: fix type in web3.js
const id = info.accountId as unknown as string;
// TODO: do we need a better way to identify layout (maybe a enum identifing type?)
if (info.accountInfo.data.length === AccountLayout.span) {
const data = deserializeAccount(info.accountInfo.data);
if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
cache.add(id, info.accountInfo, TokenAccountParser);
setTokenAccounts(selectUserAccounts());
}
}
},
'singleGossip',
);
return () => {
connection.removeProgramAccountChangeListener(tokenSubID);
};
}
}, [connection, publicKey, selectUserAccounts]);
return (
<AccountsContext.Provider
value={{
userAccounts,
nativeAccount,
}}
>
{children}
</AccountsContext.Provider>
);
}
Example #26
Source File: token.ts From metaplex with Apache License 2.0 | 4 votes |
mintNFT = async (
connection: Connection,
wallet: WalletSigner,
// SOL account
owner: PublicKey,
) => {
if (!wallet.publicKey) throw new WalletNotConnectedError();
const TOKEN_PROGRAM_ID = new PublicKey(
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
);
//const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = new PublicKey(
// 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
//);
const mintAccount = new Account();
const tokenAccount = new Account();
// Allocate memory for the account
const mintRent = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const accountRent = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
let transaction = new Transaction();
const signers = [mintAccount, tokenAccount];
transaction.recentBlockhash = (
await connection.getRecentBlockhash('max')
).blockhash;
transaction.add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: mintAccount.publicKey,
lamports: mintRent,
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
transaction.add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: tokenAccount.publicKey,
lamports: accountRent,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
transaction.add(
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mintAccount.publicKey,
0,
wallet.publicKey,
wallet.publicKey,
),
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
mintAccount.publicKey,
tokenAccount.publicKey,
owner,
),
);
transaction.add(
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mintAccount.publicKey,
tokenAccount.publicKey,
wallet.publicKey,
[],
1,
),
);
transaction.add(
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
mintAccount.publicKey,
null,
'MintTokens',
wallet.publicKey,
[],
),
);
transaction.setSigners(wallet.publicKey, ...signers.map(s => s.publicKey));
if (signers.length > 0) {
transaction.partialSign(...signers);
}
transaction = await wallet.signTransaction(transaction);
const rawTransaction = transaction.serialize();
const options = {
skipPreflight: true,
commitment: 'singleGossip',
};
const txid = await connection.sendRawTransaction(rawTransaction, options);
return { txid, mint: mintAccount.publicKey, account: tokenAccount.publicKey };
}
Example #27
Source File: closeVault.ts From metaplex with Apache License 2.0 | 4 votes |
// This command "closes" the vault, by activating & combining it in one go, handing it over to the auction manager
// authority (that may or may not exist yet.)
export async function closeVault(
connection: Connection,
wallet: WalletSigner,
vault: StringPublicKey,
fractionMint: StringPublicKey,
fractionTreasury: StringPublicKey,
redeemTreasury: StringPublicKey,
priceMint: StringPublicKey,
externalPriceAccount: StringPublicKey,
): Promise<{
instructions: TransactionInstruction[];
signers: Keypair[];
}> {
if (!wallet.publicKey) throw new WalletNotConnectedError();
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const signers: Keypair[] = [];
const instructions: TransactionInstruction[] = [];
await activateVault(
new BN(0),
vault,
fractionMint,
fractionTreasury,
wallet.publicKey.toBase58(),
instructions,
);
const outstandingShareAccount = createTokenAccount(
instructions,
wallet.publicKey,
accountRentExempt,
toPublicKey(fractionMint),
wallet.publicKey,
signers,
);
const payingTokenAccount = createTokenAccount(
instructions,
wallet.publicKey,
accountRentExempt,
toPublicKey(priceMint),
wallet.publicKey,
signers,
);
const transferAuthority = Keypair.generate();
// Shouldn't need to pay anything since we activated vault with 0 shares, but we still
// need this setup anyway.
approve(
instructions,
[],
payingTokenAccount,
wallet.publicKey,
0,
false,
undefined,
transferAuthority,
);
approve(
instructions,
[],
outstandingShareAccount,
wallet.publicKey,
0,
false,
undefined,
transferAuthority,
);
signers.push(transferAuthority);
await combineVault(
vault,
outstandingShareAccount.toBase58(),
payingTokenAccount.toBase58(),
fractionMint,
fractionTreasury,
redeemTreasury,
wallet.publicKey.toBase58(),
wallet.publicKey.toBase58(),
transferAuthority.publicKey.toBase58(),
externalPriceAccount,
instructions,
);
return { instructions, signers };
}
Example #28
Source File: helpers.ts From psyoptions with Apache License 2.0 | 4 votes |
createExerciser = async (
connection: Connection,
exerciser: Keypair,
mintAuthority: Keypair,
quoteToken: Token,
quoteAmount: number,
optionMint: PublicKey,
underlyingTokenMint: PublicKey
) => {
const transaction = new Transaction();
const quoteAccount = new Keypair();
const assetPoolRentBalance =
await connection.getMinimumBalanceForRentExemption(AccountLayout.span);
transaction.add(
SystemProgram.createAccount({
fromPubkey: exerciser.publicKey,
newAccountPubkey: quoteAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
quoteToken.publicKey,
quoteAccount.publicKey,
exerciser.publicKey
)
);
// create an associated token account to hold the options
const optionAccount = new Keypair();
transaction.add(
SystemProgram.createAccount({
fromPubkey: exerciser.publicKey,
newAccountPubkey: optionAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
optionMint,
optionAccount.publicKey,
exerciser.publicKey
)
);
// create an associated token account to hold the underlying tokens
const underlyingAccount = new Keypair();
transaction.add(
SystemProgram.createAccount({
fromPubkey: exerciser.publicKey,
newAccountPubkey: underlyingAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
underlyingTokenMint,
underlyingAccount.publicKey,
exerciser.publicKey
)
);
await sendAndConfirmTransaction(
connection,
transaction,
[exerciser, quoteAccount, optionAccount, underlyingAccount],
{
commitment: "confirmed",
}
);
// mint underlying tokens to the minter's account
await quoteToken.mintTo(
quoteAccount.publicKey,
mintAuthority,
[],
quoteAmount
);
return { optionAccount, quoteAccount, underlyingAccount };
}
Example #29
Source File: helpers.ts From psyoptions with Apache License 2.0 | 4 votes |
createMinter = async (
connection: Connection,
minter: Keypair,
mintAuthority: Keypair,
underlyingToken: Token,
underlyingAmount: number,
optionMint: PublicKey,
writerTokenMint: PublicKey,
quoteToken: Token,
quoteAmount: number = 0
) => {
const transaction = new Transaction();
const underlyingAccount = new Keypair();
const assetPoolRentBalance =
await connection.getMinimumBalanceForRentExemption(AccountLayout.span);
transaction.add(
SystemProgram.createAccount({
fromPubkey: minter.publicKey,
newAccountPubkey: underlyingAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
underlyingToken.publicKey,
underlyingAccount.publicKey,
minter.publicKey
)
);
const quoteAccount = new Keypair();
transaction.add(
SystemProgram.createAccount({
fromPubkey: minter.publicKey,
newAccountPubkey: quoteAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
quoteToken.publicKey,
quoteAccount.publicKey,
minter.publicKey
)
);
// create an associated token account to hold the options
const optionAccount = new Keypair();
transaction.add(
SystemProgram.createAccount({
fromPubkey: minter.publicKey,
newAccountPubkey: optionAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
optionMint,
optionAccount.publicKey,
minter.publicKey
)
);
// create an associated token account to hold the writer tokens
const writerTokenAccount = new Keypair();
transaction.add(
SystemProgram.createAccount({
fromPubkey: minter.publicKey,
newAccountPubkey: writerTokenAccount.publicKey,
lamports: assetPoolRentBalance,
space: AccountLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
writerTokenMint,
writerTokenAccount.publicKey,
minter.publicKey
)
);
await sendAndConfirmTransaction(
connection,
transaction,
[
minter,
underlyingAccount,
quoteAccount,
optionAccount,
writerTokenAccount,
],
{
commitment: "confirmed",
}
);
// mint underlying tokens to the minter's account
await underlyingToken.mintTo(
underlyingAccount.publicKey,
mintAuthority,
[],
underlyingAmount
);
if (quoteAmount > 0) {
await quoteToken.mintTo(
quoteAccount.publicKey,
mintAuthority,
[],
quoteAmount
);
}
return { optionAccount, quoteAccount, underlyingAccount, writerTokenAccount };
}