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 Scaled UI Amount permite a los emisores de tokens especificar un multiplicador para ser usado al calcular la cantidad UI del saldo de tokens de un usuario. Esto permite a los emisores crear tokens con rebase y habilitar cosas como splits de acciones. Esta extensión, como la extensión de token con interés, proporciona una cantidad UI puramente cosmética, lo que significa que los equipos necesitan hacer trabajo adicional para ofrecer una buena experiencia. Los cálculos y transferencias subyacentes se realizan utilizando las cantidades brutas en el programa.

Recursos:

Resumen

  • Los usuarios finales deben interactuar con la UIAmount (cantidad bruta * multiplicador) para el precio del token, saldo del token y cantidades de token siempre que sea posible
  • Las dApps y proveedores de servicios deben usar la cantidad bruta y precios no escalados para todos los cálculos y convertir para los usuarios al final
  • Los feeds de precios históricos deben proporcionarse tanto para cantidades escaladas como no escaladas para una integración más fácil
  • Los valores históricos del multiplicador deben ser accesibles para datos históricos precisos

Definiciones de términos

  • Multiplicador: multiplicador estático actualizable que se usa para cálculos de UI Amount
  • 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 usan la extensión scaled UI amount 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 un 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 un monto arbitrario, 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 este motivo, esta no debería ser la forma predeterminada de obtener un saldo.

Llamadas RPC

  • getTokenAccountBalance
    • Devuelve el saldo de la 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 programar automáticamente un sondeo 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 dust antes que arriesgarse a 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.
web3js-uiAmountToAmountForMintWithoutSimulation.ts
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 bruta total cuando un usuario solicita realizar una acción con el "máximo" o "todo" su saldo. Esto asegura que no quede dust.
    • Opcional: Puedes considerar cerrar automáticamente una cuenta cuando se usa "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 feed 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 la 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 feed 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 el 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 causaría cierta confusión al usuario.
  • 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

RequisitoDescripciónPrioridad
Soportar acciones de usuario usando UiAmountTodas 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

Monederos

RequisitoDescripciónPrioridad
Mostrar saldo escaladoMostrar la cantidad escalada (uiAmount) como el saldo principal.P0
Soporte para transferencias de tokensLos usuarios finales deben introducir las cantidades de transferencia con sus saldos escalados (cantidad bruta * saldo).P0
Mostrar precio de mercadoMostrar el precio de mercado escalado para los usuariosP0
Metadatos del historial de transaccionesMostrar la cantidad escalada (UIAmount) para cada transferencia siempre que sea posible.P1
Mostrar actualizaciones del multiplicador en el historial de transaccionesCuando ocurran actualizaciones del multiplicador, mostrar esto como un evento en el historial de transacciones del usuario incluyendo la cantidad ganadaP2
Mostrar gráfico del historial de preciosReflejar los precios escalados en el gráfico de preciosP1
Incorporación/TooltipsOfrecer tooltips o incorporación para educar a los usuarios sobre tokens que utilizan la extensión de cantidad ui escaladaP2

Exploradores

RequisitoDescripciónPrioridad
Mejoras en la página de detalles del tokenMostrar metadatos como la capitalización de mercado escalada total y el multiplicador actualP0
Mostrar saldo escalado para los saldosMostrar saldos escalados (UiAmount) para los saldos actuales.P0
Mostrar saldo escalado para las transaccionesMostrar saldos escalados (UiAmount) para las cantidades de transferencia en transacciones históricas.P0
Mostrar precio escalado para las transaccionesMostrar precios escalados para transacciones anterioresP1
Analizar y mostrar correctamente las transacciones de actualización del multiplicadorMostrar correctamente los detalles sobre la actualización del multiplicadorP2

Agregadores de datos de mercado (Ej: CoinGecko)

RequisitoDescripciónPrioridad
Actualizaciones de API para datos escaladosAmpliar la funcionalidad de la API para incluir cambios de multiplicador a lo largo del tiempo y el feed de precios escalado.P0
Suministro total con ajuste escaladoAl mostrar el suministro total y la capitalización total del mercado, tener en cuenta los saldos escaladosP0
Seguimiento histórico de preciosProporcionar un gráfico histórico de precios utilizando el precio escalado a lo largo del tiempo.P1
Seguimiento histórico de multiplicadoresProporcionar marcadores históricos de actualizaciones de multiplicadores para tokens que generan intereses.P2
Contenido educativo o explicacionesIncluir descripciones breves o tooltips que expliquen cómo funcionan los tokens escalados.P2

Proveedores de feeds de precios

RequisitoDescripciónPrioridad
Feeds de precios escalados y no escaladosProporcionar feeds de precios tanto para precios escalados como no escalados.P0
Datos históricos de multiplicadoresOfrecer APIs con cambios históricos de multiplicadores.P0
Datos históricos de preciosOfrecer APIs con precios históricos basados en cantidades escaladas y no escaladas.P0

DEXes

RequisitoDescripciónPrioridad
Mostrar saldos de tokens rebasadosMostrar saldos escalados para operaciones o provisión de liquidez en la UI. (el backend puede seguir usando cantidades brutas)P0
Soporte para acciones de tokensLos usuarios finales deben introducir cantidades de acción con sus saldos UiAmount (multiplicador * cantidad bruta).P0
Adaptación de feed de preciosEn cualquier lugar donde se utilice un feed de precios para mostrar el precio actual, proporcionar el precio escalado a los usuarios finales.P1
Mostrar gráfico de historial de preciosReflejar los precios escalados en el gráfico de preciosP1

Is this page helpful?