Jeton
De quoi ai-je besoin pour commencer avec SPL-Tokens ?
Chaque fois que vous interagissez avec des jetons sur Solana, vous interagissez en fait avec la Bibliothèque du Programme Solana (SPL) de Jeton, ou norme SPL-Token. La norme SPL-Token nécessite l'utilisation d'une bibliothèque spécifique, que vous trouverez ci-dessous en fonction de votre langage de programmation.
"@solana/spl-token": "^0.2.0"
Comment créer un nouveau Jeton
La création de jetons se fait par la création de ce que l'on appelle un "compte de création" (mint account). Ce compte de création est ensuite utilisé pour créer des jetons sur le compte de jetons d'un utilisateur.
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])}`
);
})();
// 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
);
// or
// 2) compose by yourself
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)
)
);
Comment obtenir un "mint" de jeton
Afin d'obtenir l'offre actuelle, l'autorité ou les décimales d'un jeton, vous devez obtenir les informations de compte du mint du jeton.
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>
}
}
*/
})();
let mintAccount = await getMint(connection, mintAccountPublicKey);
Comment créer un compte de jeton
Un compte de jetons est nécessaire pour qu'un utilisateur puisse détenir des jetons.
Un utilisateur aura au moins un compte de jeton pour chaque type de jeton qu'il possède.
Les Comptes de Jetons Associés (ATAs) sont des comptes créés de façon déterministe pour chaque paire de clés (keypair). Les ATAs sont la méthode recommandée pour la gestion des comptes de jetons.
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])}`);
}
})();
// 1) use build-in function
{
let ata = await createAssociatedTokenAccount(
connection, // connection
feePayer, // fee payer
mintPubkey, // mint
alice.publicKey // owner,
);
}
// or
// 2) composed by yourself
{
let tx = new Transaction().add(
createAssociatedTokenAccountInstruction(
feePayer.publicKey, // payer
ata, // ata
alice.publicKey, // owner
mintPubkey // mint
)
);
}
Comment obtenir un compte de jetons
Chaque compte de jetons a des informations sur le jeton comme le propriétaire, le mint, le montant (solde), et les décimales.
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
}
*/
})();
let tokenAccount = await getAccount(connection, tokenAccountPubkey);
Comment obtenir le solde d'un compte de jetons
Le compte de jetons possède le solde du jeton, qui peut être récupéré en un seul appel.
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}`);
})();
let tokenAmount = await connection.getTokenAccountBalance(tokenAccount);
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);
}
let balance = connection
.get_token_account_balance(&token_account)
.unwrap();
TIP
Un compte de jetons ne peut contenir qu'un seul type de mint. Lorsque vous spécifiez un compte de jetons vous spécifiez également un mint.
Comment créer (mint) de nouveaux jetons
Lorsque vous créez des jetons, vous augmentez l'offre et transférez les nouveaux jetons vers un compte de jetons spécifique.
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 */,
])}`
);
}
})();
// 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
);
}
// 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
)
);
}
Comment transférer des jetons
Vous pouvez transférer des jetons d'un compte de jetons à un autre compte de jetons.
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 */,
])}`
);
}
})();
// 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
);
}
// 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
)
);
}
Comment brûler des jetons
Vous pouvez brûler un jeton si vous en êtes le propriétaire.
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 */,
])}`
);
}
})();
// 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
);
}
// 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
)
);
}
Comment fermer des comptes de jetons
Vous pouvez fermer un compte de jetons si vous ne voulez plus l'utiliser. Il y a deux situations :
- Wrapped SOL - La fermeture convertit les Wrapped SOL en SOL
- Other Tokens - Vous ne pouvez le fermer que si le solde du compte de jetons est égal à 0.
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 */,
])}`
);
}
})();
// 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
);
}
// 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
)
);
}
Comment définir l'autorité sur les comptes de jetons ou de mints ?
Il est possible de définir/mettre à jour l'autorité. Il en existe 4 types :
- MintTokens (pour un compte de mint)
- FreezeAccount (pour un compte de mint)
- AccountOwner (pour un compte de jetons)
- CloseAccount (pour un compte de jetons)
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 */,
])}`
);
}
})();
// 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)
);
}
// or
// 2) compose by yourself
{
let tx = new Transaction().add(
createSetAuthorityInstruction(
mintPubkey, // mint acocunt || token account
alice.publicKey, // current auth
AuthorityType.MintTokens, // authority type
randomGuy.publicKey // new auth (you can pass `null` to close it)
)
);
}
Comment approuver une délégation de jetons
Il est possible de définir un délégué avec un montant autorisé. Après votre paramétrage, le délégué est comme un autre propriétaire de votre compte de jeton. Un compte de jetons ne peut déléguer qu'à un seul compte à la fois.
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 */,
])}`
);
}
})();
// 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
);
}
// 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
)
);
}
Comment révoquer une délégation de jetons
La révocation mettra le délégué à null et le montant délégué à 0.
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 */,
])}`
);
}
})();
// 1) use build-in function
{
let txhash = await revoke(
connection, // connection
feePayer, // payer
tokenAccountPubkey, // token account
alice // owner of token account
);
}
// or
// 2) compose by yourself
{
let tx = new Transaction().add(
createRevokeInstruction(
tokenAccountPubkey, // token account
alice.publicKey // owner of token account
)
);
}
Comment gérer les wrapped SOL
Les Wrapped SOL sont comme n'importe quel autre jeton. La différence est d'utiliser syncNative
et de créer des comptes de jetons spécifiquement sur l'adresse NATIVE_MINT
.
Créer un Compte de Jetons
Comme Créer un Compte de Jetons mais en remplaçant mint par NATIVE_MINT
import { NATIVE_MINT } from "@solana/spl-token";
Ajouter un solde
Il existe deux manières pour ajouter un solde pour Wrapped SOL
1. Par un Transfert de SOL
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])}`
);
})();
let tx = new Transaction().add(
// trasnfer SOL
SystemProgram.transfer({
fromPubkey: alice.publicKey,
toPubkey: ata,
lamports: amount,
}),
// sync wrapped SOL balance
createSyncNativeInstruction(ata)
);
2. Par un Transfert de Jetons
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,
])}`
);
})();
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
)
);
Comment obtenir tous les comptes de jetons par propriétaire
Il est possible de récupérer les comptes de jetons par propriétaire. Pour cela, il y a deux façons de procéder.
- Obtenir Tous les Comptes de Jetons
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("====================");
});
})();
let response = await connection.getParsedTokenAccountsByOwner(owner, {
programId: TOKEN_PROGRAM_ID,
});
- Filtrer Par Mint
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("====================");
});
})();
let response = await connection.getParsedTokenAccountsByOwner(owner, {
mint: mint,
});