Suporte à extensão Scaled UI Amount na Solana
Contexto
A extensão Scaled UI Amount permite que emissores de tokens especifiquem um multiplicador a ser usado ao calcular o valor de UI do saldo de tokens de um utilizador. Isso permite que emissores criem tokens de rebase e habilitem coisas como desdobramentos de ações. Esta extensão, assim como a extensão de token com juros, fornece um valor de UI puramente cosmético, o que significa que as equipas precisam fazer algum trabalho adicional para proporcionar uma boa experiência. Cálculos e transferências subjacentes ocorrem todos usando os valores brutos no programa.
Recursos:
Resumo
- Utilizadores finais devem interagir com o UIAmount (valor bruto * multiplicador) para o preço do token, saldo do token e valores de tokens sempre que possível
- dApps e fornecedores de serviços devem usar o valor bruto e preços não escalados para todos os cálculos e converter para os utilizadores na interface
- 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 que é usado para cálculos de UI Amount
- UIAmount: 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 exibir valores para tokens que usam a extensão scaled UI amount
para utilizadores finais, deve usar:
- UIAmount/UIAmountString (preferencial)
- Um cálculo manual de valor bruto * multiplicador
- Recomendamos truncar este valor com base no número de casas decimais que o
token possui.
- Ex: se yUSD tem 6 casas decimais e um utilizador tem um UIAmount de 1.123456789, deve exibir "1.123456"
Onde obter estes dados:
- Para o saldo atual de um utilizador, pode obter informações atualizadas sobre os valores acima chamando getTokenAccountBalance ou getAccountInfo
- Se precisar de saber o UI Amount para um valor arbitrário, 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 taxas 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
$ curl http://localhost:8899 -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 1, "method": "getTokenAccountBalance", "params": ["2uuvxpnEKw52aTqNerHiQ3WeSqZriCMNVt8LhWfrkbPk"]}' | jq .{"jsonrpc": "2.0","result": {"context": {"apiVersion": "2.2.14","slot": 381130751},"value": {"amount": "10000000","decimals": 6,"uiAmount": 20.0,"uiAmountString": "20"}},"id": 1}
getAccountInfo- Retorna as informações da conta e as informações do mint
$ curl http://localhost:8899 -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 1, "method": "getAccountInfo", "params": ["2uuvxpnEKw52aTqNerHiQ3WeSqZriCMNVt8LhWfrkbPk", {"encoding": "jsonParsed"}]}' | jq .{"jsonrpc": "2.0","result": {"context": {"apiVersion": "2.2.14","slot": 381131001},"value": {"data": {"parsed": {"info": {"extensions": [{"extension": "immutableOwner"},{"extension": "pausableAccount"}],"isNative": false,"mint": "BZCd6HfTbb5ZYJ8hQsm8282tG4QzLyeqFR6tdgQA9EAG","owner": "G7ARQSUCwNrfvTDUCZvM5xdiRdBJiN3qVw2PryD8Wnib","state": "initialized","tokenAmount": {"amount": "10000000","decimals": 6,"uiAmount": 20.0,"uiAmountString": "20"}},"type": "account"},"program": "spl-token-2022","space": 174},"executable": false,"lamports": 2101920,"owner": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb","rentEpoch": 18446744073709551615,"space": 174}},"id": 1}
Atualizar o valor atual
Como os emissores podem atualizar o multiplicador a qualquer momento, 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, pode fazer polling automaticamente nesse momento de atualização
Valores de tokens em transações (transferências / swaps, etc.)
- Os utilizadores devem inserir valores a serem interpretados como o “UIAmount”
escalado. A aplicação que tem de processar isto 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 residual em vez de arriscar a falha da transação
- Para fazer esta conversão, 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 */
- As aplicações devem usar o valor bruto total quando um utilizador solicita
realizar uma ação com “máximo” ou “tudo” do seu saldo. Isto garante que não
sobra nenhum resíduo.
- Opcional: Pode considerar fechar automaticamente uma conta quando “máximo” é usado para reembolsar o utilizador do seu depósito de armazenamento
Preço do token
- O preço do token deve ser sempre apresentado como o preço escalado sempre que possível.
- Se é um fornecedor de serviços de feed de preços, como um oráculo, deve expor
tanto o preço escalado como o não escalado.
- Sempre que possível, forneça um SDK/API que abstraia as complexidades da extensão de valor de interface escalado.
Multiplicador atual
- O multiplicador atual pode ser lido a partir do mint do token a qualquer
momento chamando
getAccountInfo. Adicionalmente, 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 utilizador.
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
- Os serviços que fornecem dados históricos devem armazenar e apresentar tanto os preços escalados como os não escalados para a extensão de valor de interface escalado.
- Esperamos que os valores escalados sejam usados com mais frequência, pois isto alinha-se com a forma como o mundo das finanças tradicionais trata gráficos relacionados com tokens com divisões de ações.
- As atualizações do multiplicador podem incluir um carimbo temporal que está no passado. Recomendamos usar o carimbo temporal do bloco para dados históricos.
- Note que o multiplicador ativo pode ser o "multiplicador" ou o "novoMultiplicador" dependendo do carimbo temporal atual e de quando o novo multiplicador está definido para estar ativo.
Dados históricos para valores
- Se você deseja mostrar o saldo transferido no passado, precisa ter acesso ao multiplicador naquele slot específico. Você também pode salvar o UiAmount para transferências conforme processa as transações para evitar fazer esse cálculo no futuro.
Compatibilidade retroativa
- Por padrão, carteiras e aplicativos que não entendem a extensão de valor escalado na interface mostrarão o preço total correto de uma atividade multiplicando o preço não escalado * valor bruto.
- Eles, no entanto, exibiriam o preço não escalado, causando alguma confusão ao usuário.
- Esperamos que isso incentive as equipes a atualizar seus dapps para serem compatíveis com tokens que usam a extensão de valor escalado na interface e estamos felizes em fornecer suporte durante esse 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 valores brutos 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 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 | Oferecer dicas ou integração para educar os usuários sobre tokens que usam a extensão de valor escalado na interface | 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 os detalhes sobre a atualização do multiplicador | P2 |
Agregadores de dados de mercado (ex: CoinGecko, Birdeye)
| 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 de mercado total, levar em conta os saldos escalados | P0 |
| Rastreamento de preços históricos | 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 que rendem juros. Note que as atualizações de multiplicador podem incluir um carimbo de data/hora que está no passado. Recomendamos usar o carimbo de data/hora do bloco em vez do carimbo de data/hora indicado na atualização do multiplicador para dados históricos. | P2 |
| Conteúdo educacional ou explicações | Incluir descrições breves 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 para preços escalados e não escalados. | P0 |
| Dados históricos de multiplicador | Oferecer APIs com mudanças históricas de multiplicador. Observe que as atualizações de multiplicador podem incluir um carimbo de data/hora que está no passado. Recomendamos usar o carimbo de data/hora do bloco em vez do carimbo de data/hora indicado na atualização do multiplicador para dados históricos. | 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 fornecimento 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 de feed de preços | Em qualquer lugar onde um feed de preços seja 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 |
CEXes
| Requisito | Descrição | Prioridade |
|---|---|---|
| Rastrear atualizações de multiplicador | Rastrear atualizações de multiplicador para tokens que usam a extensão de valor de ui escalada. | P0 |
| Exibir saldos de tokens rebaseados | Mostrar saldos escalados para negociação ou fornecimento 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 |
| Ações históricas não devem ser reescaladas | Ações históricas como negociações devem ser exibidas usando o valor escalado e o preço precisos no momento da ação. | P1 |
| Rastrear internamente saldos brutos | Rastrear saldos brutos para transações onchain em vez de saldos escalados. Isso será mais preciso e mais fácil de gerenciar a longo prazo. | P1 |
| Adaptação de feed de preços | Em qualquer lugar onde um feed de preços seja 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. Isso inclui reescalar preços históricos para o multiplicador atual. | P1 |
| Escalar base de custo | O custo por ação deve ser escalado para o multiplicador atual. | P1 |
Is this page helpful?