Guía de integración de cantidad escalada de UI
Soporte de la extensión de cantidad escalada de UI en Solana
Antecedentes
La extensión de cantidad escalada de UI permite a los emisores de tokens especificar un multiplicador que se utilizará al calcular la cantidad de UI del saldo de tokens de un usuario. Esto permite a los emisores crear tokens con rebase y habilitar cosas como divisiones de acciones. Esta extensión, al igual que la extensión de token con interés, proporciona una cantidad de UI puramente cosmética, lo que significa que los equipos necesitan realizar un trabajo adicional para ofrecer una buena experiencia. Los cálculos subyacentes y las transferencias se realizan utilizando las cantidades brutas en el programa.
Recursos:
- Documentación para desarrolladores
- Código Rust de la extensión
- Código Rust de conversión de cantidad a cantidad UI
Resumen
- Los usuarios finales deben interactuar con la UIAmount (cantidad bruta * multiplicador) para el precio del token, el saldo del token y las cantidades de tokens siempre que sea posible
- Las dApps y los proveedores de servicios deben usar la cantidad bruta y los precios no escalados para todos los cálculos y convertirlos para los usuarios en el extremo
- Es necesario proporcionar feeds de precios históricos tanto para cantidades escaladas como no escaladas para una integración más sencilla
- Los valores históricos del multiplicador deben ser accesibles para obtener datos históricos precisos
Definiciones de términos
- Multiplicador: multiplicador estático actualizable que se utiliza para los cálculos de cantidad de UI
- UIAmount: multiplicador * cantidad bruta (también conocido como: cantidad escalada)
- Cantidad bruta: cantidad (también conocido como: cantidad no escalada)
Saldo actual
Cantidad actual para mostrar
- Siempre que muestres cantidades de tokens que utilizan la extensión de
cantidad escalada de UI a los usuarios finales, deberías usar:
- UIAmount/UIAmountString (preferido)
- Un cálculo manual de cantidad bruta * multiplicador
- Recomendamos truncar este valor según el número de decimales que tenga el
token.
- Ej: si yUSD tiene 6 decimales y un usuario tiene una UIAmount de 1.123456789, deberías mostrar "1.123456"
Dónde obtener estos datos:
- Para el saldo en vivo de un usuario, puedes obtener información actualizada sobre las cantidades anteriores llamando a getTokenAccountBalance o getAccountInfo
- Si necesitas conocer la Cantidad UI para una cantidad arbitraria, puedes
obtener este cálculo llamando a la función
amountToUiAmountForMintWithoutSimulation
(web3.js v1) o simulando una transacción usando amountToUiAmount.- Nota: amountToUiAmount requiere una simulación de transacción, lo que significa que también necesita un pagador de comisiones válido con saldo. Por esta razón, esta no debería ser la forma predeterminada de obtener un saldo.
Llamadas RPC
getTokenAccountBalance
- Devuelve el saldo del token account y la información del 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
- Devuelve la información de la cuenta y la información del 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"}} */
Actualizando la cantidad actual
Debido a que los emisores pueden actualizar el multiplicador en cualquier momento, puedes considerar realizar sondeos ocasionales para mantener actualizado el saldo de la cuenta. Es poco probable que los emisores actualicen este multiplicador más de una vez al día. Si se establece un multiplicador para una fecha futura, puedes realizar sondeos automáticamente en este momento de actualización
Cantidades de tokens en transacciones (transferencias / intercambios, etc.)
- Los usuarios deben ingresar cantidades que se interpretarán como "UIAmount"
escalado. La aplicación que tiene que procesar esto debe convertirlo a la
cantidad bruta de tokens para la transacción.
- Si hay problemas de redondeo, redondea hacia abajo y es preferible dejar una pequeña cantidad de polvo en lugar de arriesgar que la transacción falle
- Para hacer esta conversión puedes usar la función
uiAmountToAmountForMintWithoutSimulation
(web3.js v1) o simular una transacción 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 */
- Las aplicaciones deben usar la cantidad total bruta cuando un usuario solicita
realizar una acción con "máximo" o "todo" su saldo. Esto asegura que no queden
restos.
- Opcional: Puedes considerar cerrar automáticamente una cuenta cuando se utiliza "máximo" para reembolsar al usuario su depósito de almacenamiento
Precio del token
- El precio del token siempre debe mostrarse como el precio escalado siempre que sea posible.
- Si eres un proveedor de servicios de alimentación de precios, como un oráculo,
debes exponer tanto el precio escalado como el no escalado.
- Siempre que sea posible, proporciona un SDK/API que abstraiga las complejidades de extensión de cantidad UI escalada.
Multiplicador actual
- El multiplicador actual puede leerse desde el mint del token en cualquier
momento llamando a
getAccountInfo
. Además, si se establece un multiplicador futuro, esta información también está disponible desde el mint del token. Recomendamos no mostrar este multiplicador ya que puede confundir la experiencia de usuario.
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*/
Datos históricos
Datos históricos para alimentación de precios
- Los servicios que proporcionan datos históricos deben almacenar y mostrar tanto los precios escalados como los no escalados para la extensión de cantidad UI escalada.
- Esperamos que las cantidades escaladas se utilicen con mayor frecuencia, ya que esto se alinea con cómo el mundo financiero tradicional trata los gráficos relacionados con tokens con divisiones de acciones.
Datos históricos para cantidades
- Si deseas mostrar el saldo transferido en el pasado, necesitas acceso al multiplicador en ese slot específico. También puedes guardar la UiAmount para transferencias mientras procesas transacciones para evitar hacer este cálculo en el futuro.
Compatibilidad con versiones anteriores
- Por defecto, las carteras y aplicaciones que no entienden la extensión de cantidad UI escalada mostrarán el precio total correcto de una actividad multiplicando el precio no escalado * cantidad bruta.
- Sin embargo, mostrarían el precio no escalado, lo que podría causar confusión en los usuarios.
- Esperamos que esto anime a los equipos a actualizar sus dapps para que sean compatibles con tokens que utilizan la extensión de cantidad UI escalada y estamos dispuestos a proporcionar soporte durante este proceso.
Prioridades de integración recomendadas por plataforma
Requisitos generales
Requisito | Descripción | Prioridad |
---|---|---|
Soporte de acciones de usuario usando UiAmount | Todas las acciones del usuario deben ingresarse en UiAmount cuando UiAmount esté habilitado en toda la aplicación. Si UiAmount no es visible en la aplicación, deben usar cantidades brutas hasta que la aplicación se actualice. | P0 |
Carteras
Requisito | Descripción | Prioridad |
---|---|---|
Mostrar saldo escalado | Mostrar la cantidad escalada (uiAmount) como el saldo principal. | P0 |
Soporte para transferencias de tokens | Los usuarios finales deben ingresar las cantidades de transferencia con sus saldos escalados (cantidad bruta * saldo). | P0 |
Mostrar precio de mercado | Mostrar el precio de mercado escalado para los usuarios | P0 |
Metadatos del historial de transacciones | Mostrar la cantidad escalada (UIAmount) para cada transferencia siempre que sea posible. | P1 |
Mostrar actualizaciones de multiplicador en el historial de transacciones | Cuando ocurran actualizaciones del multiplicador, mostrar esto como un evento en el historial de transacciones del usuario, incluyendo la cantidad ganada | P2 |
Mostrar gráfico de historial de precios | Reflejar los precios escalados en el gráfico de precios | P1 |
Incorporación/Tooltips | Ofrecer tooltips o incorporación para educar a los usuarios sobre tokens que utilizan la extensión de cantidad ui escalada | P2 |
Exploradores
Requisito | Descripción | Prioridad |
---|---|---|
Mejoras en la página de detalles del token | Mostrar metadatos como capitalización de mercado escalada total y multiplicador actual | P0 |
Mostrar saldo escalado para balances | Mostrar saldos escalados (UiAmount) para los balances actuales. | P0 |
Mostrar saldo escalado para transacciones | Mostrar saldos escalados (UiAmount) para montos de transferencia en transacciones históricas. | P0 |
Mostrar precio escalado para transacciones | Mostrar precios escalados para transacciones anteriores | P1 |
Analizar y mostrar correctamente transacciones de actualización del multiplicador | Mostrar correctamente los detalles sobre la actualización del multiplicador | P2 |
Agregadores de datos de mercado (Ej: CoinGecko)
Requisito | Descripción | Prioridad |
---|---|---|
Actualizaciones de API para datos escalados | Ampliar la funcionalidad de la API para incluir cambios de multiplicador a lo largo del tiempo y el feed de precios escalados. | P0 |
Suministro total con ajuste escalado | Al mostrar el suministro total y la capitalización de mercado total, tener en cuenta los saldos escalados | P0 |
Seguimiento histórico de precios | Proporcionar un gráfico histórico de precios utilizando el precio escalado a lo largo del tiempo. | P1 |
Seguimiento histórico del multiplicador | Proporcionar marcadores históricos de actualizaciones del multiplicador para tokens que generan intereses. | P2 |
Contenido educativo o explicaciones | Incluir descripciones breves o tooltips que expliquen cómo funcionan los tokens escalados. | P2 |
Proveedores de feeds de precios
Requisito | Descripción | Prioridad |
---|---|---|
Feeds de precios escalados y no escalados | Proporcionar feeds de precios tanto para precios escalados como no escalados. | P0 |
Datos históricos del multiplicador | Ofrecer APIs con cambios históricos del multiplicador. | P0 |
Datos históricos de precios | Ofrecer APIs con precios históricos basados en cantidades escaladas y no escaladas. | P0 |
DEXes
Requisito | Descripción | Prioridad |
---|---|---|
Mostrar saldos de tokens rebasados | Mostrar saldos escalados para operaciones o provisión de liquidez en la interfaz. (el backend puede seguir usando cantidades sin procesar) | P0 |
Soporte para acciones de tokens | Los usuarios finales deben introducir las cantidades de acción con sus saldos UiAmount (multiplicador * cantidad sin procesar). | P0 |
Adaptación de fuente de precios | En cualquier lugar donde se utilice una fuente de precios para mostrar el precio actual, proporcionar el precio escalado a los usuarios finales. | P1 |
Mostrar gráfico de historial de precios | Reflejar los precios escalados en el gráfico de precios | P1 |
Is this page helpful?