Przewodnik integracji rozszerzenia Scaled UI Amount

Wsparcie dla rozszerzenia Scaled UI Amount na Solanie

Tło

Rozszerzenie Scaled UI Amount pozwala emitentom tokenów określić mnożnik, który jest używany przy obliczaniu wartości UI amount salda tokena użytkownika. Dzięki temu emitenci mogą tworzyć tokeny rebase’ujące oraz umożliwiać takie operacje jak podziały akcji (stock splits). To rozszerzenie, podobnie jak rozszerzenie tokenów oprocentowanych, zapewnia wyłącznie kosmetyczną wartość UI amount, co oznacza, że zespoły muszą wykonać dodatkową pracę, aby zapewnić dobrą obsługę użytkownika. Wszystkie obliczenia i transfery odbywają się na surowych wartościach w programie.

Zasoby:

TL;DR

  • Użytkownicy końcowi powinni w miarę możliwości korzystać z UIAmount (surowa wartość * mnożnik) przy wyświetlaniu ceny tokena, salda oraz ilości tokenów
  • dAppy i dostawcy usług powinni używać surowych wartości i nieskalowanych cen do wszystkich obliczeń, a konwersję wykonywać dla użytkowników na końcu procesu
  • Historyczne dane cenowe powinny być dostępne zarówno dla wartości skalowanych, jak i nieskalowanych, aby ułatwić integrację
  • Historyczne wartości mnożnika muszą być dostępne dla zapewnienia dokładnych danych historycznych

Definicje pojęć

  • Mnożnik: statyczny, aktualizowalny mnożnik używany do obliczeń UI Amount
  • UIAmount: mnożnik * surowa wartość (inaczej: wartość skalowana)
  • Surowa wartość: amount (inaczej: wartość nieskalowana)

Aktualne saldo

Aktualna wartość do wyświetlenia

  • Za każdym razem, gdy wyświetlasz wartości tokenów korzystających z rozszerzenia scaled UI amount użytkownikom końcowym, powinieneś użyć jednej z opcji:
    • UIAmount/UIAmountString (zalecane)
    • Ręczne obliczenie: surowa wartość * mnożnik
    • Zalecamy obcinać tę wartość zgodnie z liczbą miejsc po przecinku, jaką posiada dany token.
      • Przykład: jeśli yUSD ma 6 miejsc po przecinku, a użytkownik ma UIAmount 1.123456789, powinieneś wyświetlić „1.123456”

Skąd uzyskać te dane:

  • Aby uzyskać aktualny stan konta użytkownika, możesz pobrać zaktualizowane informacje o powyższych kwotach wywołując getTokenAccountBalance lub getAccountInfo
  • Jeśli potrzebujesz poznać wartość UI Amount dla dowolnej kwoty, możesz uzyskać to wyliczenie, wywołując funkcję amountToUiAmountForMintWithoutSimulation (web3.js v1) lub symulując transakcję z użyciem amountToUiAmount.
    • Uwaga: amountToUiAmount wymaga symulacji transakcji, co oznacza, że potrzebny jest również ważny fee payer z saldem. Z tego powodu nie powinno to być domyślne rozwiązanie do pobierania salda.

Wywołania RPC

  • getTokenAccountBalance
    • Zwraca saldo token account oraz informacje o mincie
$ 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
    • Zwraca informacje o koncie oraz informacje o mincie
$ 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
}

Aktualizowanie bieżącej kwoty

Ponieważ wystawcy mogą zaktualizować mnożnik w dowolnym momencie, warto rozważyć okresowe odpytywanie, aby saldo konta było aktualne. Wystawcy raczej nie będą zmieniać tego mnożnika częściej niż raz dziennie. Jeśli mnożnik jest ustawiony na przyszłą datę, możesz automatycznie odpytować w czasie tej aktualizacji.

Kwoty tokenów w transakcjach (przelewy / swapy itd.)

  • Użytkownicy powinni wprowadzać kwoty interpretowane jako skalowane “UIAmount”. Aplikacja, która to przetwarza, powinna przekonwertować je na surową kwotę tokena do transakcji.
    • Jeśli pojawią się problemy z zaokrągleniem, zaokrąglij w dół i lepiej zostaw niewielką ilość "kurzu" niż ryzykować niepowodzenie transakcji
    • Do tej konwersji możesz użyć funkcji uiAmountToAmountForMintWithoutSimulation (web3.js v1) lub symulować transakcję z użyciem 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 */
  • Aplikacje powinny używać całkowitej, surowej kwoty, gdy użytkownik wybiera opcję “max” lub “all” swojego salda. Dzięki temu nie pozostają żadne resztki (dust).
    • Opcjonalnie: Możesz rozważyć automatyczne zamknięcie konta, gdy użyto “max” do zwrotu depozytu za przechowywanie użytkownikowi.

Cena tokena

  • Cena tokena powinna być zawsze wyświetlana jako cena skalowana, jeśli to możliwe.
  • Jeśli jesteś dostawcą usługi feedu cenowego, np. oraclem, powinieneś udostępniać zarówno cenę skalowaną, jak i nieskalowaną.
    • W miarę możliwości zapewnij SDK/API, które ukryje złożoność rozszerzenia skalowanej kwoty UI.

Aktualny mnożnik

  • Aktualny mnożnik można odczytać z token mint w dowolnym momencie, wywołując getAccountInfo. Dodatkowo, jeśli ustawiono przyszły mnożnik, ta informacja również jest dostępna z token mint. Zalecamy nie wyświetlać tego mnożnika, ponieważ może to wprowadzać zamieszanie w 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
*/

Dane historyczne

Dane historyczne dla feedu cenowego

  • Usługi dostarczające dane historyczne powinny przechowywać i udostępniać zarówno ceny skalowane, jak i nieskalowane dla rozszerzenia skalowanej kwoty UI.
  • Oczekujemy, że najczęściej będą używane kwoty skalowane, ponieważ jest to zgodne z tym, jak tradycyjny świat finansów traktuje wykresy związane z tokenami po splitach akcji.
  • Aktualizacje mnożnika mogą zawierać znacznik czasu z przeszłości. Zalecamy używanie znacznika czasu bloku dla danych historycznych.
  • Zwróć uwagę, że aktywny mnożnik może być "multiplier" lub "newMultiplier" w zależności od bieżącego znacznika czasu i tego, kiedy nowy mnożnik ma zostać aktywowany.

Dane historyczne dla kwot

  • Jeśli chcesz pokazać saldo przelane w przeszłości, musisz mieć dostęp do mnożnika w danym slocie. Możesz także zapisywać UiAmount dla transferów podczas przetwarzania transakcji, aby uniknąć wykonywania tego obliczenia w przyszłości.

Wsteczna kompatybilność

  • Domyślnie portfele i aplikacje, które nie obsługują rozszerzenia skalowanej ilości UI, pokażą poprawną łączną cenę aktywności, mnożąc nieskalowaną cenę * surową ilość.
  • Jednak wyświetlą nieskalowaną cenę, co może powodować dezorientację użytkowników.
  • Mamy nadzieję, że to zachęci zespoły do aktualizacji swoich dappów, aby były kompatybilne z tokenami korzystającymi z rozszerzenia skalowanej ilości UI. Chętnie udzielimy wsparcia w tym procesie.

Zalecane priorytety integracji według platformy

Wymagania ogólne

WymaganieOpisPriorytet
Obsługa akcji użytkownika z UiAmountWszystkie akcje użytkownika powinny być wprowadzane w UiAmount, gdy UiAmount jest włączony w całej aplikacji. Jeśli UiAmount nie jest widoczny w aplikacji, należy używać surowych wartości do czasu aktualizacji aplikacji.P0

Portfele

WymaganieOpisPriorytet
Wyświetlanie przeskalowanego saldaPokazuj przeskalowaną wartość (uiAmount) jako główne saldo.P0
Obsługa transferów tokenówUżytkownicy końcowi powinni wprowadzać kwoty transferu za pomocą przeskalowanych sald (surowa wartość * saldo).P0
Wyświetlanie ceny spotWyświetlaj przeskalowaną cenę spot dla użytkownikówP0
Metadane historii transakcjiPokazuj przeskalowaną wartość (UIAmount) dla każdego transferu, gdzie to możliwe.P1
Pokazywanie aktualizacji mnożnika w historii transakcjiGdy nastąpią aktualizacje mnożnika, pokaż to jako zdarzenie w historii transakcji użytkownika, w tym ilość uzyskanąP2
Wyświetlanie wykresu historii cenOdzwierciedlaj przeskalowane ceny na wykresie cenP1
Onboarding/podpowiedziOferuj podpowiedzi lub onboarding, aby edukować użytkowników na temat tokenów korzystających z rozszerzenia skalowanej ilości uiAmountP2

Explorery

WymaganieOpisPriorytet
Ulepszenia strony szczegółów tokenaWyświetl metadane, takie jak całkowita przeskalowana kapitalizacja rynkowa i aktualny mnożnikP0
Wyświetlanie przeskalowanego salda dla saldWyświetl przeskalowane salda (UiAmount) dla bieżących sald.P0
Wyświetlanie przeskalowanego salda dla transakcjiWyświetl przeskalowane salda (UiAmount) dla kwot transferów w transakcjach historycznych.P0
Wyświetlanie przeskalowanej ceny dla transakcjiWyświetl przeskalowane ceny dla wcześniejszych transakcjiP1
Poprawne parsowanie i wyświetlanie aktualizacji mnożnikaPoprawnie pokazuj szczegóły dotyczące aktualizacji mnożnikaP2

Agregatory danych rynkowych (np. CoinGecko, Birdeye)

WymaganieOpisPriorytet
Aktualizacje API dla danych skalowanychRozszerz funkcjonalność API o zmiany mnożnika w czasie oraz o przeskalowany kanał cenowy.P0
Całkowita podaż z uwzględnieniem skalowaniaPrzy wyświetlaniu całkowitej podaży i kapitalizacji rynkowej uwzględnij przeskalowane salda.P0
Historyczne śledzenie cenUdostępnij historyczny wykres cen z wykorzystaniem przeskalowanej ceny w czasie.P1
Historyczne śledzenie mnożnikaUdostępnij historyczne znaczniki aktualizacji mnożnika dla tokenów oprocentowanych. Zwróć uwagę, że aktualizacje mnożnika mogą zawierać znacznik czasu z przeszłości. Zalecamy użycie znacznika czasu bloku zamiast tego z aktualizacji mnożnika dla danych historycznych.P2
Treści edukacyjne lub wyjaśnieniaDodaj krótkie opisy lub podpowiedzi wyjaśniające, jak działają tokeny skalowane.P2

Dostawcy kanałów cenowych

WymaganieOpisPriorytet
Skalowane i nieskalowane kanały cenZapewnij kanały cenowe zarówno dla cen skalowanych, jak i nieskalowanych.P0
Historyczne dane mnożnikaUdostępnij API z historycznymi zmianami mnożnika. Uwaga: aktualizacje mnożnika mogą zawierać znacznik czasu z przeszłości. Zalecamy użycie znacznika czasu bloku zamiast tego podanego w aktualizacji mnożnika dla danych historycznych.P0
Historyczne dane cenUdostępnij API z historycznymi cenami na podstawie zarówno skalowanych, jak i nieskalowanych wartości.P0

DEX-y

WymaganieOpisPriorytet
Wyświetlanie sald tokenów po rebasePokaż skalowane salda dla handlu lub dostarczania płynności w interfejsie użytkownika. (backend może nadal używać wartości surowych)P0
Obsługa akcji na tokenachUżytkownicy końcowi powinni wprowadzać kwoty akcji przy użyciu swoich sald UiAmount (mnożnik * surowa wartość).P0
Adaptacja kanału cenowegoW każdym miejscu, gdzie kanał cenowy służy do wyświetlania bieżącej ceny, należy podać użytkownikom końcowym cenę skalowaną.P1
Wyświetlanie wykresu historii cenOdzwierciedlaj skalowane ceny na wykresie cen.P1

CEX-y

WymaganieOpisPriorytet
Śledzenie aktualizacji mnożnikaŚledź aktualizacje mnożnika dla tokenów korzystających z rozszerzenia skalowanej kwoty UI.P0
Wyświetlanie sald tokenów po rebasePokaż skalowane salda dla handlu lub dostarczania płynności w interfejsie użytkownika. (backend może nadal używać wartości surowych)P0
Obsługa akcji na tokenachUżytkownicy końcowi powinni wprowadzać kwoty akcji przy użyciu swoich sald UiAmount (mnożnik * surowa wartość).P0
Historyczne akcje nie powinny być skalowaneHistoryczne akcje, takie jak transakcje, powinny być wyświetlane z dokładną skalowaną kwotą i ceną z momentu akcji.P1
Wewnętrzne śledzenie sald surowychŚledź salda surowe dla transakcji onchain zamiast skalowanych. Będzie to dokładniejsze i łatwiejsze do zarządzania w dłuższej perspektywie.P1
Adaptacja kanału cenowegoW każdym miejscu, gdzie kanał cenowy służy do wyświetlania bieżącej ceny, należy podać użytkownikom końcowym cenę skalowaną.P1
Wyświetlanie wykresu historii cenOdzwierciedlaj skalowane ceny na wykresie cen. Obejmuje to przeskalowanie historycznych cen do aktualnego mnożnika.P1
Skalowanie ceny zakupuKoszt za udział powinien być przeliczony według aktualnego mnożnika.P1

Is this page helpful?

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco