ラップされたSOLとは?
ラップされたSOL(WSOL)は、Token Programのネイティブミント用のトークンアカウントに保持されたSOLです。ネイティブミントは、Token ProgramがSOLをラップするトークンアカウントに使用するミントアドレスです。ネイティブミントにより、Token Programのinstructionsを通じてSOLを使用できるようになります。
| プログラム | ネイティブミントアドレス |
|---|---|
| Token Program | So11111111111111111111111111111111111111112 |
| Token Extensions Program | 9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP |
ラップされたSOLトークンアカウントは、アカウントのlamportsフィールドにSOLを保存しますが、ラップされたSOLトークンアカウントに保持されているSOLは、トークンアカウントのamountフィールドを通じてトークン残高として追跡されます。ラップされたSOLトークンアカウントにSOLを転送すると、lamport残高は即座に増加しますが、Token
ProgramのSyncNative
instructionを呼び出すまで、トークンのamountフィールドは変更されません。
ネイティブSOLを同期する方法
ラップされたSOLトークンアカウントにSOLを転送した後、Token ProgramのSyncNative
instructionを使用します。SyncNative
instructionは、トークンアカウントのamountフィールドを、レント免除リザーブを超えてアカウントに保持されているlamportと一致するように更新します。
ソースリファレンス
| 項目 | 説明 | Token Program | Token Extensions Program |
|---|---|---|---|
Account | トークンアカウントステートはis_nativeを使用してアカウントをWSOLとしてマークし、ネイティブリザーブ(アカウントが保持する必要があるレント免除最小lamport残高)と追跡されたトークン量を保存します。 | ソース | ソース |
SyncNative | ラップされたSOLトークンアカウントのamountフィールドを、レント免除リザーブを超えてアカウントに保持されているlamportと一致するように更新するinstructionです。 | ソース | ソース |
process_sync_native | ラップされたSOL残高を同期するための共有プロセッサロジックです。 | ソース | ソース |
Typescript
以下のKit の例は、@solana/kit を使用した推奨アプローチを示しています。
@solana/web3.js を使用したレガシー例も参考として含まれています。
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 python3import asyncioimport jsonfrom solana.rpc.async_api import AsyncClientfrom solders.keypair import Keypairfrom solders.message import Messagefrom solders.pubkey import Pubkeyfrom solders.transaction import Transactionfrom solders.system_program import transfer, TransferParamsfrom spl.token.async_client import AsyncTokenfrom 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_MINTAMOUNT_TO_WRAP = 1_000_000async 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 valuefor 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?