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.
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
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Obsługa akcji użytkownika z UiAmount | Wszystkie 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
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Wyświetlanie przeskalowanego salda | Pokazuj przeskalowaną wartość (uiAmount) jako główne saldo. | P0 |
| Obsługa transferów tokenów | Użytkownicy końcowi powinni wprowadzać kwoty transferu za pomocą przeskalowanych sald (surowa wartość * saldo). | P0 |
| Wyświetlanie ceny spot | Wyświetlaj przeskalowaną cenę spot dla użytkowników | P0 |
| Metadane historii transakcji | Pokazuj przeskalowaną wartość (UIAmount) dla każdego transferu, gdzie to możliwe. | P1 |
| Pokazywanie aktualizacji mnożnika w historii transakcji | Gdy nastąpią aktualizacje mnożnika, pokaż to jako zdarzenie w historii transakcji użytkownika, w tym ilość uzyskaną | P2 |
| Wyświetlanie wykresu historii cen | Odzwierciedlaj przeskalowane ceny na wykresie cen | P1 |
| Onboarding/podpowiedzi | Oferuj podpowiedzi lub onboarding, aby edukować użytkowników na temat tokenów korzystających z rozszerzenia skalowanej ilości uiAmount | P2 |
Explorery
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Ulepszenia strony szczegółów tokena | Wyświetl metadane, takie jak całkowita przeskalowana kapitalizacja rynkowa i aktualny mnożnik | P0 |
| Wyświetlanie przeskalowanego salda dla sald | Wyświetl przeskalowane salda (UiAmount) dla bieżących sald. | P0 |
| Wyświetlanie przeskalowanego salda dla transakcji | Wyświetl przeskalowane salda (UiAmount) dla kwot transferów w transakcjach historycznych. | P0 |
| Wyświetlanie przeskalowanej ceny dla transakcji | Wyświetl przeskalowane ceny dla wcześniejszych transakcji | P1 |
| Poprawne parsowanie i wyświetlanie aktualizacji mnożnika | Poprawnie pokazuj szczegóły dotyczące aktualizacji mnożnika | P2 |
Agregatory danych rynkowych (np. CoinGecko, Birdeye)
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Aktualizacje API dla danych skalowanych | Rozszerz funkcjonalność API o zmiany mnożnika w czasie oraz o przeskalowany kanał cenowy. | P0 |
| Całkowita podaż z uwzględnieniem skalowania | Przy wyświetlaniu całkowitej podaży i kapitalizacji rynkowej uwzględnij przeskalowane salda. | P0 |
| Historyczne śledzenie cen | Udostępnij historyczny wykres cen z wykorzystaniem przeskalowanej ceny w czasie. | P1 |
| Historyczne śledzenie mnożnika | Udostę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śnienia | Dodaj krótkie opisy lub podpowiedzi wyjaśniające, jak działają tokeny skalowane. | P2 |
Dostawcy kanałów cenowych
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Skalowane i nieskalowane kanały cen | Zapewnij kanały cenowe zarówno dla cen skalowanych, jak i nieskalowanych. | P0 |
| Historyczne dane mnożnika | Udostę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 cen | Udostępnij API z historycznymi cenami na podstawie zarówno skalowanych, jak i nieskalowanych wartości. | P0 |
DEX-y
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Wyświetlanie sald tokenów po rebase | Pokaż 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 tokenach | Użytkownicy końcowi powinni wprowadzać kwoty akcji przy użyciu swoich sald UiAmount (mnożnik * surowa wartość). | P0 |
| Adaptacja kanału cenowego | W 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 cen | Odzwierciedlaj skalowane ceny na wykresie cen. | P1 |
CEX-y
| Wymaganie | Opis | Priorytet |
|---|---|---|
| Ś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 rebase | Pokaż 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 tokenach | Użytkownicy końcowi powinni wprowadzać kwoty akcji przy użyciu swoich sald UiAmount (mnożnik * surowa wartość). | P0 |
| Historyczne akcje nie powinny być skalowane | Historyczne 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 cenowego | W 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 cen | Odzwierciedlaj skalowane ceny na wykresie cen. Obejmuje to przeskalowanie historycznych cen do aktualnego mnożnika. | P1 |
| Skalowanie ceny zakupu | Koszt za udział powinien być przeliczony według aktualnego mnożnika. | P1 |
Is this page helpful?