同步原生 SOL

同步原生 SOL

封装 SOL (WSOL) 是一种代币账户,它将账户中的 lamport 数量作为代币余额进行跟踪。WSOL 使得与 DeFi 协议的集成成为可能,可以将 SOL 作为 SPL 代币进行转账。

SyncNative 指令用于同步封装 SOL (WSOL) 代币账户余额与实际存储在其中的 SOL (lamport) 数量。当您将原生 SOL 转入 WSOL 代币账户时,代币余额不会自动更新。您必须调用 SyncNative 来反映正确的 WSOL 余额。

Token ProgramToken Extension Program 具有类似的实现方式以实现相同的功能。

Typescript

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners,
address
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import {
getCreateAssociatedTokenInstructionAsync,
TOKEN_PROGRAM_ADDRESS,
findAssociatedTokenPda,
getSyncNativeInstruction
} from "@solana-program/token";
// Create Connection, local validator in this example
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate keypairs for fee payer
const feePayer = await generateKeyPairSigner();
// Fund fee payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: feePayer.address,
lamports: lamports(2_000_000_000n),
commitment: "confirmed"
});
// Native mint (Wrapped SOL) address
const NATIVE_MINT = address("So11111111111111111111111111111111111111112");
// Use findAssociatedTokenPda to derive the ATA address for WSOL
const [associatedTokenAddress] = await findAssociatedTokenPda({
mint: NATIVE_MINT,
owner: feePayer.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS
});
// Get latest blockhash to include in transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Create instruction to create the WSOL associated token account
const createAtaInstruction = await getCreateAssociatedTokenInstructionAsync({
payer: feePayer,
mint: NATIVE_MINT,
owner: feePayer.address
});
// Amount to wrap (1 SOL = 1,000,000,000 lamports)
const amountToSync = 1_000_000_000n;
// Create instruction to transfer SOL to the WSOL token account
const transferSolInstruction = getTransferSolInstruction({
source: feePayer,
destination: associatedTokenAddress,
amount: amountToSync
});
// Create instruction to sync native SOL balance with WSOL token balance
const syncNativeInstruction = getSyncNativeInstruction({
account: associatedTokenAddress
});
const instructions = [
createAtaInstruction,
transferSolInstruction,
syncNativeInstruction
];
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(feePayer, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions(instructions, tx)
);
// Sign transaction message with all required signers
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Send and confirm transaction
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
// Get transaction signature
const transactionSignature = getSignatureFromTransaction(signedTransaction);
console.log("Fee Payer Address:", feePayer.address.toString());
console.log("WSOL Token Account Address:", associatedTokenAddress.toString());
console.log("Successfully wrapped 1.0 SOL into WSOL");
console.log("Transaction Signature:", transactionSignature);
Console
Click to execute the code.

Rust

use anyhow::Result;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::{
commitment_config::CommitmentConfig,
signature::{Keypair, Signer},
system_instruction::transfer as sol_transfer,
transaction::Transaction,
};
use spl_associated_token_account::{
get_associated_token_address_with_program_id, instruction::create_associated_token_account,
};
use spl_token::{
id as token_program_id,
instruction::sync_native,
native_mint::ID as NATIVE_MINT_ID,
};
#[tokio::main]
async fn main() -> Result<()> {
// Create connection to local validator
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let recent_blockhash = client.get_latest_blockhash().await?;
// Generate a new keypair for the fee payer
let fee_payer = Keypair::new();
// Airdrop 2 SOL to fee payer
let airdrop_signature = client
.request_airdrop(&fee_payer.pubkey(), 2_000_000_000)
.await?;
client.confirm_transaction(&airdrop_signature).await?;
loop {
let confirmed = client.confirm_transaction(&airdrop_signature).await?;
if confirmed {
break;
}
}
// Calculate the associated token account address for WSOL
let associated_token_address = get_associated_token_address_with_program_id(
&fee_payer.pubkey(), // owner
&NATIVE_MINT_ID, // mint (Wrapped SOL)
&token_program_id(), // program_id
);
// Instruction to create associated token account for WSOL
let create_ata_instruction = create_associated_token_account(
&fee_payer.pubkey(), // funding address
&fee_payer.pubkey(), // wallet address
&NATIVE_MINT_ID, // mint address
&token_program_id(), // program id
);
// Amount to wrap (1 SOL = 1,000,000,000 lamports)
let amount = 1_000_000_000;
// Create transfer instruction to send SOL to the WSOL token account
let transfer_instruction = sol_transfer(
&fee_payer.pubkey(),
&associated_token_address,
amount
);
// Create sync native instruction to update WSOL balance
let sync_native_instruction = sync_native(
&token_program_id(),
&associated_token_address
)?;
// Create transaction and add instructions
let transaction = Transaction::new_signed_with_payer(
&[
create_ata_instruction,
transfer_instruction,
sync_native_instruction,
],
Some(&fee_payer.pubkey()),
&[&fee_payer],
recent_blockhash,
);
// Send and confirm transaction
let transactionSignature = client.send_and_confirm_transaction(&transaction).await?;
println!("Fee Payer Address: {}", fee_payer.pubkey());
println!(
"WSOL Token Account Address: {}",
associated_token_address
);
println!("Successfully wrapped 1.0 SOL into WSOL");
println!("Transaction Signature: {}", transactionSignature);
Ok(())
}
Console
Click to execute the code.

Is this page helpful?

Table of Contents

Edit Page