Συγχρονισμός Native

Συγχρονισμός Native SOL

Το Wrapped SOL (WSOL) είναι ένας λογαριασμός token που παρακολουθεί την ποσότητα των lamports στον λογαριασμό ως υπόλοιπο token. Το WSOL επιτρέπει την ενσωμάτωση με πρωτόκολλα DeFi για τη μεταφορά του SOL ως SPL token.

Η εντολή SyncNative συγχρονίζει το υπόλοιπο ενός λογαριασμού wrapped SOL (WSOL) με τα πραγματικά SOL (lamports) που είναι αποθηκευμένα σε αυτόν. Όταν μεταφέρετε native SOL σε έναν λογαριασμό token WSOL, το υπόλοιπο του token δεν ενημερώνεται αυτόματα. Πρέπει να καλέσετε το 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?

Πίνακας Περιεχομένων

Επεξεργασία Σελίδας