@solana/spl-token#Token TypeScript Examples

The following examples show how to use @solana/spl-token#Token. 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 zo-client with Apache License 2.0 6 votes vote down vote up
export async function createMintIxs(
  mint: Keypair,
  provider: Provider,
  authority: PublicKey,
  decimals: number,
  freezeAuthority?: PublicKey,
): Promise<TransactionInstruction[]> {
  return [
    SystemProgram.createAccount({
      fromPubkey: provider.wallet.publicKey,
      newAccountPubkey: mint.publicKey,
      space: MintLayout.span,
      lamports: await Token.getMinBalanceRentForExemptMint(provider.connection),
      programId: TOKEN_PROGRAM_ID,
    }),
    Token.createInitMintInstruction(
      TOKEN_PROGRAM_ID,
      mint.publicKey,
      decimals,
      authority,
      freezeAuthority ?? null,
    ),
  ];
}
Example #2
Source File: raydium-wrap-manager.ts    From rubic-app with GNU General Public License v3.0 6 votes vote down vote up
private static async unwrapSol(address: string): Promise<BaseTransaction> {
    const { setupInstructions, owner, signers } =
      SolanaWeb3Public.createBaseSwapInformation(address);
    const toPublicKey = new PublicKey(TOKENS.WSOL.mintAddress);
    const ata = await Token.getAssociatedTokenAddress(
      AT_PROGRAM_ID,
      TOKEN_PROGRAM_ID,
      toPublicKey,
      owner,
      true
    );

    setupInstructions.push(
      closeAccount({
        source: new PublicKey(ata),
        destination: owner,
        owner
      })
    );

    return SolanaWeb3Public.createTransactions(setupInstructions, null, signers);
  }
Example #3
Source File: cli.ts    From protocol-v1 with Apache License 2.0 6 votes vote down vote up
commandWithDefaultOption('deposit')
	.argument('<amount>', 'The amount to deposit')
	.action(async (amount, options: OptionValues) => {
		await wrapActionInUserSubscribeUnsubscribe(
			options,
			async (user: ClearingHouseUser) => {
				log.info(`amount: ${amount}`);
				amount = new BN(amount);

				const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
					ASSOCIATED_TOKEN_PROGRAM_ID,
					TOKEN_PROGRAM_ID,
					user.clearingHouse.getStateAccount().collateralMint,
					user.authority
				);

				await user.clearingHouse.depositCollateral(
					amount,
					associatedTokenPublicKey
				);
			}
		);
	});
Example #4
Source File: internal.spec.ts    From kin-node with MIT License 6 votes vote down vote up
test('submitTransaction rejected', async () => {
    const env = newTestEnv();
    const [client, txClientV4] = [env.client, env.txClientV4];
    const [sender, destination] = [PrivateKey.random().publicKey(), PrivateKey.random().publicKey()];

    const transaction = new SolanaTransaction({
        feePayer: sender.solanaKey(),
        recentBlockhash: new PublicKey(recentBlockhash).toBase58(),
    }).add(
        Token.createTransferInstruction(
            TOKEN_PROGRAM_ID,
            sender.solanaKey(),
            destination.solanaKey(),
            sender.solanaKey(),
            [],
            100,
        )
    );

    when(txClientV4.submitTransaction(anything(), anything(), anything()))
        .thenCall((_, __, callback) => {
            const resp = new transactionpbv4.SubmitTransactionResponse();
            resp.setResult(transactionpbv4.SubmitTransactionResponse.Result.REJECTED);

            callback(undefined, resp);
        });

    try {
        await client.submitTransaction(transaction);
        fail();
    } catch (err) {
        expect(err).toBeInstanceOf(TransactionRejected);
    }
});
Example #5
Source File: various.ts    From metaplex with Apache License 2.0 6 votes vote down vote up
getPriceWithMantissa = async (
  price: number,
  mint: web3.PublicKey,
  walletKeyPair: any,
  anchorProgram: Program,
): Promise<number> => {
  const token = new Token(
    anchorProgram.provider.connection,
    new web3.PublicKey(mint),
    TOKEN_PROGRAM_ID,
    walletKeyPair,
  );

  const mintInfo = await token.getMintInfo();

  const mantissa = 10 ** mintInfo.decimals;

  return Math.ceil(price * mantissa);
}
Example #6
Source File: initializeMarket.ts    From psyoptions with Apache License 2.0 6 votes vote down vote up
getOrAddAssociatedTokenAccountTx = async (
  associatedAddress: PublicKey,
  token: Token,
  payer: PublicKey,
  owner: PublicKey = FEE_OWNER_KEY,
) => {
  // This is the optimum logic, considering TX fee, client-side computation,
  // RPC roundtrips and guaranteed idempotent.
  // Sadly we can't do this atomically;
  try {
    await token.getAccountInfo(associatedAddress);
    return null;
  } catch (err) {
    // INVALID_ACCOUNT_OWNER can be possible if the associatedAddress has
    // already been received some lamports (= became system accounts).
    // Assuming program derived addressing is safe, this is the only case
    // for the INVALID_ACCOUNT_OWNER in this code-path
    if (
      err.message === 'Failed to find account' ||
      err.message === 'Invalid account owner'
    ) {
      // as this isn't atomic, it's possible others can create associated
      // accounts meanwhile
      return Token.createAssociatedTokenAccountInstruction(
        ASSOCIATED_TOKEN_PROGRAM_ID,
        TOKEN_PROGRAM_ID,
        token.publicKey,
        associatedAddress,
        owner,
        payer,
      );
    } else {
      throw err;
    }
  }
}
Example #7
Source File: pools.ts    From serum-ts with Apache License 2.0 6 votes vote down vote up
approveTransfer = (
  instructions: TransactionInstruction[],
  cleanupInstructions: TransactionInstruction[],
  account: PublicKey,
  owner: PublicKey,
  amount: number,

  // if delegate is not passed ephemeral transfer authority is used
  delegate?: PublicKey,
) => {
  const transferAuthority = new Account();
  instructions.push(
    Token.createApproveInstruction(
      TOKEN_PROGRAM_ID,
      account,
      delegate ?? transferAuthority.publicKey,
      owner,
      [],
      amount,
    ),
  );

  cleanupInstructions.push(
    Token.createRevokeInstruction(TOKEN_PROGRAM_ID, account, owner, []),
  );

  return transferAuthority;
}
Example #8
Source File: Swap.tsx    From swap-ui with Apache License 2.0 6 votes vote down vote up
function unwrapSol(
  provider: Provider,
  wrappedSolAccount: Keypair
): { tx: Transaction; signers: Array<Signer | undefined> } {
  const tx = new Transaction();
  tx.add(
    Token.createCloseAccountInstruction(
      TOKEN_PROGRAM_ID,
      wrappedSolAccount.publicKey,
      provider.wallet.publicKey,
      provider.wallet.publicKey,
      []
    )
  );
  return { tx, signers: [] };
}
Example #9
Source File: helpers.ts    From sdk with MIT License 6 votes vote down vote up
export async function getPriceWithMantissa(
	price: number,
	mint: PublicKey,
	walletKeyPair: any,
	anchorProgram: Program,
): Promise<number> {
	const token = new Token(
		anchorProgram.provider.connection,
		new PublicKey(mint),
		TOKEN_PROGRAM_ID,
		walletKeyPair,
	)

	const mintInfo = await token.getMintInfo()

	const mantissa = 10 ** mintInfo.decimals

	return Math.ceil(price * mantissa)
}
Example #10
Source File: web3.ts    From raydium-ui with GNU General Public License v3.0 6 votes vote down vote up
export async function createAssociatedTokenAccountIfNotExist(
  account: string | undefined | null,
  owner: PublicKey,
  mintAddress: string,

  transaction: Transaction,
  atas: string[] = []
) {
  let publicKey
  if (account) {
    publicKey = new PublicKey(account)
  }

  const mint = new PublicKey(mintAddress)
  // @ts-ignore without ts ignore, yarn build will failed
  const ata = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, owner, true)

  if ((!publicKey || !ata.equals(publicKey)) && !atas.includes(ata.toBase58())) {
    transaction.add(
      Token.createAssociatedTokenAccountInstruction(
        ASSOCIATED_TOKEN_PROGRAM_ID,
        TOKEN_PROGRAM_ID,
        mint,
        ata,
        owner,
        owner
      )
    )
    atas.push(ata.toBase58())
  }

  return ata
}
Example #11
Source File: associated-token-account.ts    From easy-spl with Apache License 2.0 6 votes vote down vote up
createAssociatedTokenAccountRawInstructions = (
  mint: web3.PublicKey,
  address: web3.PublicKey,
  owner: web3.PublicKey,
  sender: web3.PublicKey,
): web3.TransactionInstruction[] => {
  return [Token.createAssociatedTokenAccountInstruction(
    ASSOCIATED_TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    mint,
    address,
    owner,
    sender
  )]
}
Example #12
Source File: index.ts    From zo-client with Apache License 2.0 5 votes vote down vote up
export async function getWrappedSolInstructionsAndKey(
  initialSmollAmount,
  provider,
): Promise<{
  createTokenAccountIx: TransactionInstruction;
  initTokenAccountIx: TransactionInstruction;
  closeTokenAccountIx: TransactionInstruction;
  intermediary: PublicKey;
  intermediaryKeypair: Keypair;
}> {
  // sol wrapping code taken from jet: https://github.com/jet-lab/jet-v1/blob/30c56d5c14b68685466164fc45c96080f1d9348a/app/src/scripts/jet.ts
  const intermediaryKeypair = Keypair.generate();
  const intermediary = intermediaryKeypair.publicKey;

  const rent = await provider.connection.getMinimumBalanceForRentExemption(
    TokenAccountLayout.span,
  );
  const createTokenAccountIx = SystemProgram.createAccount({
    fromPubkey: provider.wallet.publicKey,
    newAccountPubkey: intermediary,
    programId: TOKEN_PROGRAM_ID,
    space: TokenAccountLayout.span,
    lamports: parseInt(initialSmollAmount.addn(rent).toString()),
  });

  const initTokenAccountIx = Token.createInitAccountInstruction(
    TOKEN_PROGRAM_ID,
    WRAPPED_SOL_MINT,
    intermediary,
    provider.wallet.publicKey,
  );

  const closeTokenAccountIx = Token.createCloseAccountInstruction(
    TOKEN_PROGRAM_ID,
    intermediary,
    provider.wallet.publicKey,
    provider.wallet.publicKey,
    [],
  );

  return {
    createTokenAccountIx,
    initTokenAccountIx,
    closeTokenAccountIx,
    intermediary,
    intermediaryKeypair,
  };
}
Example #13
Source File: solana-web3-private.service.ts    From rubic-app with GNU General Public License v3.0 5 votes vote down vote up
/**
   * Create the associated token account if not exists.
   * @param account Accounts to check existence.
   * @param owner Owner account.
   * @param mintAddress Token mint address.
   * @param instructions The token creation instructions.
   * @param atas Associated token accounts.
   */
  public async createAssociatedTokenAccountIfNotExist(
    owner: PublicKey,
    mintAddress: string,
    instructions: TransactionInstruction[],
    atas: string[] = []
  ): Promise<PublicKey> {
    const mint = new PublicKey(mintAddress);

    const ata = await Token.getAssociatedTokenAddress(
      AT_PROGRAM_ID,
      TOKEN_PROGRAM_ID,
      mint,
      owner,
      true
    );
    const accountInfo = await this._connection.getAccountInfo(ata);

    if (!accountInfo) {
      instructions.push(
        Token.createAssociatedTokenAccountInstruction(
          AT_PROGRAM_ID,
          TOKEN_PROGRAM_ID,
          mint,
          ata,
          owner,
          owner
        )
      );
      atas.push(ata.toBase58());
    }

    return ata;
  }
Example #14
Source File: clearingHouse.ts    From protocol-v1 with Apache License 2.0 5 votes vote down vote up
async getInitializeUserInstructions(): Promise<
		[Keypair, PublicKey, TransactionInstruction, TransactionInstruction]
	> {
		const [userAccountPublicKey, userAccountNonce] =
			await getUserAccountPublicKeyAndNonce(
				this.program.programId,
				this.wallet.publicKey
			);

		const remainingAccounts = [];
		const optionalAccounts = {
			whitelistToken: false,
		};

		const state = this.getStateAccount();
		if (state.whitelistMint) {
			optionalAccounts.whitelistToken = true;
			const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
				ASSOCIATED_TOKEN_PROGRAM_ID,
				TOKEN_PROGRAM_ID,
				state.whitelistMint,
				this.wallet.publicKey
			);
			remainingAccounts.push({
				pubkey: associatedTokenPublicKey,
				isWritable: false,
				isSigner: false,
			});
		}

		const userPositions = new Keypair();
		const initializeUserAccountIx =
			await this.program.instruction.initializeUser(
				userAccountNonce,
				optionalAccounts,
				{
					accounts: {
						user: userAccountPublicKey,
						authority: this.wallet.publicKey,
						rent: anchor.web3.SYSVAR_RENT_PUBKEY,
						systemProgram: anchor.web3.SystemProgram.programId,
						userPositions: userPositions.publicKey,
						state: await this.getStatePublicKey(),
					},
					remainingAccounts: remainingAccounts,
				}
			);

		const initializeUserOrdersAccountIx =
			await this.getInitializeUserOrdersInstruction(userAccountPublicKey);

		return [
			userPositions,
			userAccountPublicKey,
			initializeUserAccountIx,
			initializeUserOrdersAccountIx,
		];
	}
Example #15
Source File: client.ts    From kin-node with MIT License 5 votes vote down vote up
private async submitPaymentTx(
        payment: Payment, config: transactionpbv4.GetServiceConfigResponse, commitment: Commitment, transferSender?: PublicKey,
        createInstructions?: TransactionInstruction[], createSigner?: PrivateKey,
    ): Promise<SubmitTransactionResult> {
        let subsidizerKey: SolanaPublicKey;
        let signers: PrivateKey[];
        if (payment.subsidizer) {
            subsidizerKey = payment.subsidizer!.publicKey().solanaKey();
            signers = [payment.subsidizer, payment.sender];
        } else {
            subsidizerKey = new SolanaPublicKey(Buffer.from(config.getSubsidizerAccount()!.getValue_asU8()));
            signers = [payment.sender];
        }

        if (createSigner) {
            signers.push(createSigner);
        }
        
        const instructions = [];
        let invoiceList: commonpb.InvoiceList | undefined = undefined;
        
        if (payment.memo) {
            instructions.push(MemoProgram.memo({data: payment.memo}));
        } else if (this.appIndex) {
            let fk = Buffer.alloc(29);

            if (payment.invoice) {
                invoiceList = new commonpb.InvoiceList();
                invoiceList.addInvoices(invoiceToProto(payment.invoice));

                const serialized = invoiceList.serializeBinary();
                fk = Buffer.from(hash.sha224().update(serialized).digest('hex'), "hex");
            }

            const kinMemo = KinMemo.new(1, payment.type, this.appIndex!, fk);
            instructions.push(MemoProgram.memo({data: kinMemo.buffer.toString("base64")}));
        }

        if (createInstructions) {
            instructions.push(...createInstructions);
        }
        
        let sender: PublicKey;
        if (transferSender) {
            sender = transferSender;
        } else {
            sender = payment.sender.publicKey();
        }

        instructions.push(Token.createTransferInstruction(
            TOKEN_PROGRAM_ID,
            sender.solanaKey(),
            payment.destination.solanaKey(),
            payment.sender.publicKey().solanaKey(),
            [],
            bigNumberToU64(payment.quarks)
        ));

        const tx = new Transaction({
            feePayer: subsidizerKey,
        }).add(...instructions);

        return this.signAndSubmitTx(signers, tx, commitment, invoiceList, payment.dedupeId);
    }
Example #16
Source File: candy-machine.ts    From metaplex with Apache License 2.0 5 votes vote down vote up
createAccountsForMint = async (
  candyMachine: CandyMachineAccount,
  payer: anchor.web3.PublicKey,
): Promise<SetupState> => {
  const mint = anchor.web3.Keypair.generate();
  const userTokenAccountAddress = (
    await getAtaForMint(mint.publicKey, payer)
  )[0];

  const signers: anchor.web3.Keypair[] = [mint];
  const instructions = [
    anchor.web3.SystemProgram.createAccount({
      fromPubkey: payer,
      newAccountPubkey: mint.publicKey,
      space: MintLayout.span,
      lamports:
        await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
          MintLayout.span,
        ),
      programId: TOKEN_PROGRAM_ID,
    }),
    Token.createInitMintInstruction(
      TOKEN_PROGRAM_ID,
      mint.publicKey,
      0,
      payer,
      payer,
    ),
    createAssociatedTokenAccountInstruction(
      userTokenAccountAddress,
      payer,
      payer,
      mint.publicKey,
    ),
    Token.createMintToInstruction(
      TOKEN_PROGRAM_ID,
      mint.publicKey,
      userTokenAccountAddress,
      payer,
      [],
      1,
    ),
  ];

  return {
    mint: mint,
    userTokenAccount: userTokenAccountAddress,
    transaction: (
      await sendTransactions(
        candyMachine.program.provider.connection,
        candyMachine.program.provider.wallet,
        [instructions],
        [signers],
        SequenceType.StopOnFailure,
        'singleGossip',
        () => {},
        () => false,
        undefined,
        [],
        [],
      )
    ).txs[0].txid,
  };
}
Example #17
Source File: mintOption.ts    From psyoptions with Apache License 2.0 5 votes vote down vote up
mintOptionsTx = async (
  program: Program<PsyAmerican>,
  minter: Keypair,
  minterOptionAcct: Keypair,
  minterWriterAcct: Keypair,
  minterUnderlyingAccount: Keypair,
  size: anchor.BN,
  optionMarket: OptionMarketV2,
) => {
  let mintFeeKey: PublicKey,
    remainingAccounts: AccountMeta[] = [];
  const mintFee = feeAmountPerContract(
    optionMarket.underlyingAmountPerContract,
  );
  if (mintFee.gtn(0)) {
    mintFeeKey = await Token.getAssociatedTokenAddress(
      ASSOCIATED_TOKEN_PROGRAM_ID,
      TOKEN_PROGRAM_ID,
      optionMarket.underlyingAssetMint,
      FEE_OWNER_KEY,
    );
    remainingAccounts.push({
      pubkey: mintFeeKey,
      isWritable: true,
      isSigner: false,
    });
  }
  await program.rpc.mintOption(size, {
    accounts: {
      userAuthority: minter.publicKey,
      underlyingAssetMint: optionMarket.underlyingAssetMint,
      underlyingAssetPool: optionMarket.underlyingAssetPool,
      underlyingAssetSrc: minterUnderlyingAccount.publicKey,
      optionMint: optionMarket.optionMint,
      mintedOptionDest: minterOptionAcct.publicKey,
      writerTokenMint: optionMarket.writerTokenMint,
      mintedWriterTokenDest: minterWriterAcct.publicKey,
      optionMarket: optionMarket.key,
      feeOwner: FEE_OWNER_KEY,
      tokenProgram: TOKEN_PROGRAM_ID,
      associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
      clock: SYSVAR_CLOCK_PUBKEY,
      rent: SYSVAR_RENT_PUBKEY,
      systemProgram: SystemProgram.programId,
    },
    remainingAccounts,
    signers: [minter],
  });
}
Example #18
Source File: pools.ts    From serum-ts with Apache License 2.0 5 votes vote down vote up
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 #19
Source File: Swap.tsx    From swap-ui with Apache License 2.0 5 votes vote down vote up
async function wrapSol(
  provider: Provider,
  wrappedSolAccount: Keypair,
  fromMint: PublicKey,
  amount: BN
): Promise<{ tx: Transaction; signers: Array<Signer | undefined> }> {
  const tx = new Transaction();
  const signers = [wrappedSolAccount];
  // Create new, rent exempt account.
  tx.add(
    SystemProgram.createAccount({
      fromPubkey: provider.wallet.publicKey,
      newAccountPubkey: wrappedSolAccount.publicKey,
      lamports: await Token.getMinBalanceRentForExemptAccount(
        provider.connection
      ),
      space: 165,
      programId: TOKEN_PROGRAM_ID,
    })
  );
  // Transfer lamports. These will be converted to an SPL balance by the
  // token program.
  if (fromMint.equals(SOL_MINT)) {
    tx.add(
      SystemProgram.transfer({
        fromPubkey: provider.wallet.publicKey,
        toPubkey: wrappedSolAccount.publicKey,
        lamports: amount.toNumber(),
      })
    );
  }
  // Initialize the account.
  tx.add(
    Token.createInitAccountInstruction(
      TOKEN_PROGRAM_ID,
      WRAPPED_SOL_MINT,
      wrappedSolAccount.publicKey,
      provider.wallet.publicKey
    )
  );
  return { tx, signers };
}
Example #20
Source File: migrate.ts    From raydium-ui with GNU General Public License v3.0 5 votes vote down vote up
// interface Farms {
//   farmInfo: FarmInfo | undefined | null
//   lpAccount: string | undefined | null
//   rewardAccount: string | undefined | null
//   infoAccount: string | undefined | null
//   amount: TokenAmount
// }

export async function mergeTokens(
  connection: Connection | undefined | null,
  wallet: any | undefined | null,
  auxiliaryTokenAccounts: Array<{ pubkey: PublicKey; account: AccountInfo<ParsedAccountData> }>,
  tokenAccounts: any
) {
  if (!connection || !wallet) throw new Error('Miss connection')
  if (!auxiliaryTokenAccounts || auxiliaryTokenAccounts.length === 0)
    throw new Error('Miss auxiliary accounts infomations')

  const owner = wallet.publicKey

  const { blockhash } = await connection.getRecentBlockhash()
  const transaction = new Transaction({ recentBlockhash: blockhash, feePayer: owner })
  const signers: any = []

  const atas: string[] = []

  for (let index = 0; index < auxiliaryTokenAccounts.length; index++) {
    if (index > 0) {
      try {
        const data = transaction.compileMessage().serialize()
        // 1280 - 40 - 8 - 64 - 1 - 256
        if (data.length > 911) {
          break
        }
      } catch {
        break
      }
    }

    const auxiliaryTokenAccount = auxiliaryTokenAccounts[index]

    const { pubkey: from, account: accountInfo } = auxiliaryTokenAccount
    const { info } = accountInfo.data.parsed
    const { mint, tokenAmount } = info

    const mintPubkey = new PublicKey(mint)

    const ata = await findAssociatedTokenAddress(owner, mintPubkey)
    const ataAccountInfo = get(tokenAccounts, mint)

    if (!ataAccountInfo && !atas.includes(ata.toBase58())) {
      transaction.add(
        Token.createAssociatedTokenAccountInstruction(
          ASSOCIATED_TOKEN_PROGRAM_ID,
          TOKEN_PROGRAM_ID,
          mintPubkey,
          ata,
          owner,
          owner
        )
      )
      atas.push(ata.toBase58())
    }

    const { amount } = tokenAmount
    transaction.add(Token.createTransferInstruction(TOKEN_PROGRAM_ID, from, ata, owner, [], new U64(amount)))
  }

  return await sendTransaction(connection, wallet, transaction, signers)
}
Example #21
Source File: associated-token-account.ts    From easy-spl with Apache License 2.0 5 votes vote down vote up
getAssociatedTokenAddress = async (
  mint: web3.PublicKey,
  user: web3.PublicKey
): Promise<web3.PublicKey> => {
  return Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, user)
}
Example #22
Source File: mint.ts    From candy-machine-v2 with MIT License 4 votes vote down vote up
mintOneToken = async (
  candyMachine: CandyMachineAccount,
  payer: anchor.web3.PublicKey,
  mint: anchor.web3.Keypair
): Promise<(string | undefined)[]> => {
  // const mint = anchor.web3.Keypair.generate();
  console.log(mint.publicKey);
  const userTokenAccountAddress = (
    await getAtaForMint(mint.publicKey, payer)
  )[0];

  const userPayingAccountAddress = candyMachine.state.tokenMint
    ? (await getAtaForMint(candyMachine.state.tokenMint, payer))[0]
    : payer;

  const candyMachineAddress = candyMachine.id;
  const remainingAccounts = [];
  const signers: anchor.web3.Keypair[] = [mint];
  const cleanupInstructions = [];
  const metadataAddress = await getMetadata(mint.publicKey);
  const masterEdition = await getMasterEdition(mint.publicKey);
  const [candyMachineCreator, creatorBump] = await getCandyMachineCreator(
    candyMachineAddress
  );
  const instructions = [
    anchor.web3.SystemProgram.createAccount({
      fromPubkey: payer,
      newAccountPubkey: mint.publicKey,
      space: MintLayout.span,
      lamports:
        await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
          MintLayout.span
        ),
      programId: TOKEN_PROGRAM_ID,
    }),
    Token.createInitMintInstruction(
      TOKEN_PROGRAM_ID,
      mint.publicKey,
      0,
      payer,
      payer
    ),
    createAssociatedTokenAccountInstruction(
      userTokenAccountAddress,
      payer,
      payer,
      mint.publicKey
    ),
    Token.createMintToInstruction(
      TOKEN_PROGRAM_ID,
      mint.publicKey,
      userTokenAccountAddress,
      payer,
      [],
      1
    ),
  ];

  if (candyMachine.state.whitelistMintSettings) {
    const mint = new anchor.web3.PublicKey(
      candyMachine.state.whitelistMintSettings.mint
    );

    const whitelistToken = (await getAtaForMint(mint, payer))[0];
    remainingAccounts.push({
      pubkey: whitelistToken,
      isWritable: true,
      isSigner: false,
    });

    if (candyMachine.state.whitelistMintSettings.mode.burnEveryTime) {
      const whitelistBurnAuthority = anchor.web3.Keypair.generate();

      remainingAccounts.push({
        pubkey: mint,
        isWritable: true,
        isSigner: false,
      });
      remainingAccounts.push({
        pubkey: whitelistBurnAuthority.publicKey,
        isWritable: false,
        isSigner: true,
      });
      signers.push(whitelistBurnAuthority);
      const exists =
        await candyMachine.program.provider.connection.getAccountInfo(
          whitelistToken
        );
      if (exists) {
        instructions.push(
          Token.createApproveInstruction(
            TOKEN_PROGRAM_ID,
            whitelistToken,
            whitelistBurnAuthority.publicKey,
            payer,
            [],
            1
          )
        );
        cleanupInstructions.push(
          Token.createRevokeInstruction(
            TOKEN_PROGRAM_ID,
            whitelistToken,
            payer,
            []
          )
        );
      }
    }
  }
  if (candyMachine.state.tokenMint) {
    const transferAuthority = anchor.web3.Keypair.generate();

    signers.push(transferAuthority);
    remainingAccounts.push({
      pubkey: userPayingAccountAddress,
      isWritable: true,
      isSigner: false,
    });
    remainingAccounts.push({
      pubkey: transferAuthority.publicKey,
      isWritable: false,
      isSigner: true,
    });

    instructions.push(
      Token.createApproveInstruction(
        TOKEN_PROGRAM_ID,
        userPayingAccountAddress,
        transferAuthority.publicKey,
        payer,
        [],
        candyMachine.state.price.toNumber()
      )
    );
    cleanupInstructions.push(
      Token.createRevokeInstruction(
        TOKEN_PROGRAM_ID,
        userPayingAccountAddress,
        payer,
        []
      )
    );
  }
  instructions.push(
    await candyMachine.program.instruction.mintNft(creatorBump, {
      accounts: {
        candyMachine: candyMachineAddress,
        candyMachineCreator,
        payer: payer,
        wallet: candyMachine.state.treasury,
        mint: mint.publicKey,
        metadata: metadataAddress,
        masterEdition,
        mintAuthority: payer,
        updateAuthority: payer,
        tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
        tokenProgram: TOKEN_PROGRAM_ID,
        systemProgram: SystemProgram.programId,
        rent: anchor.web3.SYSVAR_RENT_PUBKEY,
        clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
        recentBlockhashes: anchor.web3.SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
        instructionSysvarAccount: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
      },
      remainingAccounts:
        remainingAccounts.length > 0 ? remainingAccounts : undefined,
    })
  );

  try {
    return (
      await sendTransactions(
        candyMachine.program.provider.connection,
        candyMachine.program.provider.wallet,
        [instructions, cleanupInstructions],
        [signers, []]
      )
    ).txs.map((t) => t.txid);
  } catch (e) {
    console.log(e);
  }

  return [];
}
Example #23
Source File: fees.ts    From protocol-v1 with Apache License 2.0 4 votes vote down vote up
describe('fees', () => {
	const provider = anchor.AnchorProvider.local(undefined, {
		preflightCommitment: 'confirmed',
		commitment: 'confirmed',
	});
	const connection = provider.connection;
	anchor.setProvider(provider);
	const chProgram = anchor.workspace.ClearingHouse as Program;

	let clearingHouse: Admin;
	let referrerClearingHouse: ClearingHouse;

	let userAccountPublicKey: PublicKey;

	let usdcMint;
	let userUSDCAccount;

	// ammInvariant == k == x * y
	const mantissaSqrtScale = new BN(Math.sqrt(MARK_PRICE_PRECISION.toNumber()));
	const ammInitialQuoteAssetReserve = new anchor.BN(5 * 10 ** 13).mul(
		mantissaSqrtScale
	);
	const ammInitialBaseAssetReserve = new anchor.BN(5 * 10 ** 13).mul(
		mantissaSqrtScale
	);

	const usdcAmount = new BN(10 * 10 ** 6);

	let discountMint: Token;
	let discountTokenAccount: AccountInfo;

	const referrerKeyPair = new Keypair();
	let referrerUSDCAccount: Keypair;
	let referrerUserAccountPublicKey: PublicKey;

	before(async () => {
		usdcMint = await mockUSDCMint(provider);
		userUSDCAccount = await mockUserUSDCAccount(usdcMint, usdcAmount, provider);

		clearingHouse = Admin.from(
			connection,
			provider.wallet,
			chProgram.programId,
			{
				commitment: 'confirmed',
			}
		);
		await clearingHouse.initialize(usdcMint.publicKey, true);
		await clearingHouse.subscribe();

		const solUsd = await mockOracle(1);
		const periodicity = new BN(60 * 60); // 1 HOUR

		await clearingHouse.initializeMarket(
			Markets[0].marketIndex,
			solUsd,
			ammInitialBaseAssetReserve,
			ammInitialQuoteAssetReserve,
			periodicity
		);

		[, userAccountPublicKey] =
			await clearingHouse.initializeUserAccountAndDepositCollateral(
				usdcAmount,
				userUSDCAccount.publicKey
			);

		discountMint = await Token.createMint(
			connection,
			// @ts-ignore
			provider.wallet.payer,
			provider.wallet.publicKey,
			provider.wallet.publicKey,
			6,
			TOKEN_PROGRAM_ID
		);

		await clearingHouse.updateDiscountMint(discountMint.publicKey);

		discountTokenAccount = await discountMint.getOrCreateAssociatedAccountInfo(
			provider.wallet.publicKey
		);

		provider.connection.requestAirdrop(referrerKeyPair.publicKey, 10 ** 9);
		referrerUSDCAccount = await mockUserUSDCAccount(
			usdcMint,
			usdcAmount,
			provider,
			referrerKeyPair.publicKey
		);
		referrerClearingHouse = ClearingHouse.from(
			connection,
			new Wallet(referrerKeyPair),
			chProgram.programId
		);
		await referrerClearingHouse.subscribe();

		[, referrerUserAccountPublicKey] =
			await referrerClearingHouse.initializeUserAccountAndDepositCollateral(
				usdcAmount,
				referrerUSDCAccount.publicKey
			);
	});

	after(async () => {
		await clearingHouse.unsubscribe();
		await referrerClearingHouse.unsubscribe();
	});

	it('Trade no rebate', async () => {
		const marketIndex = new BN(0);
		await clearingHouse.openPosition(
			PositionDirection.LONG,
			usdcAmount,
			marketIndex,
			new BN(0),
			discountTokenAccount.address
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9990000)));
		assert(user.totalFeePaid.eq(new BN(10000)));
		assert(user.totalTokenDiscount.eq(new BN(0)));
		assert(user.totalRefereeDiscount.eq(new BN(0)));
	});

	it('Trade fourth tier rebate', async () => {
		await discountMint.mintTo(
			discountTokenAccount.address,
			// @ts-ignore
			provider.wallet.payer,
			[],
			1000 * 10 ** 6
		);

		const marketIndex = new BN(0);
		await clearingHouse.openPosition(
			PositionDirection.LONG,
			usdcAmount,
			marketIndex,
			new BN(0),
			discountTokenAccount.address,
			referrerUserAccountPublicKey
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9981000)));
		assert(user.totalFeePaid.eq(new BN(19000)));
		assert(user.totalTokenDiscount.eq(new BN(500)));
		assert(user.totalRefereeDiscount.eq(new BN(500)));

		const referrer: any = await clearingHouse.program.account.user.fetch(
			referrerUserAccountPublicKey
		);

		assert(referrer.totalReferralReward.eq(new BN(500)));
	});

	it('Trade third tier rebate', async () => {
		await discountMint.mintTo(
			discountTokenAccount.address,
			// @ts-ignore
			provider.wallet.payer,
			[],
			10000 * 10 ** 6
		);

		const marketIndex = new BN(0);
		await clearingHouse.openPosition(
			PositionDirection.LONG,
			usdcAmount,
			marketIndex,
			new BN(0),
			discountTokenAccount.address,
			referrerUserAccountPublicKey
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9972500)));
		assert(user.totalFeePaid.eq(new BN(27500)));
		assert(user.totalTokenDiscount.eq(new BN(1500)));
		assert(user.totalRefereeDiscount.eq(new BN(1000)));

		const referrer: any = await clearingHouse.program.account.user.fetch(
			referrerUserAccountPublicKey
		);

		assert(referrer.totalReferralReward.eq(new BN(1000)));
	});

	it('Trade second tier rebate', async () => {
		await discountMint.mintTo(
			discountTokenAccount.address,
			// @ts-ignore
			provider.wallet.payer,
			[],
			100000 * 10 ** 6
		);

		const marketIndex = new BN(0);
		await clearingHouse.openPosition(
			PositionDirection.LONG,
			usdcAmount,
			marketIndex,
			new BN(0),
			discountTokenAccount.address,
			referrerUserAccountPublicKey
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9964500)));
		assert(user.totalFeePaid.eq(new BN(35500)));
		assert(user.totalTokenDiscount.eq(new BN(3000)));
		assert(user.totalRefereeDiscount.eq(new BN(1500)));

		const referrer: any = await clearingHouse.program.account.user.fetch(
			referrerUserAccountPublicKey
		);

		assert(referrer.totalReferralReward.eq(new BN(1500)));
	});

	it('Trade first tier rebate', async () => {
		await discountMint.mintTo(
			discountTokenAccount.address,
			// @ts-ignore
			provider.wallet.payer,
			[],
			1000000 * 10 ** 6
		);

		const marketIndex = new BN(0);
		await clearingHouse.openPosition(
			PositionDirection.LONG,
			usdcAmount.mul(new BN(9)).div(new BN(10)),
			marketIndex,
			new BN(0),
			discountTokenAccount.address,
			referrerUserAccountPublicKey
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9957750)));
		assert(user.totalFeePaid.eq(new BN(42250)));
		assert(user.totalTokenDiscount.eq(new BN(4800)));
		assert(user.totalRefereeDiscount.eq(new BN(1950)));

		const referrer: any = await clearingHouse.program.account.user.fetch(
			referrerUserAccountPublicKey
		);

		assert(referrer.totalReferralReward.eq(new BN(1950)));
	});

	it('Close position', async () => {
		const marketIndex = new BN(0);
		await clearingHouse.closePosition(
			marketIndex,
			discountTokenAccount.address,
			referrerUserAccountPublicKey
		);

		const user: any = await clearingHouse.program.account.user.fetch(
			userAccountPublicKey
		);

		assert(user.collateral.eq(new BN(9921000)));
		assert(user.totalFeePaid.eq(new BN(79000)));
		assert(user.totalTokenDiscount.eq(new BN(14600)));
		assert(user.totalRefereeDiscount.eq(new BN(4400)));

		const referrer: any = await clearingHouse.program.account.user.fetch(
			referrerUserAccountPublicKey
		);

		assert(referrer.totalReferralReward.eq(new BN(4400)));
	});
});