Typed Clients Blueprint
Clientes tipados são como TypeScript off-chain fala com um programa Solana sem codificar discriminators, account metas e layouts Borsh à mão. Quando você trata o IDL como contrato compartilhado e todo gerador de cliente como consumidor desse contrato, a API Program do Anchor, a saída Codama, helpers gill, builders de instrução e decoders de conta deixam de parecer bibliotecas concorrentes e passam a parecer um pipeline de anchor build até uma transação assinada.
Typed Clients Basics é a entrada prática; The Anchor TS Client, Codama, gill, Building Instructions, Fetching & Decoding Accounts e Keeping Clients in Sync aprofundam cada etapa. Esta página fica por baixo: como as peças se conectam, qual caminho escolher e o que fixar para que frontends e bots permaneçam honestos após upgrades de programa.
Resumo
- A superfície pública de um programa é descrita por um IDL; clientes tipados regeneram builders de instrução, codecs e helpers de fetch a partir desse JSON para que TypeScript não possa inventar layouts silenciosamente que divergem da codificação on-chain.
- Por que importa: Listas de contas e buffers de args escritos à mão derivam; uma superfície de cliente orientada por IDL reduz bugs de encode na mainnet, acelera trabalho de UI e bot, e permite que CI falhe quando a interface muda sem atualização do cliente.
- Conceitos-chave: Anchor IDL, Anchor TS
Program, Codama + @solana/kit, gill, builders de instrução tipados, helpers fetch/decode, discriminators e Borsh, regen em CI e checagens de drift. - Quando usar: Enviar ou manter apps TypeScript contra programas Anchor (ou descritos por IDL), escolher entre cliente Anchor clássico e stacks kit-first, ou desenhar gates de release em monorepo para programa mais frontend.
- Limitações / trade-offs: Qualidade do cliente acompanha qualidade do IDL; remaining accounts e alguns programas nativos precisam de docs extras; Anchor TS e Codama miram runtimes diferentes, então escolha uma história de transação por app; gill não gera a superfície IDL do seu programa.
- Tópicos relacionados: cliente Anchor TS, Codama, gill, construção de instruções, fetch e decode de contas, manter clientes em sync.
Fundamentos
Programas Solana expõem bytes: instruction data (geralmente um discriminator de 8 bytes mais args) e listas de contas com flags de signer e writable. Nada no wire é "nativo em TypeScript." Sem uma descrição compartilhada dessas formas, todo dApp, script e indexer inventa sua própria codificação e eventualmente discorda do programa.
Anchor preenche essa lacuna para programas framework. Macros em instructions, accounts, events e errors alimentam anchor build, que emite IDL JSON em target/idl/. Esse arquivo é o contrato para trabalho off-chain nesta seção: nomes de instruction e accounts, types, errors, events e metadados de program address. Clientes tipados existem para consumir esse contrato, não para substituí-lo.
Pense na stack off-chain como camadas do IDL até a UX:
+------------------------------------------+
| App / bot / API (business flows) | <- UI, jobs, wallets
+------------------------------------------+
| Convenience (optional gill helpers) | <- RPC + send patterns
+------------------------------------------+
| Program client surface |
| Codama-generated kit codecs / ixs |
| or Anchor TS Program.methods.* |
+------------------------------------------+
| Runtime primitives (@solana/kit 7.0.0) | <- RPC, messages, signers
+------------------------------------------+
| IDL artifact (JSON, git/npm pin) | <- versioned contract
+------------------------------------------+
| Program build (Anchor 0.32.1 + sBPF) |
+------------------------------------------+Duas histórias de program client em TypeScript dominam:
- Cliente Anchor TS (
@coral-xyz/anchor): carregue IDL emnew Program(...), chameprogram.methods.<ix>(...).accounts(...).rpc(). Encaixa bem emanchor test, dApps brownfield e equipes já em padrões Anchor Provider. - Codama: parse Anchor IDL em um grafo de nós e renderize módulos orientados a @solana/kit (
get*Instruction, helpersfetch*/decode*, mapas de erro). Encaixa bem em stacks kit greenfield e montagem de transação tree-shakable.
@solana/kit 7.0.0 é a camada moderna de RPC, codec, signer e transaction-message. Codama é a ponte usual de Anchor IDL para types kit. Kit sozinho não conhece os layouts de conta do seu programa; sem Codama (ou codecs escritos à mão) você volta a inventar bytes.
gill fica acima de kit como conveniência opcional: padrões de factory de cliente, RPC por moniker e helpers comuns de send. Ele não substitui a saída Codama do seu programa customizado. Você ainda gera builders e decoders específicos do programa a partir do IDL, depois os compõe com caminhos de send kit ou gill.
Reads e writes compartilham a mesma superfície gerada: builders codificam discriminator + args e account metas; helpers de fetch decodificam bytes RPC com o layout correspondente. Um gerador mantém ambos os caminhos alinhados.
Pins de plataforma neste site: Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1 e @solana/kit 7.0.0.
Mecânica e interações
IDL entra, superfície tipada sai
A espinha dorsal é sempre:
programs/.../lib.rs --macros--> anchor build
|
v
target/idl/foo.json
|
+--------------------------+--------------------------+
v v
Anchor TS Program(idl) Codama CLI + renderers
methods / account.fetch get*Instruction, fetch*
| |
v v
classic Provider / tests kit transaction messagesRegenere a cada mudança de interface pública. Editar à mão pastas geradas ou o JSON do IDL para "combinar com a UI" cria drift silencioso: o programa ainda codifica o layout definido por macro enquanto clientes codificam ficção. Detalhes de geração em Codama; o caminho clássico em The Anchor TS Client.
Escolhendo Anchor TS vs Codama
| Concern | Anchor TS Program | Codama + kit |
|---|---|---|
| Primary runtime | Modelo histórico web3.js / Provider | Messages e codecs @solana/kit 7.0.0 |
| DX shape | Fluent .methods / .rpc() | Builders explícitos + appendTransactionMessageInstruction |
| Best fit | Testes, dApps legados, protótipos Anchor rápidos | Apps kit greenfield, pacotes server/web compartilhados |
| Migration cost | Baixo se já no formato Anchor | Pague uma vez pela literacia do pipeline de messages kit |
Não misture montagem de transação kit com instruction objects web3.js sem uma ponte deliberada. Escolha um runtime de cliente por app e regenere quando o IDL mudar. Prefira Codama + kit para módulos novos; mantenha Anchor TS onde o custo de migração domina.
Construindo instruções
Um builder de instrução gerado responde: quais contas, quais flags, quais tipos de arg, qual discriminator. Você passa addresses e signers; o builder emite um instruction object nativo em kit (ou Anchor) pronto para append em uma transaction message.
getIncrementInstruction({ counter, authority })
|
v
Instruction {
programAddress,
accounts: [ { counter, writable }, { authority, signer } ],
data: discriminator || borsh(args)
}
|
v
append to TransactionMessage -> sign -> sendNunca reordene account metas à mão. Ordem e flags vêm do IDL; fluxos estilo init ainda precisam de System Program e contas de funding quando necessário. Aprofundamento: Building Instructions.
Fetch e decode de contas
Reads são o dual de writes:
- RPC retorna owner, lamports e data bytes (
getAccountInfoou um helper fetch gerado). - Decoder gerado checa discriminator / layout e retorna um objeto tipado.
- Chamadores tratam
null(contas ausentes ou fechadas) antes da UI ou lógica de negócio.
RPC getAccountInfo(address)
|
v
raw bytes + owner
|
v
decodeFoo / fetchFoo --> { data: { ... }, ... } | nullOwner errado, program id do cluster ou decoder obsoleto produzem lixo que parece válido até um write falhar. Prefira helpers fetch* gerados; use RPC bruto + decode* para batching customizado. Detalhes: Fetching & Decoding Accounts.
Onde gill se encaixa
gill reduz boilerplate de kit (criação de cliente, monikers, padrões send-and-confirm). Conhecimento específico do programa ainda vem de Codama (ou Anchor TS). Uma composição saudável é:
gill createSolanaClient --> rpc + send helpers
Codama generated module --> getIx / fetchAccount
App code --> compose bothTrate gill como aceleração sobre literacia de kit, não como caixa preta que inventa a API do seu programa. Veja gill.
Mantendo clientes em sync
Clientes tipados só permanecem corretos se a regeneração for mecânica e aplicada:
- Edite a superfície do programa sob Anchor 0.32.1; build com Agave/CLI e Rust fixados.
- Revise diff do IDL; commite o artefato se for a fonte de verdade da equipe.
- Rode Codama (ou atualize types Anchor); falhe CI em árvores geradas sujas.
- Rode testes unit/integration contra localnet ou harnesses estilo Surfpool.
- Coordene deploys de frontend/bot com deploys de programa quando a mudança for breaking.
- Tag releases com program id, cluster e hash de conteúdo IDL (ou commit SHA).
program change --> IDL diff --> client diff --> app rebuild --> deploy train
^
|
CI: git diff --exit-code generated/Fetch on-chain de IDL ajuda discovery; clientes de produção ainda fixam artefatos confiáveis. Prática completa: Keeping Clients in Sync.
Um dia de trabalho pelo pipeline
- Mude uma instruction ou account struct;
anchor build. - Confirme que
target/idlcorresponde à superfície pública pretendida. - Regenere clientes Codama (ou recarregue Anchor IDL em testes).
- Atualize call sites; corrija erros TypeScript.
- Simule a instruction; fetch e decode a conta afetada.
- Instale gates CI para que regen não possa ser pulada.
Considerações avançadas e aplicações
Combine idade da stack, escolha de runtime e rigor de release a um caminho, depois adicione gates quando drift multi-dev ou risco na mainnet aumentar.
| Path | O que você envia | Strengths | Weaknesses | Best fit |
|---|---|---|---|---|
| Anchor TS only | IDL + Program em app/testes | API fluent rápida; natural com testes Anchor | Migração kit depois; acoplamento histórico web3.js | dApps Anchor brownfield |
| Codama + kit | Codecs gerados em monorepo ou pacote | Stack kit moderna; messages explícitas | Passo de codegen e disciplina de pin | UIs e APIs de produto greenfield |
| Codama + kit + gill | Acima + helpers de cliente gill | Bootstrap mais rápido; padrões de send compartilhados | Outra versão para rastrear; ainda precisa Codama | Apps scaffolded e equipes pequenas |
| Multi-program monorepo | Um IDL e pasta gerada por programa | Namespaces claros; CI compartilhado | Colisões de nome se pastas se fundirem | Workspaces com vários crates de programa |
| Full release train | Hash IDL, pin npm/git, CI dirty-tree, deploy coordenado | Pronto para integradores; audit-friendly | Custo de processo | Programas mainnet com clientes externos |
Apps multi-programa: nunca funda superfícies IDL em um JSON. Namespace a saída gerada (clients/program_a, clients/program_b) e evite colisões de nome de export.
Indexers e bots também são clientes; um decoder obsoleto em worker é a mesma classe de bug que um hook de UI obsoleto, só mais silenciosa.
Programas nativos podem não ter Anchor IDL completo. Prefira IDL compatível mantido, Codama a partir de descrição customizada, ou codecs kit escritos à mão.
Remaining accounts frequentemente ficam fora de listas IDL fixas. Documente-os e passe explicitamente; codegen pode não inventar o grafo completo de contas em runtime.
Para design reviews: qual runtime TS você padroniza, quem é dono do artefato IDL, como CI detecta drift, se gill é permitido, e como mudanças breaking de IDL são lançadas.
Equívocos comuns
- "Clientes tipados significam que posso pular aprender kit messages." Builders ainda caem em transaction messages; simulação, fees e signers continuam sendo sua responsabilidade.
- "Anchor TS e Codama são substitutos drop-in." Ambos leem IDL, mas miram stacks de cliente diferentes; escolha um caminho primário de transação por app.
- "gill gera meu program client." gill ajuda em workflows kit; instructions e decoders específicos do programa ainda vêm de Codama ou Anchor TS.
- "Posso editar à mão arquivos gerados para um hotfix." A próxima regen apaga; coloque overrides apenas em módulos wrapper.
- "Se a UI type-check, o IDL combina com a mainnet." Types combinam com o IDL contra o qual você gerou, não necessariamente com o programa deployado; fixe program id, cluster e hash IDL.
- "Helpers fetch são polish opcional." Decoders compartilhados impedem dois layouts (caminho read vs write) de divergir dentro de um codebase.
- "Regen em CI é exagero para repo solo." Drift aparece na primeira vez que você muda um campo de conta e esquece um segundo pacote.
- "Importar o IDL JSON completo em runtime é sempre ok." IDLs grandes incham bundles; prefira módulos gerados tree-shakable ou loads lazy.
FAQs
Qual é a ideia mais importante em clientes tipados?
Um IDL versionado é o contrato compartilhado; todo helper TypeScript tipado é um consumidor regenerado desse contrato, não um ABI paralelo escrito à mão.
De onde vem o IDL?
Para programas Anchor, anchor build (0.32.1 neste site) emite JSON em target/idl/ a partir de macros. Commite e revise esse artefato como produto de API.
Quando devo usar o cliente Anchor TS?
Quando você mantém testes Anchor clássicos ou dApps brownfield no modelo Provider / .methods e ainda não está padronizando em montagem de transação kit.
Quando devo usar Codama?
Quando o app padroniza em @solana/kit 7.0.0 e você quer builders de instrução e decoders de conta gerados que combinem com Anchor IDL sem codecs à mão.
Como Codama se relaciona com Anchor IDL?
Codama ingere Anchor IDL JSON (via nodes-from-anchor e pacotes relacionados), constrói um grafo interno e renderiza TypeScript orientado a kit. Rebuild quando o IDL mudar e fixe versões CLI/renderer em CI.
gill é obrigatório?
Não. É açúcar opcional para padrões RPC e send de kit. Tipagem específica do programa ainda depende de Codama ou Anchor TS.
Como construo uma instrução tipada?
Chame o get*Instruction gerado (Codama) ou program.methods.* (Anchor TS) com accounts e args, depois coloque o resultado no caminho de send escolhido. Veja Building Instructions.
Como faço fetch de uma conta tipada?
Use helpers fetch* gerados com RPC kit, ou getAccountInfo mais decode*. Sempre trate contas ausentes e verifique suposições de owner/program id. Veja Fetching & Decoding Accounts.
O que quebra se IDL e programa divergirem?
Discriminators errados, ordem de contas ou layouts causam falhas de simulação, custom errors crípticos, decodes de conta corrompidos ou mentiras silenciosas na UI que só falham no write.
Como CI deve manter clientes em sync?
Build o programa, regenere clientes, git diff --exit-code em paths gerados, e rode testes. Combine com tags de release que incluam hash de programa e versão IDL. Veja Keeping Clients in Sync.
Posso misturar kit e web3.js em uma feature?
Apenas com uma ponte explícita. Prefira um runtime por limite de feature para que types de instruction e address não oscilem.
Clientes tipados substituem validação on-chain?
Não. Clientes reduzem erros de encode; o programa ainda aplica constraints, ownership e regras de signer. Simulação continua obrigatória para fluxos sérios.
Como monorepos multi-programa permanecem limpos?
Um IDL e um diretório de saída gerada por programa, regen CI compartilhada para todos, e exports de pacote explícitos para que paths de import não cruzem fios silenciosamente.
Onde @solana/kit se encaixa em relação a Codama?
Kit é a stack RPC e de transação (este site: 7.0.0). Codama faz a ponte de Anchor IDL para essa stack. Kit não compila sBPF nem é dono do formato IDL.
Related
- The Anchor TS Client -
Program, methods e fluxos Provider clássicos - Codama - gerando clientes @solana/kit a partir de Anchor IDL
- gill - helpers kit de nível superior para caminhos RPC e send comuns
- Building Instructions - builders de instrução tipados em transaction messages
- Fetching & Decoding Accounts - reads tipados com codecs gerados
- Keeping Clients in Sync - regeneração orientada por IDL e gates de drift em CI
Stack versions: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1 e @solana/kit 7.0.0.