개요
채널 전송은 게이트웨이에 제출되는 표준 SPL 토큰 전송입니다 - 전용 Private Channels 전송 명령어는 없습니다. 게이트웨이는 트랜잭션을 write 노드로 라우팅하며, 이 노드는 채널의 오프체인 계정 레이어에 대해 트랜잭션을 실행합니다. 전송은 시퀀서가 처리할 때 확인되며, Solana 블록이 확인될 때가 아니며, Mainnet에는 표시되지 않습니다.
지갑 RPC 전환
전송을 보내기 전에 지갑의 RPC 엔드포인트를 Solana Devnet 대신 게이트웨이 URL로 전환하세요:
http://localhost:8899
공개 Solana RPC로 전송된 트랜잭션은 채널이 아닌 Mainnet에 도달합니다.
인증
--profile auth 없이 스택을 시작한 경우 (기본 devnet
구성), 게이트웨이는 오픈 모드로 작동하며 토큰이 필요하지 않습니다 -
이 섹션을 건너뛰세요.
Auth Service가 활성화된 경우 (게이트웨이에 JWT_SECRET이 설정됨), 모든
요청에는 Authorization 헤더에 JWT bearer 토큰이 필요합니다:
Authorization: Bearer <JWT_TOKEN>
등록, 로그인 및 토큰 획득 방법은 **Authentication & Roles**를 참조하세요.
전송 빌드 및 보내기
수신자의 associated token account가 채널에 아직 존재하지 않는 경우,
전송 전에 createAssociatedTokenAccountIdempotent 명령어를 추가하세요.
아래 코드는 두 가지 경우를 모두 처리합니다:
import {address,createSolanaRpc,pipe,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstruction,signAndSendTransactionMessageWithSigners,assertIsTransactionMessageWithSingleSendingSigner,getBase58Decoder} from "@solana/kit";import {findAssociatedTokenPda,getCreateAssociatedTokenIdempotentInstruction,getTransferInstruction} from "@solana-program/token";const TOKEN_PROGRAM_ADDRESS = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");// Point to the gateway, not a public Solana RPCconst privateChannelRpc = createSolanaRpc("http://localhost:8899");// Derive source and destination associated token accountsconst [sourceAta] = await findAssociatedTokenPda({mint: address(mintAddress),owner: address(senderAddress),tokenProgram: TOKEN_PROGRAM_ADDRESS});const [destinationAta] = await findAssociatedTokenPda({mint: address(mintAddress),owner: address(recipientAddress),tokenProgram: TOKEN_PROGRAM_ADDRESS});const transferInstruction = getTransferInstruction({source: sourceAta,destination: destinationAta,authority: transactionSigner,amount: 1_000_000n // 1 USDC (6 decimals)});// Create the destination ATA on the channel if it does not exist yetconst destinationAtaInfo = await privateChannelRpc.getAccountInfo(destinationAta, { encoding: "base64" }).send();const { value: latestBlockhash } = await privateChannelRpc.getLatestBlockhash({ commitment: "confirmed" }).send();// Sent to the Private Channels gateway (not Solana RPC directly), which// expects the legacy transaction format - do not switch this to version 0.const transactionMessage = !destinationAtaInfo.value? pipe(createTransactionMessage({ version: "legacy" }),(m) => setTransactionMessageFeePayerSigner(transactionSigner, m),(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),(m) =>appendTransactionMessageInstruction(getCreateAssociatedTokenIdempotentInstruction({payer: transactionSigner,ata: destinationAta,owner: address(recipientAddress),mint: address(mintAddress)}),m),(m) => appendTransactionMessageInstruction(transferInstruction, m)): pipe(createTransactionMessage({ version: "legacy" }),(m) => setTransactionMessageFeePayerSigner(transactionSigner, m),(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),(m) => appendTransactionMessageInstruction(transferInstruction, m));assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);const signatureBytes =await signAndSendTransactionMessageWithSigners(transactionMessage);const signature = getBase58Decoder().decode(signatureBytes);console.log("Transfer signature:", signature);
전송 확인
전송이 완료되었는지 확인하기 위해 게이트웨이를 통해 수신자의 채널 잔액을 조회하세요:
const [recipientAta] = await findAssociatedTokenPda({mint: address(mintAddress),owner: address(recipientAddress),tokenProgram: TOKEN_PROGRAM_ADDRESS});const balance = await privateChannelRpc.getTokenAccountBalance(recipientAta).send();console.log(balance.value.uiAmountString);
다음 단계
Withdraw Funds - 토큰을 Solana 지갑으로 출금하기
Is this page helpful?