@solana/spl-token#getAccount TypeScript Examples

The following examples show how to use @solana/spl-token#getAccount. 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: providers.ts    From amman with Apache License 2.0 6 votes vote down vote up
private async _tryResolveAccountFromBuiltins(address: PublicKey) {
    for (const provider of [getMint, getAccount]) {
      try {
        const account = await provider(this.connection, address, 'singleGossip')
        if (account != null) {
          const ammanAccount = await this._toAmmanAccount(account)
          return {
            account: ammanAccount,
            rendered: undefined,
          }
        }
      } catch (err) {
        logTrace(err)
      }
    }
  }
Example #2
Source File: createTransfer.ts    From solana-pay with Apache License 2.0 6 votes vote down vote up
async function createSPLTokenInstruction(
    recipient: PublicKey,
    amount: BigNumber,
    splToken: PublicKey,
    sender: PublicKey,
    connection: Connection
): Promise<TransactionInstruction> {
    // Check that the token provided is an initialized mint
    const mint = await getMint(connection, splToken);
    if (!mint.isInitialized) throw new CreateTransferError('mint not initialized');

    // Check that the amount provided doesn't have greater precision than the mint
    if (amount.decimalPlaces() > mint.decimals) throw new CreateTransferError('amount decimals invalid');

    // Convert input decimal amount to integer tokens according to the mint decimals
    amount = amount.times(TEN.pow(mint.decimals)).integerValue(BigNumber.ROUND_FLOOR);

    // Get the sender's ATA and check that the account exists and can send tokens
    const senderATA = await getAssociatedTokenAddress(splToken, sender);
    const senderAccount = await getAccount(connection, senderATA);
    if (!senderAccount.isInitialized) throw new CreateTransferError('sender not initialized');
    if (senderAccount.isFrozen) throw new CreateTransferError('sender frozen');

    // Get the recipient's ATA and check that the account exists and can receive tokens
    const recipientATA = await getAssociatedTokenAddress(splToken, recipient);
    const recipientAccount = await getAccount(connection, recipientATA);
    if (!recipientAccount.isInitialized) throw new CreateTransferError('recipient not initialized');
    if (recipientAccount.isFrozen) throw new CreateTransferError('recipient frozen');

    // Check that the sender has enough tokens
    const tokens = BigInt(String(amount));
    if (tokens > senderAccount.amount) throw new CreateTransferError('insufficient funds');

    // Create an instruction to transfer SPL tokens, asserting the mint and decimals match
    return createTransferCheckedInstruction(senderATA, splToken, recipientATA, sender, tokens, mint.decimals);
}
Example #3
Source File: validateTransfer.ts    From octane with Apache License 2.0 5 votes vote down vote up
// Check that a transaction contains a valid transfer to Octane's token account
export async function validateTransfer(
    transaction: Transaction
): Promise<DecodedTransferInstruction | DecodedTransferCheckedInstruction> {
    // Get the first instruction of the transaction
    const [first] = transaction.instructions;
    if (!first) throw new Error('missing instructions');

    // Decode the first instruction and make sure it's a valid SPL Token `Transfer` or `TransferChecked` instruction
    const instruction = decodeInstruction(first);
    if (!(isTransferInstruction(instruction) || isTransferCheckedInstruction(instruction)))
        throw new Error('invalid instruction');

    const {
        keys: { source, destination, owner },
        data: { amount },
    } = instruction;

    // Check that the source account exists, has the correct owner, is not frozen, and has enough funds
    const account = await getAccount(connection, source.pubkey, 'confirmed');
    if (!account.owner.equals(owner.pubkey)) throw new Error('source invalid owner');
    if (account.isFrozen) throw new Error('source frozen');
    if (account.amount < amount) throw new Error('source insufficient balance');

    // Check that the source account's mint is one of the accepted tokens
    const token = tokens[account.mint.toBase58()];
    if (!token) throw new Error('invalid token');

    // Check that the instruction is going to pay the fee
    if (amount < token.fee) throw new Error('invalid amount');

    // Check that the instruction has a valid source account
    if (!source.isWritable) throw new Error('source not writable');
    if (source.isSigner) throw new Error('source is signer');

    // Check that the destination account is Octane's and is valid
    if (!destination.pubkey.equals(token.account)) throw new Error('invalid destination');
    if (!destination.isWritable) throw new Error('destination not writable');
    if (destination.isSigner) throw new Error('destination is signer');

    // Check that the owner of the source account is valid and has signed
    if (!owner.pubkey.equals(transaction.signatures[1].publicKey)) throw new Error('owner missing signature');
    if (owner.isWritable) throw new Error('owner is writable');
    if (!owner.isSigner) throw new Error('owner not signer');

    // If the instruction is a `TransferChecked` instruction, check that the mint and decimals are valid
    if (isTransferCheckedInstruction(instruction)) {
        const {
            keys: { mint },
            data: { decimals },
        } = instruction;

        if (decimals !== token.decimals) throw new Error('invalid decimals');

        if (!mint.pubkey.equals(token.mint)) throw new Error('invalid mint');
        if (mint.isWritable) throw new Error('mint is writable');
        if (mint.isSigner) throw new Error('mint is signer');
    }

    return instruction;
}
Example #4
Source File: solana.tx.ts    From tatum-js with MIT License 5 votes vote down vote up
transferSplToken = async (
  body: TransferSolanaSpl,
  web3: SolanaWeb3,
  provider?: string,
  feePayer?: string,
  feePayerPrivateKey?: string,
) => {
  const connection = web3.getClient(provider)
  const from = new PublicKey(body.from as string)
  const transaction = new Transaction({ feePayer: feePayer ? new PublicKey(feePayer) : from })
  const mint = new PublicKey(body.contractAddress)
  const to = new PublicKey(body.to)

  const fromTokenAddress = await getAssociatedTokenAddress(mint, from)
  const toTokenAccountAddress = await getAssociatedTokenAddress(mint, to)
  try {
    await getAccount(connection, toTokenAccountAddress)
  } catch (e) {
    transaction.add(createAssociatedTokenAccountInstruction(toTokenAccountAddress, from, to, mint))
  }

  transaction.add(
    createTransferInstruction(
      fromTokenAddress,
      toTokenAccountAddress,
      from,
      new BigNumber(body.amount).multipliedBy(10 ** body.digits).toNumber(),
      [],
      TOKEN_PROGRAM_ID,
    ),
  )

  if (body.signatureId) {
    transaction.recentBlockhash = '7WyEshBZcZwEbJsvSeGgCkSNMxxxFAym3x7Cuj6UjAUE'
    return { txData: transaction.compileMessage().serialize().toString('hex') }
  }

  const signers = [web3.generateKeyPair(body.fromPrivateKey)]
  if (feePayerPrivateKey) {
    signers.push(web3.generateKeyPair(feePayerPrivateKey))
  }
  return {
    txId: await connection.sendTransaction(transaction, signers),
  }
}