Token

Apa yang saya perlukan untuk memulai dengan SPL-Tokens?

Setiap kali anda berinteraksi dengan tokens di Solana, anda sebenarnya berinteraksi dengan Solana Program Library Token, atau SPL-Token standard. SPL-Token standard mensyaratkan sebuah library spesifik untuk digunakan, yang anda dapat temukan dibawah ini berdasarkan bahasa anda.

"@solana/spl-token": "^0.2.0"

Bagaimana cara untuk membuat sebuah Token baru

Membuat token-token didapat dengan menciptakan apa yang disebut dengan sebuah "akun mint". Akun mint ini nantinya akan digunakan untuk me-mint token-token ke sebuah akun token dan membuat supply awal.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  Keypair,
  Transaction,
  SystemProgram,
} from "@solana/web3.js";
import {
  createInitializeMintInstruction,
  TOKEN_PROGRAM_ID,
  MINT_SIZE,
  getMinimumBalanceForRentExemptMint,
  createMint,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  // 1) use build-in function
  let mintPubkey = await createMint(
    connection, // conneciton
    feePayer, // fee payer
    alice.publicKey, // mint authority
    alice.publicKey, // freeze authority (you can use `null` to disable it. when you disable it, you can't turn it on again)
    8 // decimals
  );
  console.log(`mint: ${mintPubkey.toBase58()}`);

  // or

  // 2) compose by yourself
  const mint = Keypair.generate();
  console.log(`mint: ${mint.publicKey.toBase58()}`);

  let tx = new Transaction().add(
    // create mint account
    SystemProgram.createAccount({
      fromPubkey: feePayer.publicKey,
      newAccountPubkey: mint.publicKey,
      space: MINT_SIZE,
      lamports: await getMinimumBalanceForRentExemptMint(connection),
      programId: TOKEN_PROGRAM_ID,
    }),
    // init mint account
    createInitializeMintInstruction(
      mint.publicKey, // mint pubkey
      8, // decimals
      alice.publicKey, // mint authority
      alice.publicKey // freeze authority (you can use `null` to disable it. when you disable it, you can't turn it on again)
    )
  );
  console.log(
    `txhash: ${await connection.sendTransaction(tx, [feePayer, mint])}`
  );
})();

Bagaimana cara mendapatkan sebuah token mint

Untuk mendapatkan supply yang berjalan, authority, atau decimals yang dimliki sebuah token, anda perlu mendapatkan account info untuk me-mint token.

Press </> button to view full source
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { getMint } from "@solana/spl-token";

(async () => {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  const mintAccountPublicKey = new PublicKey("8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV");

  let mintAccount = await getMint(connection, mintAccountPublicKey);

  console.log(mintAccount);
  /*
  {
    address: PublicKey {
      _bn: <BN: 7351e5e067cc7cfefef42e78915d3c513edbb8adeeab4d9092e814fe68c39fec>
    },
    mintAuthority: PublicKey {
      _bn: <BN: df30e6ca0981c1a677eed6f7cb46b2aa442ca9b7a10a10e494badea4b9b6944f>
    },
    supply: 0n,
    decimals: 8,
    isInitialized: true,
    freezeAuthority: PublicKey {
      _bn: <BN: df30e6ca0981c1a677eed6f7cb46b2aa442ca9b7a10a10e494badea4b9b6944f>
    }
  }
  */
})();

Bagaimana cara membuat sebuah akun token

Sebuah akun token diperlukan untuk menampung token-token. Setiap token mint mempunyai sebuah akun token berbeda yang diasosiasikan dengannya.

Associated Token Accounts secara deterministik membuat akun-akun untuk setiap keypair. ATA adalah method yang direkomendasi untuk mengature akun-akun token.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
  SystemProgram,
} from "@solana/web3.js";
import {
  createAssociatedTokenAccount,
  getAssociatedTokenAddress,
  createAssociatedTokenAccountInstruction,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const mintPubkey = new PublicKey(
    "2SKpuBU9ksneBZD4nqbZkw75NE11HsSHsGRtW2BZh5aQ"
  );

  // 1) use build-in function
  {
    let ata = await createAssociatedTokenAccount(
      connection, // connection
      feePayer, // fee payer
      mintPubkey, // mint
      alice.publicKey // owner,
    );
    console.log(`ATA: ${ata.toBase58()}`);
  }

  // or

  // 2) composed by yourself
  {
    // calculate ATA
    let ata = await getAssociatedTokenAddress(
      mintPubkey, // mint
      alice.publicKey // owner
    );
    console.log(`ATA: ${ata.toBase58()}`);

    // if your wallet is off-curve, you should use
    // let ata = await getAssociatedTokenAddress(
    //   mintPubkey, // mint
    //   alice.publicKey // owner
    //   true, // allowOwnerOffCurve
    // );

    let tx = new Transaction().add(
      createAssociatedTokenAccountInstruction(
        feePayer.publicKey, // payer
        ata, // ata
        alice.publicKey, // owner
        mintPubkey // mint
      )
    );
    console.log(`txhash: ${await connection.sendTransaction(tx, [feePayer])}`);
  }
})();

Bagaimana cara mendapatkan sebuah Akun Token

Setiap akun token mempunyai informasi di dalam token seperti pemilik, mint, jumlah (saldo), dan decimlas.

Press </> button to view full source
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { getAccount } from "@solana/spl-token";

(async () => {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  const tokenAccountPubkey = new PublicKey(
    "2XYiFjmU1pCXmC2QfEAghk6S7UADseupkNQdnRBXszD5"
  );

  let tokenAccount = await getAccount(connection, tokenAccountPubkey);
  console.log(tokenAccount);
  /*
  {
    address: PublicKey {
      _bn: <BN: 16aef79dfadb39ffedb3b6f77688b8c162b18bb9cba2ffefe152303629ae3030>
    },
    mint: PublicKey {
      _bn: <BN: 7351e5e067cc7cfefef42e78915d3c513edbb8adeeab4d9092e814fe68c39fec>
    },
    owner: PublicKey {
      _bn: <BN: df30e6ca0981c1a677eed6f7cb46b2aa442ca9b7a10a10e494badea4b9b6944f>
    },
    amount: 0n,
    delegate: null,
    delegatedAmount: 0n,
    isInitialized: true,
    isFrozen: false,
    isNative: false,
    rentExemptReserve: null,
    closeAuthority: null
  }
  */
})();

Bagaimana cara mendapatkan saldo dari akun token

Akun token memiliki saldo token yang dapat diambil dengan sebuah single call.

Press </> button to view full source
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";

(async () => {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  const tokenAccount = new PublicKey(
    "FWZedVtyKQtP4CXhT7XDnLidRADrJknmZGA2qNjpTPg8"
  );

  let tokenAmount = await connection.getTokenAccountBalance(tokenAccount);
  console.log(`amount: ${tokenAmount.value.amount}`);
  console.log(`decimals: ${tokenAmount.value.decimals}`);
})();
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use solana_sdk::commitment_config::CommitmentConfig;
use std::str::FromStr;

fn main() {
    let rpc_url = String::from("https://api.devnet.solana.com");
    let connection = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());

    let token_account = Pubkey::from_str("FWZedVtyKQtP4CXhT7XDnLidRADrJknmZGA2qNjpTPg8").unwrap();
    let balance = connection
        .get_token_account_balance(&token_account)
        .unwrap();

    println!("amount: {}, decimals: {}", balance.amount, balance.decimals);
}

TIP

Sebuah akun token hanya dapat menampung satu jenis mint. Ketika anda menspesifikasikan sebuat akun token, anda juga menspesifikasikan mintnya juga.

Bagaimana cara untuk me-mint token-token

Ketika anda me-mint token-token, anda menambah supply dan mentransfer token-token baru ke sebuah akun token spesifik.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import {
  createMintToCheckedInstruction,
  mintToChecked,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const mintPubkey = new PublicKey(
    "8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV"
  );

  const tokenAccountPubkey = new PublicKey(
    "2XYiFjmU1pCXmC2QfEAghk6S7UADseupkNQdnRBXszD5"
  );

  // 1) use build-in function
  {
    let txhash = await mintToChecked(
      connection, // connection
      feePayer, // fee payer
      mintPubkey, // mint
      tokenAccountPubkey, // receiver (should be a token account)
      alice, // mint authority
      1e8, // amount. if your decimals is 8, you mint 10^8 for 1 token.
      8 // decimals
    );
    console.log(`txhash: ${txhash}`);

    // if alice is a multisig account
    // let txhash = await mintToChecked(
    //   connection, // connection
    //   feePayer, // fee payer
    //   mintPubkey, // mint
    //   tokenAccountPubkey, // receiver (should be a token account)
    //   alice.publicKey, // !! mint authority pubkey !!
    //   1e8, // amount. if your decimals is 8, you mint 10^8 for 1 token.
    //   8, // decimals
    //   [signer1, signer2 ...],
    // );
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createMintToCheckedInstruction(
        mintPubkey, // mint
        tokenAccountPubkey, // receiver (should be a token account)
        alice.publicKey, // mint authority
        1e8, // amount. if your decimals is 8, you mint 10^8 for 1 token.
        8 // decimals
        // [signer1, signer2 ...], // only multisig account will use
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + mint authority */,
      ])}`
    );
  }
})();

Bagaimana cara mentransfer token-token

Anda dapat mentransfer token-token dari satu akun token ke akun token lainnya.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import {
  createTransferCheckedInstruction,
  TOKEN_PROGRAM_ID,
  transferChecked,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const mintPubkey = new PublicKey(
    "8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV"
  );

  const tokenAccountXPubkey = new PublicKey(
    "2XYiFjmU1pCXmC2QfEAghk6S7UADseupkNQdnRBXszD5"
  );
  const tokenAccountYPubkey = new PublicKey(
    "GMxZfDmpR1b3vdJYXHzdF5noVLQogZuUAsDHHQ3ytPfV"
  );

  // 1) use build-in function
  {
    let txhash = await transferChecked(
      connection, // connection
      feePayer, // payer
      tokenAccountXPubkey, // from (should be a token account)
      mintPubkey, // mint
      tokenAccountYPubkey, // to (should be a token account)
      alice, // from's owner
      1e8, // amount, if your deciamls is 8, send 10^8 for 1 token
      8 // decimals
    );
    console.log(`txhash: ${txhash}`);
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createTransferCheckedInstruction(
        tokenAccountXPubkey, // from (should be a token account)
        mintPubkey, // mint
        tokenAccountYPubkey, // to (should be a token account)
        alice.publicKey, // from's owner
        1e8, // amount, if your deciamls is 8, send 10^8 for 1 token
        8 // decimals
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + owner */,
      ])}`
    );
  }
})();

Bagaimana cara membakar token-token

Anda dapat membakar token jika anda adalah pemilik dari token tersebut.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import {
  burnChecked,
  createBurnCheckedInstruction,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const mintPubkey = new PublicKey(
    "8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV"
  );

  const tokenAccountPubkey = new PublicKey(
    "2XYiFjmU1pCXmC2QfEAghk6S7UADseupkNQdnRBXszD5"
  );

  // 1) use build-in function
  {
    let txhash = await burnChecked(
      connection, // connection
      feePayer, // payer
      tokenAccountPubkey, // token account
      mintPubkey, // mint
      alice, // owner
      1e8, // amount, if your deciamls is 8, 10^8 for 1 token
      8
    );
    console.log(`txhash: ${txhash}`);
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createBurnCheckedInstruction(
        tokenAccountPubkey, // token account
        mintPubkey, // mint
        alice.publicKey, // owner of token account
        1e8, // amount, if your deciamls is 8, 10^8 for 1 token
        8 // decimals
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + token authority */,
      ])}`
    );
  }
})();

Bagaimana cara menutup akun-akun token

Anda dapat menutup akun token jika anda tidak ingin menggunakannya lagi. Ada dua situasi:

  1. Wrapped SOL - penutupan mengkonversi Wrapped SOL ke SOL
  2. Token-token lainnya - Anda dapat menutupnya hanya jika saldo akun adalah 0.
Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import { closeAccount, createCloseAccountInstruction } from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const tokenAccountPubkey = new PublicKey(
    "2XYiFjmU1pCXmC2QfEAghk6S7UADseupkNQdnRBXszD5"
  );

  // 1) use build-in function
  {
    let txhash = await closeAccount(
      connection, // connection
      feePayer, // payer
      tokenAccountPubkey, // token account which you want to close
      alice.publicKey, // destination
      alice // owner of token account
    );
    console.log(`txhash: ${txhash}`);
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createCloseAccountInstruction(
        tokenAccountPubkey, // token account which you want to close
        alice.publicKey, // destination
        alice.publicKey // owner of token account
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + owner */,
      ])}`
    );
  }
})();

Bagaimana cara untuk men-set authority pada akun-akun token atau mints

Anda dapat men-set/men-update authority. Ada 4 jenis:

  1. MintTokens (mint account)
  2. FreezeAccount (mint account)
  3. AccountOwner (token account)
  4. CloseAccount (token account)
Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import {
  AuthorityType,
  createSetAuthorityInstruction,
  setAuthority,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const randomGuy = Keypair.generate();
  console.log(`random guy: ${randomGuy.publicKey.toBase58()}`);

  const mintPubkey = new PublicKey(
    "8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV"
  );

  // authority type

  // 1) for mint account
  // AuthorityType.MintTokens
  // AuthorityType.FreezeAccount

  // 2) for token account
  // AuthorityType.AccountOwner
  // AuthorityType.CloseAccount

  // 1) use build-in function
  {
    let txhash = await setAuthority(
      connection, // connection
      feePayer, // payer
      mintPubkey, // mint account || token account
      alice, // current authority
      AuthorityType.MintTokens, // authority type
      randomGuy.publicKey // new authority (you can pass `null` to close it)
    );
    console.log(`txhash: ${txhash}`);
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createSetAuthorityInstruction(
        mintPubkey, // mint acocunt || token account
        alice.publicKey, // current auth
        AuthorityType.MintTokens, // authority type
        feePayer.publicKey // new auth (you can pass `null` to close it)
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + origin auth */,
      ])}`
    );
  }
})();

Bagaimana cara untuk men-approve delegasi sebuah token

Anda dapat mengatur sebuah delegasi dengan jumlah yang diijinkan. Setelah anda atur, delegasi akan seperti pemilik lainnya dari akun token anda. Sebuah akun token hanya dapat didelegasikan ke satu akun di saat yang bersamaan

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import {
  approveChecked,
  createApproveCheckedInstruction,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const randomGuy = Keypair.generate();

  const mintPubkey = new PublicKey(
    "8mAKLjGGmjKTnmcXeyr3pr7iX13xXVjJJiL6RujDbSPV"
  );
  const tokenAccountPubkey = new PublicKey(
    "GMxZfDmpR1b3vdJYXHzdF5noVLQogZuUAsDHHQ3ytPfV"
  );

  // 1) use build-in function
  {
    let txhash = await approveChecked(
      connection, // connection
      feePayer, // fee payer
      mintPubkey, // mint
      tokenAccountPubkey, // token account
      randomGuy.publicKey, // delegate
      alice, // owner of token account
      1e8, // amount, if your deciamls is 8, 10^8 for 1 token
      8 // decimals
    );
    console.log(`txhash: ${txhash}`);
  }
  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createApproveCheckedInstruction(
        tokenAccountPubkey, // token account
        mintPubkey, // mint
        randomGuy.publicKey, // delegate
        alice.publicKey, // owner of token account
        1e8, // amount, if your deciamls is 8, 10^8 for 1 token
        8 // decimals
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + owner */,
      ])}`
    );
  }
})();

Bagaimana cara menarik kembali delegasi token

Menarik kembali akan men-set delegate ke null dan men-set jumlah delegasi ke 0.

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  PublicKey,
  Keypair,
  Transaction,
} from "@solana/web3.js";
import { createRevokeInstruction, revoke } from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  const tokenAccountPubkey = new PublicKey(
    "DRS5CSgPQp4uvPPcUA34tckfYFNUPNBJi77fVbnSfQHr"
  );

  // 1) use build-in function
  {
    let txhash = await revoke(
      connection, // connection
      feePayer, // payer
      tokenAccountPubkey, // token account
      alice // owner of token account
    );
    console.log(`txhash: ${txhash}`);
  }

  // or

  // 2) compose by yourself
  {
    let tx = new Transaction().add(
      createRevokeInstruction(
        tokenAccountPubkey, // token account
        alice.publicKey // owner of token account
      )
    );
    console.log(
      `txhash: ${await connection.sendTransaction(tx, [
        feePayer,
        alice /* fee payer + origin auth */,
      ])}`
    );
  }
})();

Bagaimana cara mengature wrapped SOL

Wrapped SOL seperti hanya token mint lainnya. Perbedaannya adalah menggunakan syncNative dan membuat akun-akun token khusus di alamat NATIVE_MINT.

Membuat Akun Token

Sperti Create Token Account tetapi menganti mint dengan NATIVE_MINT

import { NATIVE_MINT } from "@solana/spl-token";

Menambah Saldo

Ada dua cara untuk menambah saldo untuk Wrapped SOL

1. Dengan SOL Transfer

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  Keypair,
  Transaction,
  SystemProgram,
} from "@solana/web3.js";
import {
  NATIVE_MINT,
  getAssociatedTokenAddress,
  createSyncNativeInstruction,
  createAccount,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  // remember to create ATA first
  let ata = await getAssociatedTokenAddress(
    NATIVE_MINT, // mint
    alice.publicKey // owner
  );

  let amount = 1 * 1e9; /* Wrapped SOL's decimals is 9 */

  let tx = new Transaction().add(
    // trasnfer SOL
    SystemProgram.transfer({
      fromPubkey: alice.publicKey,
      toPubkey: ata,
      lamports: amount,
    }),
    // sync wrapped SOL balance
    createSyncNativeInstruction(ata)
  );
  console.log(
    `txhash: ${await connection.sendTransaction(tx, [feePayer, alice])}`
  );
})();

2. Dengan Token Transfer

Press </> button to view full source
import {
  clusterApiUrl,
  Connection,
  Keypair,
  Transaction,
  SystemProgram,
} from "@solana/web3.js";
import {
  TOKEN_PROGRAM_ID,
  NATIVE_MINT,
  getMinimumBalanceForRentExemptAccount,
  getAssociatedTokenAddress,
  ACCOUNT_SIZE,
  createInitializeAccountInstruction,
  createTransferInstruction,
  closeAccountInstructionData,
  createCloseAccountInstruction,
} from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  // 5YNmS1R9nNSCDzb5a7mMJ1dwK9uHeAAF4CmPEwKgVWr8
  const feePayer = Keypair.fromSecretKey(
    bs58.decode(
      "588FU4PktJWfGfxtzpAAXywSNt74AvtroVzGfKkVN1LwRuvHwKGr851uH8czM5qm4iqLbs1kKoMKtMJG4ATR7Ld2"
    )
  );

  // G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY
  const alice = Keypair.fromSecretKey(
    bs58.decode(
      "4NMwxzmYj2uvHuq8xoqhY8RXg63KSVJM1DXkpbmkUY7YQWuoyQgFnnzn6yo3CMnqZasnNPNuAT2TLwQsCaKkUddp"
    )
  );

  // remember to create ATA first
  let ata = await getAssociatedTokenAddress(
    NATIVE_MINT, // mint
    alice.publicKey // owner
  );

  let auxAccount = Keypair.generate();
  let amount = 1 * 1e9; /* Wrapped SOL's decimals is 9 */

  let tx = new Transaction().add(
    // create token account
    SystemProgram.createAccount({
      fromPubkey: alice.publicKey,
      newAccountPubkey: auxAccount.publicKey,
      space: ACCOUNT_SIZE,
      lamports:
        (await getMinimumBalanceForRentExemptAccount(connection)) + amount, // rent + amount
      programId: TOKEN_PROGRAM_ID,
    }),
    // init token account
    createInitializeAccountInstruction(
      auxAccount.publicKey,
      NATIVE_MINT,
      alice.publicKey
    ),
    // transfer WSOL
    createTransferInstruction(
      auxAccount.publicKey,
      ata,
      alice.publicKey,
      amount
    ),
    // close aux account
    createCloseAccountInstruction(
      auxAccount.publicKey,
      alice.publicKey,
      alice.publicKey
    )
  );

  console.log(
    `txhash: ${await connection.sendTransaction(tx, [
      feePayer,
      auxAccount,
      alice,
    ])}`
  );
})();

Bagaimana cara mendapatkan semua akun-akun token sebagai pemilik

Anda dapat mengambil akun-akun token sebagai pemilik. Ada 2 cara untuk mendapatkannya.

  1. Mendapatkan semua akun token
Press </> button to view full source
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  const owner = new PublicKey("G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY");
  let response = await connection.getParsedTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID,
  });

  response.value.forEach((accountInfo) => {
    console.log(`pubkey: ${accountInfo.pubkey.toBase58()}`);
    console.log(`mint: ${accountInfo.account.data["parsed"]["info"]["mint"]}`);
    console.log(
      `owner: ${accountInfo.account.data["parsed"]["info"]["owner"]}`
    );
    console.log(
      `decimals: ${accountInfo.account.data["parsed"]["info"]["tokenAmount"]["decimals"]}`
    );
    console.log(
      `amount: ${accountInfo.account.data["parsed"]["info"]["tokenAmount"]["amount"]}`
    );
    console.log("====================");
  });
})();
  1. Filter Dengan Mint
Press </> button to view full source
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import * as bs58 from "bs58";

(async () => {
  // connection
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

  const owner = new PublicKey("G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY");
  const mint = new PublicKey("54dQ8cfHsW1YfKYpmdVZhWpb9iSi6Pac82Nf7sg3bVb");

  let response = await connection.getParsedTokenAccountsByOwner(owner, {
    mint: mint,
  });

  response.value.forEach((accountInfo) => {
    console.log(`pubkey: ${accountInfo.pubkey.toBase58()}`);
    console.log(`mint: ${accountInfo.account.data["parsed"]["info"]["mint"]}`);
    console.log(
      `owner: ${accountInfo.account.data["parsed"]["info"]["owner"]}`
    );
    console.log(
      `decimals: ${accountInfo.account.data["parsed"]["info"]["tokenAmount"]["decimals"]}`
    );
    console.log(
      `amount: ${accountInfo.account.data["parsed"]["info"]["tokenAmount"]["amount"]}`
    );
    console.log("====================");
  });
})();
Last Updated:
Contributors: akangaziz