Entrega contra Pagamento (DvP) é um método de liquidação de valores mobiliários que garante que a transferência de títulos ocorre simultaneamente com a transferência do pagamento. Isso elimina o risco de contraparte ao garantir que ambas as etapas da transação sejam executadas atomicamente — ou ambas são concluídas, ou nenhuma delas é.
O Problema
Quando você compra títulos (como commercial paper), tradicionalmente duas coisas precisam acontecer:
- Você envia dinheiro → Vendedor
- Vendedor envia títulos → Você
Se isso acontecer separadamente, há risco — e se você pagar mas nunca receber os títulos? Ou vice-versa?
A Solução
(DvP) "Entrega contra Pagamento" significa que ambas as transferências acontecem no exato mesmo momento, ou nenhuma acontece. É como uma troca em que ambos os lados trocam simultaneamente.
┌─────────────────────────────────────────────────────┐│ ONE ATOMIC TRANSACTION │├─────────────────────────────────────────────────────┤│ ││ Investor ──── $95,000 USDC ────→ Issuer ││ ││ Issuer ─────── 100 Bonds ──────→ Investor ││ ││ ✅ Both happen together, or neither happens ││ │└─────────────────────────────────────────────────────┘
Este guia demonstra como implementar um fluxo de trabalho completo de DvP na Solana usando extensões SPL Token 2022 para emissão de títulos em conformidade regulatória e USDC padrão para liquidação, tudo sem escrever programas Rust personalizados.
Implementação de Referência Educacional
Você pode usar o código-fonte desta implementação para experimentar uma implementação de DvP localmente.
Este guia fornece uma implementação de referência apenas para fins de exploração e educação. NÃO use este código diretamente em produção sem:
- Auditorias de segurança abrangentes
- Sistemas adequados de gestão de chaves
- Revisão de conformidade regulatória
- Consulta jurídica
- Testes extensivos e modificações
Por que Solana para DvP?
A arquitetura da Solana oferece vantagens significativas em relação à liquidação tradicional de valores mobiliários:
| Aspecto | Tradicional (T+2) | Solana |
|---|---|---|
| Lógica de Liquidação | Câmaras de Compensação | Agrupamento atômico de transações |
| Tempo de Liquidação | 2 dias | <1 segundo |
| Custo da Transação | $50-500 | <$0,01 |
| Risco de Contraparte | Alto (intermediários) | Zero (execução atômica) |
| Finalidade | Fim do dia | ~400ms |
O agrupamento atômico de transações da Solana elimina intermediários, proporcionando liquidações instantâneas, econômicas e seguras.
Visão Geral da Arquitetura
O sistema DvP é composto pelos seguintes componentes principais:
- Token de Título (Commercial Paper): SPL Token 2022 com Token Extensions
- Moeda de Liquidação: USDC padrão (token SPL existente)
- Agente de Liquidação: Orquestra swaps atômicos por meio de autoridade delegada
- Sistema de Lista de Permissões: Controla quais endereços podem deter títulos
Princípios-Chave de Design
- Sem Programas Personalizados: Utiliza apenas Token Extensions Program e USDC padrão
- Liquidação Atômica: Uma única transação garante que ambas as transferências sejam bem-sucedidas ou falhem juntas
- Estado Congelado Padrão: Os títulos exigem inclusão explícita na lista de permissões para conformidade regulatória
- Autoridade Delegada: O agente de liquidação coordena sem assumir a custódia
- Comunicação via Estado da Rede: Não é necessária conectividade ponto a ponto via API
┌─────────────────────────────────────────────────────┐│ DvP Settlement Flow │├─────────────────────────────────────────────────────┤│ ││ 1. Bond Creation (Token-2022 + Extensions) ││ └─> Default State: FROZEN ││ └─> Freeze Authority: Settlement Agent/Issuer ││ └─> Token metadata: Bond information ││ ││ 2. Whitelist Participants ││ └─> Whitelist issuer, mint bonds ││ └─> Whitelist investor for trading ││ ││ 3. Delegate Authority to settlement agent ││ ├─> Issuer delegates bonds ││ └─> Investor delegates USDC ││ ││ 4. Atomic Settlement ││ ├─> Transfer bonds: Issuer → Investor ││ └─> Transfer USDC: Investor → Issuer ││ (Both or neither - atomic) ││ │└─────────────────────────────────────────────────────┘
Uma parte confiável que orquestra a negociação. Ambos os lados delegam autoridade ao agente de liquidação, que então executa o swap atômico.
┌─────────┐ delegates ┌──────────────────┐ delegates ┌──────────┐│ Issuer │ ─────────────────→ │ Settlement Agent │ ←──────────────── │ Investor │└─────────┘ (bonds) │ (trusted) │ (USDC) └──────────┘│ ││ executes atomic ││ transaction │└──────────────────┘
Token de Título com Token Extensions 2022
O SPL Token 2022 oferece extensões poderosas que permitem a emissão de valores mobiliários em conformidade sem programas personalizados:
Extensões Essenciais para Títulos
- Extensão de Estado Padrão de Conta: Define todas as novas token accounts como congeladas por padrão, exigindo inclusão explícita na lista de permissões
- Extensão de Metadados: Armazena detalhes do título na blockchain (ISIN, data de vencimento, taxa de cupom, etc.)
- Delegado Permanente (opcional): Permite recuperação autorizada ou clawback se exigido pela regulação
Configuração de Autoridade
- Autoridade de Emissão: Emissor (controla a criação de supply)
- Autoridade de Congelamento: Agente de Liquidação (gerencia a lista de permissões)
- Autoridade de Atualização: Agente de Liquidação (pode atualizar metadados)
O estado congelado padrão é fundamental para a conformidade regulatória. Ele garante que apenas os endereços explicitamente incluídos na lista de permissões possam receber e deter os valores mobiliários, atendendo aos requisitos de KYC/AML.
Implementação Completa de DvP
Configurando o Motor DvP
Primeiro, crie a classe principal do motor DvP que gerencia todas as operações:
import {Connection,Keypair,PublicKey,Transaction,SystemProgram,sendAndConfirmTransaction,LAMPORTS_PER_SOL} from "@solana/web3.js";import {approve,thawAccount,freezeAccount,getAccount,getAssociatedTokenAddress,getOrCreateAssociatedTokenAccount,createTransferCheckedInstruction,TOKEN_2022_PROGRAM_ID,TOKEN_PROGRAM_ID,ExtensionType,getMintLen,createInitializeMintInstruction,createInitializeDefaultAccountStateInstruction,createInitializeMetadataPointerInstruction,AccountState,LENGTH_SIZE,TYPE_SIZE} from "@solana/spl-token";import {pack,createInitializeInstruction,createUpdateFieldInstruction,type TokenMetadata} from "@solana/spl-token-metadata";interface BondTokenConfig {name: string;symbol: string;decimals: number;maturityDate: Date;couponRate: number;isin?: string;description?: string;}interface DvPParams {bondMint: PublicKey;usdcMint: PublicKey;bondAmount: number;usdcAmount: number;issuer: PublicKey;investor: PublicKey;}interface DvPResult {signature: string;bondAmount: number;usdcAmount: number;timestamp: Date;bondsSent: boolean;usdcReceived: boolean;}/*** DvP Engine - Reference Implementation** This implementation demonstrates Delivery vs Payment (DvP) on Solana using:* - SPL Token 2022 with Default Account State extension for bonds* - Standard USDC for settlement* - Atomic transactions for settlement* - Delegated authority pattern for settlement agent** ⚠️ IMPORTANT: This is a reference implementation for educational purposes.* Do NOT use in production without proper audits and security reviews.*/export class DvPEngine {private connection: Connection;private settlementAgent: Keypair;constructor(connection: Connection, settlementAgent: Keypair) {this.connection = connection;this.settlementAgent = settlementAgent;}/*** Creates a bond token using Token-2022 with Default Account State and Metadata extensions* Bonds are frozen by default and require whitelisting* Metadata is stored onchain using the TokenMetadata extension*/async createBondToken(issuer: Keypair,config: BondTokenConfig): Promise<PublicKey> {console.log("\n🏗️ Creating bond token with Token-2022 + Metadata...");console.log(` Name: ${config.name}`);console.log(` Symbol: ${config.symbol}`);console.log(` Coupon Rate: ${config.couponRate}%`);console.log(` Maturity: ${config.maturityDate.toISOString().split("T")[0]}`);// Generate new keypair for the mintconst mintKeypair = Keypair.generate();// Create the metadata object to get EXACT sizeconst metadata: TokenMetadata = {mint: mintKeypair.publicKey,name: config.name,symbol: config.symbol,uri: config.description || "",additionalMetadata: [["couponRate", config.couponRate.toString()],["maturityDate", config.maturityDate.toISOString()],["isin", config.isin || ""]]};// Size of metadata using pack() - this gives us the EXACT sizeconst metadataLen = pack(metadata).length;// Size of MetadataExtension: 2 bytes for type, 2 bytes for lengthconst metadataExtension = TYPE_SIZE + LENGTH_SIZE;// Calculate space for mint with extensions (without metadata)const extensions = [ExtensionType.DefaultAccountState,ExtensionType.MetadataPointer];const spaceWithoutMetadataExtension = getMintLen(extensions);// Calculate rent for FULL space (mint + metadata + TLV overhead)const lamports = await this.connection.getMinimumBalanceForRentExemption(spaceWithoutMetadataExtension + metadataLen + metadataExtension);// Build transaction following the official docs patternconst transaction = new Transaction().add(// 1. Create account with just base space, but rent for full spaceSystemProgram.createAccount({fromPubkey: issuer.publicKey,newAccountPubkey: mintKeypair.publicKey,space: spaceWithoutMetadataExtension, // Just base spacelamports, // But rent for full space (includes metadata + TLV)programId: TOKEN_2022_PROGRAM_ID}),// 2. Initialize metadata pointer (before mint!)createInitializeMetadataPointerInstruction(mintKeypair.publicKey,issuer.publicKey, // authoritymintKeypair.publicKey, // metadata address (self)TOKEN_2022_PROGRAM_ID),// 3. Initialize default account state (frozen)createInitializeDefaultAccountStateInstruction(mintKeypair.publicKey,AccountState.Frozen,TOKEN_2022_PROGRAM_ID),// 4. Initialize mintcreateInitializeMintInstruction(mintKeypair.publicKey,config.decimals,issuer.publicKey, // mint authoritythis.settlementAgent.publicKey, // freeze authorityTOKEN_2022_PROGRAM_ID),// 5. Initialize metadatacreateInitializeInstruction({programId: TOKEN_2022_PROGRAM_ID,mint: mintKeypair.publicKey,metadata: mintKeypair.publicKey,name: config.name,symbol: config.symbol,uri: config.description || "",mintAuthority: issuer.publicKey,updateAuthority: this.settlementAgent.publicKey}));// 6. Add custom metadata fieldsfor (const [field, value] of metadata.additionalMetadata) {if (value) {transaction.add(createUpdateFieldInstruction({programId: TOKEN_2022_PROGRAM_ID,metadata: mintKeypair.publicKey,updateAuthority: this.settlementAgent.publicKey,field: field,value: value}));}}// Send transactionawait sendAndConfirmTransaction(this.connection,transaction,[issuer, mintKeypair, this.settlementAgent],{ commitment: "confirmed" });console.log(`✅ Bond token created: ${mintKeypair.publicKey.toBase58()}`);console.log(` Mint Authority: ${issuer.publicKey.toBase58()}`);console.log(` Freeze Authority: ${this.settlementAgent.publicKey.toBase58()}`);console.log(` Update Authority: ${this.settlementAgent.publicKey.toBase58()}`);console.log(` Default State: FROZEN (requires whitelisting)`);console.log(` ✨ Metadata: ON-CHAIN`);return mintKeypair.publicKey;}/*** Whitelists a participant by creating their bond account and thawing it*/async whitelist(bondMint: PublicKey,participant: PublicKey,payer: Keypair): Promise<PublicKey> {console.log(`\n🔓 Whitelisting participant: ${participant.toBase58()}`);// Get or create token account (will be frozen by default if new)const bondAccount = await getOrCreateAssociatedTokenAccount(this.connection,payer,bondMint,participant,false,"confirmed",{ commitment: "confirmed" },TOKEN_2022_PROGRAM_ID);console.log(` Account: ${bondAccount.address.toBase58()}`);// Only thaw if the account is frozenif (bondAccount.isFrozen) {await thawAccount(this.connection,this.settlementAgent,bondAccount.address,bondMint,this.settlementAgent,[],{ commitment: "confirmed" },TOKEN_2022_PROGRAM_ID);console.log(`✅ Participant whitelisted and account thawed`);} else {console.log(`✅ Participant already whitelisted (account was not frozen)`);}return bondAccount.address;}/*** Removes an investor from whitelist by freezing their account*/async removeFromWhitelist(bondMint: PublicKey,investorBondAccount: PublicKey): Promise<void> {console.log(`\n🔒 Removing from whitelist: ${investorBondAccount.toBase58()}`);await freezeAccount(this.connection,this.settlementAgent,investorBondAccount,bondMint,this.settlementAgent,[],{ commitment: "confirmed" },TOKEN_2022_PROGRAM_ID);console.log(`✅ Account frozen and removed from whitelist`);}/*** Delegates authority to settlement agent for a token account*/async delegateAuthority(owner: Keypair,tokenAccount: PublicKey,amount: number,decimals: number,programId: PublicKey): Promise<void> {const amountWithDecimals = amount * Math.pow(10, decimals);console.log(`\n🤝 Delegating authority...`);console.log(` Account: ${tokenAccount.toBase58()}`);console.log(` Amount: ${amount}`);console.log(` Delegate: ${this.settlementAgent.publicKey.toBase58()}`);await approve(this.connection,owner,tokenAccount,this.settlementAgent.publicKey,owner.publicKey,amountWithDecimals,[],{ commitment: "confirmed" },programId);console.log(`✅ Authority delegated`);}/*** Executes atomic DvP settlement* Both bond and USDC transfers happen in a single transaction*/async executeDvP(params: DvPParams): Promise<DvPResult> {console.log(`\n⚡ Executing atomic DvP settlement...`);console.log(` Bonds: ${params.bondAmount}`);console.log(` USDC: ${params.usdcAmount}`);console.log(` Issuer: ${params.issuer.toBase58()}`);console.log(` Investor: ${params.investor.toBase58()}`);// Get all associated token account addresses (deterministically)const issuerBondAccount = await getAssociatedTokenAddress(params.bondMint,params.issuer,false, // allowOwnerOffCurveTOKEN_2022_PROGRAM_ID);const investorBondAccount = await getAssociatedTokenAddress(params.bondMint,params.investor,false,TOKEN_2022_PROGRAM_ID);const investorUSDCAccount = await getAssociatedTokenAddress(params.usdcMint,params.investor,false,TOKEN_PROGRAM_ID);const issuerUSDCAccount = await getAssociatedTokenAddress(params.usdcMint,params.issuer,false,TOKEN_PROGRAM_ID);// Build atomic transactionconst transaction = new Transaction();// Add bond transfer instruction (Issuer → Investor)transaction.add(this.createTransferCheckedIx(issuerBondAccount,params.bondMint,investorBondAccount,params.bondAmount,0, // bonds have 0 decimalsTOKEN_2022_PROGRAM_ID));// Add USDC transfer instruction (Investor → Issuer)transaction.add(this.createTransferCheckedIx(investorUSDCAccount,params.usdcMint,issuerUSDCAccount,params.usdcAmount * 1e6, // USDC has 6 decimals6,TOKEN_PROGRAM_ID));// Send atomic transactionconsole.log(`\n📡 Sending atomic transaction...`);const signature = await sendAndConfirmTransaction(this.connection,transaction,[this.settlementAgent],{ commitment: "confirmed" });console.log(`✅ DvP SETTLED ATOMICALLY`);console.log(` Signature: ${signature}`);console.log(` Bonds transferred: ${params.bondAmount}`);console.log(` USDC transferred: ${params.usdcAmount}`);return {signature,bondAmount: params.bondAmount,usdcAmount: params.usdcAmount,timestamp: new Date(),bondsSent: true,usdcReceived: true};}/*** Helper to create a transferChecked instruction using delegated authority*/private createTransferCheckedIx(source: PublicKey,mint: PublicKey,destination: PublicKey,amount: number,decimals: number,programId: PublicKey) {return createTransferCheckedInstruction(source,mint,destination,this.settlementAgent.publicKey, // Settlement agent acts via delegationamount,decimals,[],programId);}/*** Gets account information for inspection*/async getAccountInfo(tokenAccount: PublicKey, programId: PublicKey) {const account = await getAccount(this.connection,tokenAccount,"confirmed",programId);return {address: tokenAccount,mint: account.mint,owner: account.owner,amount: account.amount,isFrozen: account.isFrozen};}/*** Airdrops SOL for testing (devnet/testnet only)*/async airdropSol(publicKey: PublicKey, amount: number): Promise<void> {console.log(`\n💰 Airdropping ${amount} SOL to ${publicKey.toBase58()}`);const signature = await this.connection.requestAirdrop(publicKey,amount * LAMPORTS_PER_SOL);await this.connection.confirmTransaction(signature, "confirmed");console.log(`✅ Airdrop complete`);}}
Exemplo Completo de Uso
Aqui está um exemplo completo demonstrando todo o fluxo de trabalho DvP:
import { Connection, Keypair, clusterApiUrl, PublicKey } from "@solana/web3.js";import {getOrCreateAssociatedTokenAccount,mintTo,TOKEN_2022_PROGRAM_ID,TOKEN_PROGRAM_ID} from "@solana/spl-token";// Standard USDC mint address on mainnetconst USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");async function runDvPExample() {// 1. Initialize connection and keypairsconst connection = new Connection(clusterApiUrl("devnet"));const settlementAgent = Keypair.generate();const issuer = Keypair.generate();const investor = Keypair.generate();console.log("🚀 Starting DvP Workflow\n");// 2. Initialize DvP engineconst dvp = new DvPEngine(connection, settlementAgent);// 3. Airdrop SOL for transaction fees (devnet only)await dvp.airdropSol(settlementAgent.publicKey, 2);await dvp.airdropSol(issuer.publicKey, 2);await dvp.airdropSol(investor.publicKey, 2);// 4. Create commercial paper (bond) token with metadataconst bondMint = await dvp.createBondToken(issuer, {name: "ACME Commercial Paper Series A",symbol: "ACME-CP-A",decimals: 0, // Bonds are whole unitsmaturityDate: new Date("2026-12-31"),couponRate: 4.5, // 4.5% annual couponisin: "US0000000001",description: "https://acme.com/bonds/series-a"});// 5. Whitelist issuer and mint bondsconsole.log("\n🏦 Whitelisting issuer for bond holding...");const issuerBondAccount = await dvp.whitelist(bondMint,issuer.publicKey,settlementAgent);console.log("\n💰 Minting 100 bonds to issuer...");await mintTo(connection,issuer,bondMint,issuerBondAccount,issuer,100, // 100 bonds[],{ commitment: "confirmed" },TOKEN_2022_PROGRAM_ID);// 6. Whitelist investor (KYC/AML approved)await dvp.whitelist(bondMint, investor.publicKey, settlementAgent);// 7. Setup USDC for investorconsole.log("\n💵 Setting up USDC for investor...");const investorUSDCAccount = await getOrCreateAssociatedTokenAccount(connection,investor,USDC_MINT,investor.publicKey,false,"confirmed",{ commitment: "confirmed" },TOKEN_PROGRAM_ID);// In production, investor would acquire USDC from exchange/market// For this example, assume they have 95,000 USDC// 8. Delegate authority to settlement agentconsole.log("\n🔐 Delegating authority to settlement agent...");// Issuer delegates bondsawait dvp.delegateAuthority(issuer,issuerBondAccount,100, // 100 bonds0, // 0 decimalsTOKEN_2022_PROGRAM_ID);// Investor delegates USDCawait dvp.delegateAuthority(investor,investorUSDCAccount.address,95000, // $95,0006, // USDC decimalsTOKEN_PROGRAM_ID);// 9. Execute atomic DvP settlementconsole.log("\n⚡ Executing atomic DvP settlement...");console.log(" Terms: 100 bonds @ $950 each = $95,000\n");const result = await dvp.executeDvP({bondMint,usdcMint: USDC_MINT,bondAmount: 100,usdcAmount: 95000,issuer: issuer.publicKey,investor: investor.publicKey});console.log("\n✨ Settlement complete!");console.log(` Transaction: ${result.signature}`);console.log(` Timestamp: ${result.timestamp.toISOString()}`);console.log(` View on explorer: https://explorer.solana.com/tx/${result.signature}?cluster=devnet`);// 10. Verify balancesconsole.log("\n🔍 Verifying final balances...");const issuerBondInfo = await dvp.getAccountInfo(issuerBondAccount,TOKEN_2022_PROGRAM_ID);console.log(` Issuer bonds: ${issuerBondInfo.amount}`);const investorBondInfo = await dvp.getAccountInfo(await getAssociatedTokenAddress(bondMint,investor.publicKey,false,TOKEN_2022_PROGRAM_ID),TOKEN_2022_PROGRAM_ID);console.log(` Investor bonds: ${investorBondInfo.amount}`);console.log(` Investor frozen: ${investorBondInfo.isFrozen}`);}// Run the examplerunDvPExample().catch(console.error);
Funcionalidades Adicionais
Atualizando Metadados
O agente de liquidação (com autoridade de atualização) pode atualizar campos de metadados:
import { createUpdateFieldInstruction } from "@solana/spl-token-metadata";async function updateBondMetadata(connection: Connection,settlementAgent: Keypair,bondMint: PublicKey,field: string,value: string): Promise<void> {const transaction = new Transaction().add(createUpdateFieldInstruction({programId: TOKEN_2022_PROGRAM_ID,metadata: bondMint,updateAuthority: settlementAgent.publicKey,field: field,value: value}));await sendAndConfirmTransaction(connection, transaction, [settlementAgent]);}
Removendo da Lista de Permissões
Remova a capacidade de um investidor de deter títulos congelando sua conta usando o
método integrado removeFromWhitelist:
await dvp.removeFromWhitelist(bondMint, investorBondAccount);
Congelamento vs. Queima
Congelar uma conta impede transferências, mas preserva a conta e o saldo. Para remoção completa, talvez você queira primeiro transferir os títulos de volta ao emissor, em seguida congelar a conta.
Liquidação Multipartes
Para cenários mais complexos envolvendo múltiplas partes, você pode agrupar múltiplas transferências em uma única transação atômica:
import { sendAndConfirmTransaction } from "@solana/web3.js";import { createTransferCheckedInstruction } from "@solana/spl-token";interface TransferLeg {from: PublicKey;to: PublicKey;mint: PublicKey;amount: number;decimals: number;programId: PublicKey;}async function executeMultiPartyDvP(connection: Connection,settlementAgent: Keypair,legs: TransferLeg[]): Promise<string> {const transaction = new Transaction();// Add all transfer legs to single transactionfor (const leg of legs) {const fromAccount = await getAssociatedTokenAddress(leg.mint,leg.from,false,leg.programId);const toAccount = await getAssociatedTokenAddress(leg.mint,leg.to,false,leg.programId);// Add transfer instruction using delegated authoritytransaction.add(createTransferCheckedInstruction(fromAccount,leg.mint,toAccount,settlementAgent.publicKey, // Uses delegated authorityleg.amount * Math.pow(10, leg.decimals),leg.decimals,[],leg.programId));}// All legs settle atomically - either all succeed or all failconst signature = await sendAndConfirmTransaction(connection,transaction,[settlementAgent],{ commitment: "confirmed" });console.log(`✅ Multi-party DvP settled: ${legs.length} legs`);return signature;}
Limites de Tamanho de Transação
As transações da Solana têm um limite de tamanho (~1232 bytes). Cada instrução de transferência adiciona ~200 bytes. Para liquidações multipartes muito grandes, considere usar Address Lookup Tables para comprimir endereços de contas e incluir mais transferências por transação.
Considerações para Produção
Antes de implantar em produção, certifique-se de abordar:
- Segurança: Infraestrutura profissional de gestão de chaves, controles multi-sig, auditorias abrangentes do código-fonte
- Conformidade Regulatória: Registro de valores mobiliários, sistemas de KYC/AML, restrições de transferência e arcabouço jurídico
- Gestão de Chaves: Soluções profissionais de custódia com procedimentos adequados de backup e recuperação
- Processamento de Transações: Taxas de prioridade, lógica de reenvio, tratamento de confirmações e redundância de RPC para execução confiável de liquidações
- Operações: Agendamento de liquidações, tratamento de negociações com falha, reconciliação e suporte ao cliente
- Monitoramento: Rastreamento em tempo real, alertas e relatórios regulatórios automatizados
Limitação do SPL Token
As token accounts do SPL Token só podem ter um delegado por vez. Isso significa que, para cenários multipartes, pode ser necessário projetar em torno dessa restrição usando múltiplas delegações sequenciais ou diferentes padrões de arquitetura.
Inspecionando o Estado da Conta
O DvPEngine inclui um utilitário para inspecionar o estado de token accounts. Isso é útil
para verificar o status na lista de permissões, confirmar a conclusão da liquidação, depurar
problemas de transferência e auditar estados de contas.
// Get detailed account informationconst accountInfo = await dvp.getAccountInfo(investorBondAccount,TOKEN_2022_PROGRAM_ID);console.log("Account Information:");console.log(` Address: ${accountInfo.address.toBase58()}`);console.log(` Mint: ${accountInfo.mint.toBase58()}`);console.log(` Owner: ${accountInfo.owner.toBase58()}`);console.log(` Balance: ${accountInfo.amount}`);console.log(` Frozen: ${accountInfo.isFrozen}`);
Próximos Passos
Após entender os conceitos básicos de DvP na Solana:
-
Explorar Token Extensions: Saiba mais sobre outras extensões do Token 2022 como Transfer Hooks para funcionalidades adicionais de conformidade
-
Implementar Token ACL: Para necessidades de conformidade mais sofisticadas, considere usar Token ACL para implementar listas de permissão/bloqueio com capacidades de desbloqueio sem permissão. Isso permite que os usuários realizem a verificação de inclusão na lista de permissões de forma autônoma, mantendo o controle total de conformidade.
-
Aprofundamento Regulatório: Consulte especialistas jurídicos sobre regulamentações de valores mobiliários em sua jurisdição
-
Arquitetura para Produção: Projete sistemas robustos de gestão de chaves, monitoramento e recuperação de desastres
Conclusão
O modelo de transação atômica da Solana e as Token Extensions do Token 2022 fornecem uma base powerosa para implementar liquidações DvP em conformidade para valores mobiliários. A combinação de:
- Execução atômica nativa (sem risco de smart contract)
- Finalidade em menos de um segundo
- Custos de transação quase nulos
- Recursos integrados de conformidade (padrões congelados, metadados)
Torna a Solana uma plataforma ideal para modernizar a infraestrutura de liquidação de valores mobiliários.
No entanto, a transição desta referência educacional para a produção exige um trabalho adicional significativo em segurança, conformidade, custódia e operações. Sempre trabalhe com especialistas jurídicos, regulatórios e técnicos qualificados ao lidar com a tokenização de valores mobiliários.
Is this page helpful?