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:

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.
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 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

RequisitoDescripciónPrioridad
Soporte de 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

Carteras

RequisitoDescripciónPrioridad
Mostrar saldo escaladoMostrar la cantidad escalada (uiAmount) como el saldo principal.P0
Soporte para transferencias de tokensLos usuarios finales deben ingresar 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 de 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 de 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 capitalización de mercado escalada total y multiplicador actualP0
Mostrar saldo escalado para balancesMostrar saldos escalados (UiAmount) para los balances actuales.P0
Mostrar saldo escalado para transaccionesMostrar saldos escalados (UiAmount) para montos de transferencia en transacciones históricas.P0
Mostrar precio escalado para transaccionesMostrar precios escalados para transacciones anterioresP1
Analizar y mostrar correctamente 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 escalados.P0
Suministro total con ajuste escaladoAl mostrar el suministro total y la capitalización de mercado total, 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 del multiplicadorProporcionar marcadores históricos de actualizaciones del multiplicador 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 del multiplicadorOfrecer APIs con cambios históricos del multiplicador.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 interfaz. (el backend puede seguir usando cantidades sin procesar)P0
Soporte para acciones de tokensLos usuarios finales deben introducir las cantidades de acción con sus saldos UiAmount (multiplicador * cantidad sin procesar).P0
Adaptación de fuente de preciosEn 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 preciosReflejar los precios escalados en el gráfico de preciosP1

Is this page helpful?