Przewodnik integracji funkcji Scaled UI Amount

Obsługa rozszerzenia Scaled UI Amount na platformie Solana

Tło

Rozszerzenie Scaled UI Amount pozwala emitentom tokenów określić mnożnik, który będzie używany przy obliczaniu ilości tokenów użytkownika w interfejsie użytkownika (UI). Dzięki temu emitenci mogą tworzyć tokeny z mechanizmem rebasingu oraz umożliwiać takie operacje jak podziały akcji. To rozszerzenie, podobnie jak rozszerzenie tokenów oprocentowanych, zapewnia wyłącznie kosmetyczną wartość w interfejsie użytkownika, co oznacza, że zespoły muszą wykonać dodatkową pracę, aby zapewnić dobre doświadczenie użytkownika. Wszystkie obliczenia i transfery odbywają się przy użyciu surowych wartości w programie.

Zasoby:

TL;DR

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

Definicje terminów

  • Mnożnik: statyczny, aktualizowalny mnożnik używany do obliczeń UI Amount
  • UIAmount: mnożnik * surowa wartość (znane również jako: skalowana wartość)
  • Surowa wartość: wartość (znane również jako: nieskalowana wartość)

Aktualne saldo

Aktualna wartość do wyświetlenia

  • Za każdym razem, gdy wyświetlasz wartości dla tokenów korzystających z rozszerzenia scaled UI amount użytkownikom końcowym, powinieneś używać:
    • UIAmount/UIAmountString (zalecane)
    • Ręcznego obliczenia surowej wartości * mnożnika
    • Zalecamy obcinanie tej wartości na podstawie liczby miejsc dziesiętnych, jakie ma token.
      • Przykład: jeśli yUSD ma 6 miejsc dziesiętnych, a użytkownik ma UIAmount równy 1.123456789, powinieneś wyświetlić „1.123456”

Skąd uzyskać te dane:

  • Aby uzyskać aktualne informacje o saldzie użytkownika, możesz pobrać zaktualizowane dane o powyższych kwotach, wywołując funkcje getTokenAccountBalance lub getAccountInfo
  • Jeśli potrzebujesz znać kwotę UI Amount dla dowolnej kwoty, możesz uzyskać to obliczenie, wywołując funkcję amountToUiAmountForMintWithoutSimulation (web3.js v1) lub symulując transakcję za pomocą amountToUiAmount.
    • Uwaga: amountToUiAmount wymaga symulacji transakcji, co oznacza, że potrzebuje również ważnego płatnika opłat z saldem. Z tego powodu nie powinno to być domyślnym sposobem uzyskiwania salda.

Wywołania RPC

  • getTokenAccountBalance
    • Zwraca saldo konta tokena oraz informacje o monecie (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
    • Zwraca informacje o koncie oraz informacje o monecie (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"
}
} */

Aktualizacja bieżącej ilości

Ponieważ emitenci mogą aktualizować mnożnik w dowolnym momencie, warto rozważyć okresowe odpytywanie w celu utrzymania aktualnego salda konta. Emitenci prawdopodobnie nie będą aktualizować tego mnożnika częściej niż raz dziennie. Jeśli mnożnik jest ustawiony na przyszłą datę, można automatycznie odpytywać w czasie tej aktualizacji.

Ilości tokenów w transakcjach (przelewy / wymiany itp.)

  • Użytkownicy powinni wprowadzać ilości interpretowane jako skalowane „UIAmount”. Aplikacja, która musi to przetworzyć, powinna przekonwertować na surową ilość tokenów dla transakcji.
    • W przypadku problemów z zaokrąglaniem, zaokrąglaj w dół i preferuj pozostawienie niewielkiej ilości „kurzu” zamiast ryzykować niepowodzenie transakcji.
    • Do tej konwersji można użyć funkcji uiAmountToAmountForMintWithoutSimulation (web3.js v1) lub symulacji transakcji przy użyciu 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 ilości, gdy użytkownik żąda wykonania akcji z „max” lub „all” swojego salda. Zapewnia to, że nie pozostanie żaden „kurz”.
    • Opcjonalnie: Można rozważyć automatyczne zamknięcie konta, gdy używane jest „max”, aby zwrócić użytkownikowi jego depozyt za przechowywanie.

Cena tokena

  • Cena tokena powinna być zawsze wyświetlana jako skalowana cena, gdzie to możliwe.
  • Jeśli jesteś dostawcą kanałów cenowych, takim jak wyrocznia, powinieneś udostępniać zarówno skalowaną, jak i nieskalowaną cenę.
    • Gdzie to możliwe, zapewnij SDK/API, które abstrahuje złożoności związane z rozszerzeniem skalowanej ilości 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 źródła cen

  • Usługi dostarczające dane historyczne powinny przechowywać i udostępniać zarówno skalowane, jak i nieskalowane ceny dla rozszerzenia skalowanej kwoty UI.
  • Oczekujemy, że skalowane kwoty będą używane najczęściej, ponieważ jest to zgodne z tym, jak tradycyjny świat finansów traktuje wykresy związane z tokenami z podziałami akcji.

Dane historyczne dla kwot

  • Jeśli chcesz pokazać saldo przeniesione w przeszłości, musisz mieć dostęp do mnożnika w danym slocie. Możesz również zapisać 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 rozumieją rozszerzenia skalowanej kwoty UI, pokażą poprawną całkowitą cenę aktywności, mnożąc nieskalowaną cenę * surową kwotę.
  • Jednakże wyświetlą nieskalowaną cenę, co może powodować pewne zamieszanie wśród użytkowników.
  • Mamy nadzieję, że to zachęci zespoły do aktualizacji swoich dapps, aby były kompatybilne z tokenami używającymi rozszerzenia skalowanej kwoty UI, i chętnie zapewnimy wsparcie podczas tego procesu.

Zalecane priorytety integracji według platformy

Ogólne wymagania

WymaganieOpisPriorytet
Obsługa działań użytkownika z UiAmountWszystkie działania 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 kwot, dopóki aplikacja nie zostanie zaktualizowana.P0

Portfele

WymaganieOpisPriorytet
Wyświetlanie przeskalowanego saldaWyświetlanie przeskalowanej kwoty (uiAmount) jako głównego salda.P0
Obsługa transferów tokenówUżytkownicy końcowi powinni wprowadzać kwoty transferów z użyciem przeskalowanych sald (kwota surowa * saldo).P0
Wyświetlanie ceny spotWyświetlanie przeskalowanej ceny spot dla użytkownikówP0
Metadane historii transakcjiWyświetlanie przeskalowanej kwoty (uiAmount) dla każdego transferu, gdzie to możliwe.P1
Pokazywanie aktualizacji mnożnika w historii transakcjiGdy występują aktualizacje mnożnika, wyświetlanie tego jako zdarzenia w historii transakcji użytkownika, w tym uzyskanej kwotyP2
Wyświetlanie wykresu historii cenOdzwierciedlanie przeskalowanych cen na wykresie cenP1
Wprowadzenie/PodpowiedziOferowanie podpowiedzi lub wprowadzenia, aby edukować użytkowników na temat tokenów korzystających z rozszerzenia przeskalowanej kwoty uiP2

Eksploratory

WymaganieOpisPriorytet
Ulepszenia strony szczegółów tokenaWyświetlanie metadanych, takich jak całkowita przeskalowana kapitalizacja rynkowa i aktualny mnożnikP0
Wyświetlanie przeskalowanego salda dla saldWyświetlanie przeskalowanych sald (uiAmount) dla bieżących sald.P0
Wyświetlanie przeskalowanego salda dla transakcjiWyświetlanie przeskalowanych sald (uiAmount) dla kwot transferów w historii transakcji.P0
Wyświetlanie przeskalowanej ceny dla transakcjiWyświetlanie przeskalowanych cen dla wcześniejszych transakcjiP1
Poprawne parsowanie i wyświetlanie transakcji aktualizacji mnożnikaPoprawne wyświetlanie szczegółów dotyczących aktualizacji mnożnikaP2

Agregatory danych rynkowych (np. CoinGecko)

WymaganieOpisPriorytet
Aktualizacje API dla skalowanych danychRozszerzenie funkcjonalności API o zmiany mnożnika w czasie oraz skalowany kanał cenowy.P0
Całkowita podaż z uwzględnieniem skalowaniaPrzy wyświetlaniu całkowitej podaży i całkowitej kapitalizacji rynkowej uwzględnij skalowane saldaP0
Śledzenie historycznych cenUdostępnienie wykresu historycznych cen z wykorzystaniem skalowanych cen w czasie.P1
Śledzenie historycznych mnożnikówUdostępnienie historycznych znaczników aktualizacji mnożnika dla tokenów oprocentowanych.P2
Treści edukacyjne lub wyjaśnieniaDodanie krótkich opisów lub podpowiedzi wyjaśniających, jak działają skalowane tokeny.P2

Dostawcy kanałów cenowych

WymaganieOpisPriorytet
Skalowane i nieskalowane kanały cenoweUdostępnienie kanałów cenowych zarówno dla cen skalowanych, jak i nieskalowanych.P0
Historyczne dane mnożnikówUdostępnienie API z historycznymi zmianami mnożników.P0
Historyczne dane cenUdostępnienie API z historycznymi cenami opartymi na wartościach skalowanych i nieskalowanych.P0

DEXy

WymaganieOpisPriorytet
Wyświetlanie zrebasowanych sald tokenówWyświetlanie skalowanych sald dla handlu lub dostarczania płynności w interfejsie użytkownika (backend może nadal używać surowych wartości).P0
Wsparcie dla akcji na tokenachUżytkownicy końcowi powinni wprowadzać kwoty działań z wykorzystaniem swoich sald UiAmount (mnożnik * surowa wartość).P0
Adaptacja kanałów cenowychW miejscach, gdzie kanał cenowy jest używany do wyświetlania bieżącej ceny, należy udostępnić użytkownikom końcowym skalowaną cenę.P1
Wyświetlanie wykresu historii cenOdzwierciedlenie skalowanych cen na wykresie cenowym.P1

Is this page helpful?