네이티브 동기화

래핑된 SOL이란?

래핑된 SOL(WSOL)은 Token Program의 네이티브 민트를 위해 token account에 보관된 SOL입니다. 네이티브 민트는 Token Program이 SOL을 래핑하는 token account에 사용하는 민트 주소입니다. 네이티브 민트를 통해 SOL을 Token Program의 명령어로 사용할 수 있습니다.

프로그램네이티브 민트 주소
Token ProgramSo11111111111111111111111111111111111111112
Token Extension Program9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP

래핑된 SOL token account는 계정의 lamports 필드에 SOL을 저장하지만, token account의 amount 필드를 통해 래핑된 SOL token account에 보관된 SOL을 토큰 잔액으로 추적합니다. 래핑된 SOL token account로 SOL을 전송하면 lamport 잔액은 즉시 증가하지만, Token Program의 SyncNative 명령어를 호출하기 전까지 토큰 amount 필드는 변경되지 않습니다.

네이티브 SOL 동기화 방법

래핑된 SOL token account로 SOL을 전송한 후 Token Program의 SyncNative 명령어를 사용하세요. SyncNative 명령어는 token account의 amount 필드를 렌트 면제 준비금을 초과하여 계정에 보관된 lamport와 일치하도록 업데이트합니다.

소스 참조

항목설명Token ProgramToken Extension Program
Accounttoken account 상태는 is_native 를 사용하여 계정을 WSOL로 표시하고, 네이티브 준비금, 계정이 유지해야 하는 렌트 면제 최소 lamport 잔액, 그리고 추적된 토큰 금액을 저장합니다.SourceSource
SyncNative래핑된 SOL token account의 amount 필드를 렌트 면제 준비금을 초과하여 계정에 보관된 lamport와 일치하도록 업데이트하는 명령어입니다.SourceSource
process_sync_native래핑된 SOL 잔액을 동기화하기 위한 공유 프로세서 로직입니다.SourceSource

Typescript

아래 예제들은 Kit를 사용하는 권장 방법을 보여줍니다. 참고용으로 @solana/kit를 사용하는 레거시 예제도 포함되어 있습니다.

Kit

import { address } from "@solana/kit";
import { createLocalClient } from "@solana/kit-client-rpc";
import { systemProgram } from "@solana-program/system";
import {
findAssociatedTokenPda,
getCreateAssociatedTokenInstructionAsync,
tokenProgram,
TOKEN_PROGRAM_ADDRESS
} from "@solana-program/token";
const client = await createLocalClient()
.use(systemProgram())
.use(tokenProgram());
const NATIVE_MINT = address("So11111111111111111111111111111111111111112");
const [tokenAccount] = await findAssociatedTokenPda({
mint: NATIVE_MINT,
owner: client.payer.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS
});
const result = await client.sendTransaction([
client.system.instructions.transferSol({
source: client.payer, // Account sending the SOL to wrap.
destination: tokenAccount, // WSOL token account receiving the SOL.
amount: 1_000_000n // SOL amount in lamports.
}),
client.token.instructions.syncNative({
account: tokenAccount // WSOL token account to synchronize.
})
]);
const tokenAccountData = await client.token.accounts.token.fetch(tokenAccount);
console.log("WSOL Token Account Address:", tokenAccount);
console.log("WSOL Token Account:", tokenAccountData.data);
console.log("\nTransaction Signature:", result.context.signature);
Console
Click to execute the code.

Web3.js

import {
Connection,
Keypair,
sendAndConfirmTransaction,
LAMPORTS_PER_SOL,
SystemProgram,
Transaction
} from "@solana/web3.js";
import {
createAssociatedTokenAccount,
getAccount,
NATIVE_MINT,
syncNative,
TOKEN_PROGRAM_ID
} from "@solana/spl-token";
const result = await syncNative(
connection,
feePayer, // Account paying transaction fees.
associatedTokenAccount, // WSOL token account to synchronize.
{
commitment: "confirmed"
},
TOKEN_PROGRAM_ID // Token program to invoke.
);
const tokenAccountData = await getAccount(
connection,
associatedTokenAccount,
"confirmed",
TOKEN_PROGRAM_ID
);
console.log("WSOL Token Account Address:", associatedTokenAccount.toBase58());
console.log("WSOL Token Account:", tokenAccountData);
console.log("\nTransaction Signature:", result);
Console
Click to execute the code.

Rust

Rust
use anyhow::Result;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_commitment_config::CommitmentConfig;
use solana_sdk::{
program_pack::Pack,
signature::{Keypair, Signer},
transaction::Transaction,
};
use solana_system_interface::instruction::transfer;
use spl_associated_token_account_interface::{
address::get_associated_token_address, instruction::create_associated_token_account,
};
use spl_token_interface::{
id as token_program_id,
instruction::sync_native,
native_mint::ID as NATIVE_MINT_ID,
state::Account,
};
#[tokio::main]
async fn main() -> Result<()> {
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let associated_token_address = get_associated_token_address(&fee_payer.pubkey(), &NATIVE_MINT_ID);
let sync_amount = 1_000_000;
let transaction = Transaction::new_signed_with_payer(
&[
transfer(
&fee_payer.pubkey(), // Account sending the SOL to wrap.
&associated_token_address, // WSOL token account receiving the SOL.
sync_amount, // SOL amount in lamports.
),
sync_native(
&token_program_id(), // Token program to invoke.
&associated_token_address, // WSOL token account to synchronize.
)?,
],
Some(&fee_payer.pubkey()),
&[&fee_payer],
latest_blockhash,
);
let transaction_signature = client.send_and_confirm_transaction(&transaction).await?;
let token_account = client.get_account(&associated_token_address).await?;
let token_data = Account::unpack(&token_account.data)?;
println!("WSOL Token Account Address: {}", associated_token_address);
println!("WSOL Token Account: {:#?}", token_data);
println!("\nTransaction Signature: {}", transaction_signature);
Ok(())
}
Console
Click to execute the code.

Python

Python
#!/usr/bin/env python3
import asyncio
import json
from solana.rpc.async_api import AsyncClient
from solders.keypair import Keypair
from solders.message import Message
from solders.pubkey import Pubkey
from solders.transaction import Transaction
from solders.system_program import transfer, TransferParams
from spl.token.async_client import AsyncToken
from spl.token.instructions import (
create_associated_token_account,
get_associated_token_address,
sync_native,
SyncNativeParams,
)
from spl.token.constants import TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT
AMOUNT_TO_WRAP = 1_000_000
async def main():
rpc = AsyncClient("http://localhost:8899")
async with rpc:
sync_native_instructions = [
transfer(
TransferParams(
from_pubkey=fee_payer.pubkey(), # Account sending SOL to the wrapped SOL token account.
to_pubkey=wrapped_sol_account, # Wrapped SOL token account receiving the lamports.
lamports=AMOUNT_TO_WRAP, # Lamports to wrap as WSOL.
)
),
sync_native(
SyncNativeParams(
program_id=TOKEN_PROGRAM_ID, # Token program to invoke.
account=wrapped_sol_account, # Wrapped SOL token account whose amount field updates.
)
),
]
latest_blockhash = await rpc.get_latest_blockhash()
transaction = Transaction(
[fee_payer],
Message(sync_native_instructions, fee_payer.pubkey()),
latest_blockhash.value.blockhash,
)
result = await rpc.send_transaction(transaction)
token_account_info = await token.get_account_info(wrapped_sol_account)
token_account = {
key: str(value) if isinstance(value, Pubkey) else value
for key, value in token_account_info._asdict().items()
}
print("Native Mint Address:", WRAPPED_SOL_MINT)
print("\nWrapped SOL Token Account Address:", wrapped_sol_account)
print("Token Account:")
print(json.dumps(token_account, indent=2))
print("\nTransaction Signature:", result.value)
if __name__ == "__main__":
asyncio.run(main())
Console
Click to execute the code.

Is this page helpful?

목차

페이지 편집

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기