Guia de integração de valor de interface escalada
Suportando a extensão de valor de interface escalada no Solana
Contexto
A extensão Scaled UI Amount permite que os emissores de tokens especifiquem um multiplicador a ser usado ao calcular o valor na interface do usuário do saldo de tokens de um usuário. Isso permite que os emissores criem tokens com rebase e habilitem coisas como desdobramentos de ações. Esta extensão, como a extensão de token com rendimento de juros, fornece um valor de interface puramente cosmético, o que significa que as equipes precisam fazer algum trabalho adicional para proporcionar 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 UIAmount (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 UIAmount
- UIAmount: multiplicador * valor bruto (também conhecido como: valor escalado)
- Valor bruto: quantidade (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 scaled UI
amount para usuários finais, você deve usar:
- UIAmount/UIAmountString (preferível)
- 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 UIAmount 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 Amount 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 da 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 a quantidade 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 for definido para uma data futura, você pode automaticamente fazer polling neste momento de atualização
Quantidades de tokens em transações (transferências / trocas etc)
- Os usuários devem inserir quantidades para serem interpretadas como "UIAmount"
escalado. O aplicativo que precisa processar isso deve converter para a
quantidade bruta de tokens para a transação.
- Se houver problemas de arredondamento, arredonde para baixo e prefira deixar uma pequena quantidade de resíduo 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 a quantidade bruta total quando um usuário solicita
fazer 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 escalado sempre que possível.
- Se você é um provedor de serviço de feed de preços, como um oráculo, você deve
expor tanto o preço escalado quanto o não escalado.
- Sempre que possível, forneça um SDK/API que abstraia as complexidades da extensão de UIAmount escalado.
Multiplicador atual
- O multiplicador atual pode ser lido do mint do token a qualquer momento
chamando
getAccountInfo
. Além disso, se um multiplicador futuro estiver definido, esta informação também está disponível no mint 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 exibir tanto os preços escalados quanto os não escalados para a extensão de valor de UI escalada.
- Esperamos que os valores escalados sejam usados com mais frequência, pois isso se alinha com a forma como o mundo financeiro tradicional trata gráficos relacionados a tokens com desdobramentos de ações.
Dados históricos para quantidades
- 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 aplicativos que não compreendem a extensão de valor de UI 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 valor de UI escalada e estamos felizes em fornecer suporte durante este processo.
Prioridades de integração recomendadas por plataforma
Requisitos gerais
Requisito | Descrição | Prioridade |
---|---|---|
Suportar ações do usuário usando UiAmount | Todas as ações do usuário devem ser inseridas em UiAmount quando o UiAmount estiver habilitado 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 o valor escalado (uiAmount) como o saldo principal. | P0 |
Suporte para transferências de tokens | Os usuários finais devem inserir valores de transferência com seus saldos escalados (valor bruto * 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 o valor escalado (UIAmount) para cada transferência sempre que possível. | P1 |
Mostrar atualizações de multiplicador no histórico | Quando ocorrerem atualizações de multiplicador, mostrar como um evento no histórico de transações 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 | Oferecer dicas ou integração para educar os usuários sobre tokens que usam a extensão de valor escalado | 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 escalado. | P0 |
Fornecimento total com ajuste escalado | Ao exibir o fornecimento total e a capitalização total de mercado, levar em conta 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 multiplicadores | Fornecer marcadores históricos de atualizações de multiplicadores 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 multiplicadores | Oferecer APIs com mudanças históricas de multiplicadores. | P0 |
Dados históricos de preços | Oferecer APIs com preços históricos baseados em quantidades escaladas e não escaladas. | P0 |
DEXes
Requisito | Descrição | Prioridade |
---|---|---|
Exibir saldos de tokens rebaseados | Mostrar saldos escalados para negociação ou provisão de liquidez na UI. (o backend ainda pode usar quantidades brutas) | P0 |
Suporte para ações de tokens | Os usuários finais devem inserir quantidades de ação com seus saldos UiAmount (multiplicador * quantidade bruta). | P0 |
Adaptação de 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?