Руководство по интеграции Scaled UI Amount
Поддержка расширения Scaled UI Amount на Solana
Общая информация
Расширение Scaled UI Amount позволяет эмитентам токенов задавать множитель, который используется при расчете UI-количества баланса токенов пользователя. Это дает возможность создавать токены с ребалансировкой и реализовывать такие функции, как дробление акций. Это расширение, как и расширение для токенов с начислением процентов, предоставляет исключительно косметическое UI-количество, что означает, что командам необходимо выполнить дополнительную работу для обеспечения хорошего пользовательского опыта. Все базовые расчеты и переводы выполняются с использованием необработанных значений в программе.
Ресурсы:
- Документация для разработчиков
- Код расширения на Rust
- Код для преобразования Amount в UI Amount на Rust
Краткий обзор
- Конечные пользователи должны взаимодействовать с UIAmount (необработанное количество * множитель) для отображения цены токена, баланса токена и количества токенов, где это возможно.
- dApps и поставщики услуг должны использовать необработанное количество и нескалированные цены для всех расчетов и преобразовывать их для пользователей на уровне интерфейса.
- Исторические данные о ценах должны быть предоставлены как для скалированных, так и для нескалированных значений для упрощения интеграции.
- Исторические значения множителей должны быть доступны для точных исторических данных.
Определения терминов
- Множитель: статический обновляемый множитель, используемый для расчетов UI Amount.
- UIAmount: множитель * необработанное количество (также известное как: скалированное количество).
- Необработанное количество: количество (также известное как: нескалированное количество).
Текущий баланс
Текущее количество для отображения
- Каждый раз, когда вы отображаете количество токенов, использующих расширение
Scaled UI Amount, конечным пользователям, вы должны использовать либо:
- UIAmount/UIAmountString (предпочтительно)
- Ручной расчет необработанного количества * множитель
- Мы рекомендуем усекать это значение в зависимости от количества десятичных
знаков, которые имеет токен.
- Например: если yUSD имеет 6 десятичных знаков, а пользователь имеет UIAmount 1.123456789, вы должны отображать "1.123456".
Где получить эти данные:
- Для получения актуального баланса пользователя вы можете получить обновленную информацию о вышеуказанных суммах, вызвав либо getTokenAccountBalance, либо getAccountInfo.
- Если вам нужно узнать UI Amount для произвольной суммы, вы можете выполнить
этот расчет, вызвав функцию
amountToUiAmountForMintWithoutSimulation
(web3.js v1) или симулируя транзакцию с использованием amountToUiAmount.- Примечание: amountToUiAmount требует симуляции транзакции, что означает, что также необходим действительный плательщик комиссии с балансом. Поэтому это не должно быть основным способом получения баланса.
RPC вызовы
getTokenAccountBalance
- Возвращает баланс токен-аккаунта и информацию о выпуске (mint info)
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
- Возвращает информацию об аккаунте и информацию о выпуске (mint info)
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"}} */
Обновление текущей суммы
Поскольку эмитенты могут обновлять множитель в любое время, вы можете периодически выполнять опрос, чтобы поддерживать актуальность баланса аккаунта. Эмитенты вряд ли будут обновлять этот множитель чаще одного раза в день. Если множитель установлен на будущую дату, вы можете автоматически выполнять опрос в это время обновления.
Суммы токенов в транзакциях (переводы / обмены и т. д.)
- Пользователи должны вводить суммы, которые интерпретируются как
масштабированный "UIAmount". Приложение, которое должно обработать это, должно
преобразовать в необработанную сумму токенов для транзакции.
- Если возникают проблемы с округлением, округляйте в меньшую сторону и оставляйте небольшое количество "пыли", чтобы избежать сбоя транзакции.
- Для выполнения этого преобразования вы можете использовать функцию
uiAmountToAmountForMintWithoutSimulation
(web3.js v1) или симулировать транзакцию с использованием 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 */
- Приложения должны использовать общий необработанный баланс, когда пользователь
запрашивает выполнение действия с «максимумом» или «всем» своим балансом. Это
гарантирует, что не останется остатка.
- Необязательно: Вы можете рассмотреть возможность автоматического закрытия аккаунта, когда используется «максимум», чтобы вернуть пользователю его депозит за хранение.
Цена токена
- Цена токена всегда должна отображаться как масштабированная цена, где это возможно.
- Если вы являетесь поставщиком данных о ценах, таким как оракул, вы должны
предоставлять как масштабированную, так и немасштабированную цену.
- По возможности предоставляйте SDK/API, который абстрагирует сложности расширения масштабированного UI-количества.
Текущий множитель
- Текущий множитель можно считать из токенового минта в любое время, вызвав
getAccountInfo
. Кроме того, если установлен будущий множитель, эта информация также доступна из токенового минта. Мы рекомендуем не показывать этот множитель, так как это может запутать UX.
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*/
Исторические данные
Исторические данные для источника цен
- Сервисы, предоставляющие исторические данные, должны сохранять и отображать как масштабированные, так и немасштабированные цены для расширения масштабированного UI-количества.
- Мы ожидаем, что масштабированные значения будут использоваться чаще всего, так как это соответствует тому, как традиционный финансовый мир обрабатывает графики, связанные с токенами с дроблением акций.
Исторические данные для количеств
- Если вы хотите показать баланс, переведенный в прошлом, вам нужен доступ к множителю на данном слоте. Вы также можете сохранить UiAmount для переводов, обрабатывая транзакции, чтобы избежать выполнения этого расчета в будущем.
Обратная совместимость
- По умолчанию кошельки и приложения, которые не поддерживают расширение масштабируемого пользовательского интерфейса (UI) для отображения суммы, будут показывать правильную общую цену активности, умножая немасштабированную цену на исходное количество.
- Однако они будут отображать немасштабированную цену, что может вызвать путаницу у пользователей.
- Мы надеемся, что это побудит команды обновить свои децентрализованные приложения (dapps) для совместимости с токенами, использующими расширение масштабируемого пользовательского интерфейса, и готовы предоставить поддержку в этом процессе.
Рекомендуемые приоритеты интеграции по платформам
Общие требования
Требование | Описание | Приоритет |
---|---|---|
Поддержка действий пользователей с UiAmount | Все действия пользователей должны вводиться в UiAmount, если UiAmount включен в приложении. Если UiAmount не отображается в приложении, следует использовать исходные суммы до обновления приложения. | P0 |
Кошельки
Требование | Описание | Приоритет |
---|---|---|
Отображение масштабированного баланса | Показывать масштабированную сумму (uiAmount) в качестве основного баланса. | P0 |
Поддержка переводов токенов | Пользователи должны вводить суммы переводов с учетом их масштабированных балансов (исходное количество * баланс). | P0 |
Отображение текущей цены | Показывать масштабированную текущую цену для пользователей. | P0 |
Метаданные истории транзакций | Показывать масштабированную сумму (UIAmount) для каждого перевода, где это возможно. | P1 |
Отображение обновлений множителя в истории транзакций | При обновлении множителя отображать это событие в истории транзакций пользователя, включая полученную сумму. | P2 |
Отображение графика истории цен | Отражать масштабированные цены на графике цен. | P1 |
Обучение/подсказки | Предоставлять подсказки или обучение для информирования пользователей о токенах, использующих расширение масштабируемого пользовательского интерфейса. | P2 |
Обозреватели
Требование | Описание | Приоритет |
---|---|---|
Улучшения страницы с информацией о токенах | Отображение метаданных, таких как общий масштабируемый рыночный кап и текущий множитель | P0 |
Отображение масштабируемого баланса для балансов | Отображение масштабируемых балансов (UiAmount) для текущих балансов. | P0 |
Отображение масштабируемого баланса для транзакций | Отображение масштабируемых балансов (UiAmount) для сумм переводов в истории транзакций. | P0 |
Отображение масштабируемой цены для транзакций | Отображение масштабируемых цен для предыдущих транзакций | P1 |
Корректный разбор и отображение транзакций обновления множителя | Корректное отображение деталей об обновлении множителя | P2 |
Агрегаторы рыночных данных (например, CoinGecko)
Требование | Описание | Приоритет |
---|---|---|
Обновления API для масштабируемых данных | Расширение функциональности API для включения изменений множителя с течением времени, а также масштабируемой ценовой ленты. | P0 |
Общий объем с учетом масштабирования | При отображении общего объема и общего рыночного капа учитывать масштабируемые балансы | P0 |
Отслеживание исторических цен | Предоставление исторического графика цен с использованием масштабируемой цены с течением времени. | P1 |
Отслеживание исторических множителей | Предоставление исторических маркеров обновлений множителя для токенов с начислением процентов. | P2 |
Образовательный контент или объяснения | Включение кратких описаний или подсказок, объясняющих, как работают масштабируемые токены. | P2 |
Поставщики ценовых данных
Требование | Описание | Приоритет |
---|---|---|
Масштабируемые и немасштабируемые ценовые ленты | Предоставление ценовых лент как для масштабируемых, так и для немасштабируемых цен. | P0 |
Исторические данные множителей | Предоставление API с историческими изменениями множителей. | P0 |
Исторические данные цен | Предоставление API с историческими ценами на основе как масштабируемых, так и немасштабируемых сумм. | P0 |
DEXы
Требование | Описание | Приоритет |
---|---|---|
Отображение балансов ребейз-токенов | Отображение масштабированных балансов для торговли или предоставления ликвидности в интерфейсе. (бэкенд может использовать необработанные значения) | P0 |
Поддержка действий с токенами | Пользователи должны вводить суммы действий, используя их UiAmount балансы (множитель * необработанное значение). | P0 |
Адаптация ценового фида | Везде, где используется ценовой фид для отображения текущей цены, предоставлять масштабированную цену пользователям. | P1 |
Отображение графика истории цен | Отражение масштабированных цен на графике цен | P1 |
Is this page helpful?