Синхронизация Native

Синхронизация Native SOL

Wrapped SOL (WSOL) — это токен-аккаунт, который отслеживает количество лампортов в аккаунте как баланс токенов. WSOL позволяет интеграцию с DeFi-протоколами для перевода SOL в виде SPL-токена.

Инструкция SyncNative синхронизирует баланс токен-аккаунта wrapped SOL (WSOL) с фактическим количеством SOL (лампортов), хранящихся в нем. Когда вы переводите native SOL на токен-аккаунт WSOL, баланс токенов не обновляется автоматически. Необходимо вызвать SyncNative, чтобы отразить корректный баланс WSOL.

Программа токенов (Token Program) и Программа расширений токенов (Token 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.

Python

Python
#!/usr/bin/env python3
import asyncio
from solana.rpc.async_api import AsyncClient
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
from solders.message import MessageV0
from solders.system_program import transfer, TransferParams
from spl.token.instructions import (
create_associated_token_account,
sync_native, SyncNativeParams,
close_account, CloseAccountParams,
get_associated_token_address
)
from spl.token.constants import TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID
from solders.pubkey import Pubkey
# Native mint address for wrapped SOL
NATIVE_MINT = Pubkey.from_string("So11111111111111111111111111111111111111112")
async def main():
rpc = AsyncClient("http://localhost:8899")
# Example keypairs
payer = Keypair()
owner = Keypair()
# Amount to wrap (in lamports)
amount_to_wrap = 1000000000 # 1 SOL
async with rpc:
# Get associated token address for wrapped SOL
wrapped_sol_account = get_associated_token_address(
owner=owner.pubkey(),
mint=NATIVE_MINT,
token_program_id=TOKEN_PROGRAM_ID
)
# Create associated token account for wrapped SOL
create_ata_instruction = create_associated_token_account(
payer=payer.pubkey(),
owner=owner.pubkey(),
mint=NATIVE_MINT
)
# Transfer SOL to the wrapped SOL account
transfer_instruction = transfer(
TransferParams(
from_pubkey=payer.pubkey(),
to_pubkey=wrapped_sol_account,
lamports=amount_to_wrap
)
)
# Sync native instruction to update the wrapped SOL balance
sync_native_instruction = sync_native(
SyncNativeParams(
program_id=TOKEN_PROGRAM_ID,
account=wrapped_sol_account
)
)
instructions = [
create_ata_instruction,
transfer_instruction,
sync_native_instruction
]
# Get latest blockhash
recent_blockhash = await rpc.get_latest_blockhash()
# Create message
message = MessageV0.try_compile(
payer=payer.pubkey(),
instructions=instructions,
address_lookup_table_accounts=[],
recent_blockhash=recent_blockhash.value.blockhash
)
# Create transaction
transaction = VersionedTransaction(message, [payer])
print(f"Wrapped SOL Operations:")
print(f"Owner: {owner.pubkey()}")
print(f"Wrapped SOL Account: {wrapped_sol_account}")
print(f"Amount to wrap: {amount_to_wrap} lamports ({amount_to_wrap / 1e9} SOL)")
print(f"Native Mint: {NATIVE_MINT}")
print(f"Payer: {payer.pubkey()}")
print(f"Wrapped SOL transaction created successfully")
async def unwrap_sol_example():
"""Example of unwrapping SOL (closing wrapped SOL account)"""
rpc = AsyncClient("http://localhost:8899")
payer = Keypair()
owner = Keypair()
async with rpc:
# Get wrapped SOL account
wrapped_sol_account = get_associated_token_address(
owner=owner.pubkey(),
mint=NATIVE_MINT,
token_program_id=TOKEN_PROGRAM_ID
)
# Close account instruction (unwraps SOL)
close_account_instruction = close_account(
CloseAccountParams(
program_id=TOKEN_PROGRAM_ID,
account=wrapped_sol_account,
dest=owner.pubkey(), # SOL will be sent back to owner
owner=owner.pubkey()
)
)
# Get latest blockhash
recent_blockhash = await rpc.get_latest_blockhash()
# Create message
message = MessageV0.try_compile(
payer=payer.pubkey(),
instructions=[close_account_instruction],
address_lookup_table_accounts=[],
recent_blockhash=recent_blockhash.value.blockhash
)
# Create transaction
transaction = VersionedTransaction(message, [payer, owner])
print(f"\nUnwrap SOL Example:")
print(f"Wrapped SOL Account: {wrapped_sol_account}")
print(f"Owner: {owner.pubkey()}")
print(f"Destination: {owner.pubkey()}")
print(f"Unwrap SOL transaction created successfully")
if __name__ == "__main__":
asyncio.run(main())
asyncio.run(unwrap_sol_example())
Console
Click to execute the code.

Is this page helpful?

Содержание

Редактировать страницу