Guia de integração de valor de interface escalada
Suportando a extensão de valor de interface escalada no Solana
Contexto
A extensão de valor de interface escalada permite que os emissores de tokens especifiquem um multiplicador a ser usado ao calcular o valor de interface do saldo de tokens de um usuário. Isso permite que os emissores criem tokens de rebase e possibilitem coisas como desdobramentos de ações. Esta extensão, como a extensão de token com juros, fornece um valor de interface puramente cosmético que significa que as equipes precisam fazer algum trabalho adicional para fornecer uma boa experiência. Os cálculos e transferências subjacentes ocorrem usando os valores brutos no programa.
Recursos:
- Documentação para desenvolvedores
- Código Rust da extensão
- Código Rust de conversão de valor para valor de interface
Resumo
- Os usuários finais devem interagir com o valor de interface (valor bruto * multiplicador) para o preço do token, saldo do token e quantidades de token sempre que possível
- dApps e provedores de serviços devem usar o valor bruto e preços não escalados para todos os cálculos e converter para os usuários na borda
- Feeds de preços históricos precisam ser fornecidos tanto para valores escalados quanto não escalados para facilitar a integração
- Valores históricos do multiplicador precisam estar acessíveis para dados históricos precisos
Definições de termos
- Multiplicador: multiplicador estático atualizável usado para cálculos de valor de interface
- Valor de interface: multiplicador * valor bruto (também conhecido como: valor escalado)
- Valor bruto: valor (também conhecido como: valor não escalado)
Saldo atual
Valor atual para exibição
- Sempre que você exibir valores para tokens que usam a extensão de valor de
interface escalada para usuários finais, você deve usar:
- Valor de interface/String de valor de interface (preferido)
- Um cálculo manual de valor bruto * multiplicador
- Recomendamos truncar este valor com base no número de decimais que o token
possui.
- Ex: se yUSD tem 6 decimais e um usuário tem um valor de interface de 1.123456789, você deve exibir "1.123456"
Onde obter estes dados:
- Para o saldo em tempo real de um usuário, você pode obter informações atualizadas sobre os valores acima chamando getTokenAccountBalance ou getAccountInfo
- Se você precisar saber o Valor UI para um valor arbitrário, você pode obter
este cálculo chamando a função
amountToUiAmountForMintWithoutSimulation
(web3.js v1) ou simulando uma transação usando amountToUiAmount.- Nota: amountToUiAmount requer uma simulação de transação, o que significa que também precisa de um pagador de taxa válido com saldo. Por isso, esta não deve ser a forma padrão de obter um saldo.
Chamadas RPC
getTokenAccountBalance
- Retorna o saldo do token account e as informações do mint
import { address, createSolanaRpc } from "@solana/kit";const rpc_url = "https://api.devnet.solana.com";const rpc = createSolanaRpc(rpc_url);let tokenAddress = address("2uuvxpnEKw52aTqNerHiQ3WeSqZriCMNVt8LhWfrkbPk");let tokenBalance = await rpc.getTokenAccountBalance(tokenAddress).send();console.log("Token Balance:", tokenBalance);/* Token Balance: {context: { apiVersion: '2.2.14', slot: 381132711n },value: {amount: '10000000',decimals: 6,uiAmount: 20,uiAmountString: '20'}} */
getAccountInfo
- Retorna as informações da conta e as informações do mint
import { address, createSolanaRpc } from "@solana/kit";const rpc_url = "https://api.devnet.solana.com";const rpc = createSolanaRpc(rpc_url);const publicKey = address("2uuvxpnEKw52aTqNerHiQ3WeSqZriCMNVt8LhWfrkbPk");const accountInfo = await rpc.getAccountInfo(publicKey).send();console.log("Account Info:",JSON.stringify(accountInfo,(key, value) => (typeof value === "bigint" ? value.toString() : value),2));/* Account Info: {"context": {"apiVersion": "2.2.14","slot": "381133640"},"value": {"data": {"parsed": {"info": {"extensions": [{"extension": "immutableOwner"},{"extension": "pausableAccount"}],"isNative": false,"mint": "BZCd6HfTbb5ZYJ8hQsm8282tG4QzLyeqFR6tdgQA9EAG","owner": "G7ARQSUCwNrfvTDUCZvM5xdiRdBJiN3qVw2PryD8Wnib","state": "initialized","tokenAmount": {"amount": "10000000","decimals": 6,"uiAmount": 20,"uiAmountString": "20"}},"type": "account"},"program": "spl-token-2022","space": "174"},"executable": false,"lamports": "2101920","owner": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb","rentEpoch": "18446744073709551615","space": "174"}} */
Atualizando o valor atual
Como os emissores podem atualizar o multiplicador a qualquer momento, você pode considerar fazer polling ocasionalmente para manter o saldo da conta atualizado. É improvável que os emissores atualizem este multiplicador mais de uma vez por dia. Se um multiplicador estiver definido para uma data futura, você pode automaticamente fazer polling neste momento de atualização
Valores de token em transações (transferências / trocas etc)
- Os usuários devem inserir valores para serem interpretados como o "UIAmount"
escalado. O aplicativo que precisa processar isso deve converter para o valor
bruto do token para a transação.
- Se houver problemas de arredondamento, arredonde para baixo e prefira deixar uma pequena quantidade de poeira em vez de arriscar a falha da transação
- Para fazer esta conversão, você pode usar a função
uiAmountToAmountForMintWithoutSimulation
(web3.js v1) ou simular uma transação usando amountToUiAmount.
import { uiAmountToAmountForMintWithoutSimulation } from "@solana/web3.js";import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";const connection = new Connection(clusterApiUrl("devnet"), "confirmed");const mint = new PublicKey("BZCd6HfTbb5ZYJ8hQsm8282tG4QzLyeqFR6tdgQA9EAG");const uiAmount = "20.2";const rawAmount = await uiAmountToAmountForMintWithoutSimulation(connection as unknown as Connection,mint,uiAmount);console.log("Raw Amount:", rawAmount);/* Raw Amount: 20200000 */
- Os aplicativos devem usar o valor bruto total quando um usuário solicita
realizar uma ação com "máximo" ou "todo" o seu saldo. Isso garante que não
haja resíduos.
- Opcional: Você pode considerar fechar automaticamente uma conta quando "máximo" é usado para reembolsar o usuário de seu depósito de armazenamento
Preço do token
- O preço do token deve sempre ser exibido como o preço escalonado sempre que possível.
- Se você é um provedor de serviço de feed de preços, como um oráculo, deve
expor tanto o preço escalonado quanto o não escalonado.
- Sempre que possível, forneça um SDK/API que abstraia as complexidades da extensão de valor da UI escalonada.
Multiplicador atual
- O multiplicador atual pode ser lido da emissão do token a qualquer momento
chamando
getAccountInfo
. Além disso, se um multiplicador futuro estiver definido, esta informação também está disponível na emissão do token. Recomendamos não mostrar este multiplicador, pois pode confundir a experiência do usuário.
import { address, createSolanaRpc } from "@solana/kit";const rpc_url = "https://api.devnet.solana.com";const rpc = createSolanaRpc(rpc_url);const publicKey = address("BZCd6HfTbb5ZYJ8hQsm8282tG4QzLyeqFR6tdgQA9EAG");const accountInfo = await rpc.getAccountInfo(publicKey, { encoding: "jsonParsed" }).send();const mintData = accountInfo.value?.data as Readonly<{parsed: {info?: {extensions: {extension: string;state: object;}[];};type: string;};program: string;space: bigint;}>;const scaledUiAmountConfig = mintData.parsed.info?.extensions?.find((extension) => extension.extension === "scaledUiAmountConfig") as Readonly<{state: {newMultiplierEffectiveTimestamp: number;newMultiplier: number;multiplier: number;};}>;const currentMultiplier =scaledUiAmountConfig?.state &&Date.now() / 1000 >=scaledUiAmountConfig.state.newMultiplierEffectiveTimestamp? scaledUiAmountConfig.state.newMultiplier: scaledUiAmountConfig.state.multiplier;console.log("Scaled UI Amount Config:", scaledUiAmountConfig);console.log("Current Multiplier:", currentMultiplier);/*Scaled UI Amount Config: {extension: 'scaledUiAmountConfig',state: {authority: 'G7ARQSUCwNrfvTDUCZvM5xdiRdBJiN3qVw2PryD8Wnib',multiplier: '2',newMultiplier: '2',newMultiplierEffectiveTimestamp: 1743000000n}}Current Multiplier: 2*/
Dados históricos
Dados históricos para feed de preços
- Serviços que fornecem dados históricos devem armazenar e apresentar tanto os preços escalonados quanto os não escalonados para a extensão de valor da UI escalonada.
- Esperamos que os valores escalonados sejam usados com mais frequência, pois isso se alinha com como o mundo financeiro tradicional trata gráficos relacionados a tokens com desdobramentos de ações.
Dados históricos para valores
- Se você deseja mostrar o saldo transferido no passado, precisa ter acesso ao multiplicador naquele determinado slot. Você também pode salvar o UiAmount para transferências enquanto processa transações para evitar fazer esse cálculo no futuro.
Compatibilidade retroativa
- Por padrão, carteiras e aplicações que não compreendem a extensão de quantidade de interface do usuário escalada mostrarão o preço total correto de uma atividade multiplicando o preço não escalado * quantidade bruta.
- No entanto, eles exibiriam o preço não escalado, causando alguma confusão para o usuário.
- Esperamos que isso incentive as equipes a atualizarem seus dapps para serem compatíveis com tokens que usam a extensão de quantidade de interface do usuário escalada e estamos felizes em fornecer suporte durante este processo.
Prioridades de integração recomendadas por plataforma
Requisitos gerais
Requisito | Descrição | Prioridade |
---|---|---|
Suporte a ações do usuário usando UiAmount | Todas as ações do usuário devem ser inseridas em UiAmount quando o UiAmount estiver ativado em todo o aplicativo. Se o UiAmount não estiver visível no aplicativo, eles devem usar quantidades brutas até que o aplicativo seja atualizado. | P0 |
Carteiras
Requisito | Descrição | Prioridade |
---|---|---|
Exibir saldo escalado | Mostrar a quantidade escalada (uiAmount) como o saldo principal. | P0 |
Suporte para transferências de tokens | Os usuários finais devem inserir os valores de transferência com seus saldos escalados (quantidade bruta * saldo). | P0 |
Exibir preço à vista | Exibir o preço à vista escalado para os usuários | P0 |
Metadados do histórico de transações | Mostrar a quantidade escalada (UIAmount) para cada transferência sempre que possível. | P1 |
Mostrar atualizações de multiplicador no histórico de transações | Quando ocorrerem atualizações de multiplicador, mostrar isso como um evento no histórico de transações do usuário, incluindo o valor ganho | P2 |
Exibir gráfico de histórico de preços | Refletir os preços escalados no gráfico de preços | P1 |
Integração/dicas de ferramentas | Oferecer dicas de ferramentas ou integração para educar os usuários sobre tokens que usam a extensão de quantidade de interface do usuário escalada | P2 |
Exploradores
Requisito | Descrição | Prioridade |
---|---|---|
Melhorias na página de detalhes do token | Exibir metadados como capitalização de mercado escalada total e multiplicador atual | P0 |
Exibir saldo escalado para saldos | Exibir saldos escalados (UiAmount) para saldos atuais. | P0 |
Exibir saldo escalado para transações | Exibir saldos escalados (UiAmount) para valores de transferência em transações históricas. | P0 |
Exibir preço escalado para transações | Exibir preços escalados para transações anteriores | P1 |
Analisar e exibir corretamente transações de atualização de multiplicador | Mostrar corretamente detalhes sobre a atualização do multiplicador | P2 |
Agregadores de dados de mercado (Ex: CoinGecko)
Requisito | Descrição | Prioridade |
---|---|---|
Atualizações de API para dados escalados | Estender a funcionalidade da API para incluir mudanças de multiplicador ao longo do tempo, bem como o feed de preços escalados. | P0 |
Fornecimento total com ajuste escalado | Ao exibir o fornecimento total e a capitalização total de mercado, considerar os saldos escalados | P0 |
Rastreamento histórico de preços | Fornecer um gráfico histórico de preços usando o preço escalado ao longo do tempo. | P1 |
Rastreamento histórico de multiplicador | Fornecer marcadores históricos de atualizações de multiplicador para tokens com rendimento de juros. | P2 |
Conteúdo educacional ou explicações | Incluir breves descrições ou dicas explicando como funcionam os tokens escalados. | P2 |
Provedores de feed de preços
Requisito | Descrição | Prioridade |
---|---|---|
Feeds de preços escalados e não escalados | Fornecer feeds de preços tanto para preços escalados quanto não escalados. | P0 |
Dados históricos de multiplicador | Oferecer APIs com mudanças históricas de multiplicador. | P0 |
Dados históricos de preços | Oferecer APIs com preços históricos baseados em valores escalados e não escalados. | P0 |
DEXes
Requisito | Descrição | Prioridade |
---|---|---|
Exibir saldos de tokens rebaseados | Mostrar saldos escalados para negociação ou provisão de liquidez na interface. (o backend ainda pode usar valores brutos) | P0 |
Suporte para ações de tokens | Os usuários finais devem inserir valores de ação com seus saldos UiAmount (multiplicador * valor bruto). | P0 |
Adaptação do feed de preços | Em qualquer lugar onde um feed de preços é usado para exibir o preço atual, fornecer o preço escalado aos usuários finais. | P1 |
Exibir gráfico de histórico de preços | Refletir os preços escalados no gráfico de preços | P1 |
Is this page helpful?