スケールドUI金額統合ガイド
SolanaでスケールドUI金額拡張機能をサポートする
背景
スケールドUI金額拡張機能により、トークン発行者はユーザーのトークン残高のUI金額を計算する際に使用する乗数を指定できます。これにより、発行者はリベーストークンを作成したり、株式分割などを可能にしたりできます。この拡張機能は、利子付きトークン拡張機能と同様に、純粋に見た目上のUI金額を提供するため、チームは良い体験を提供するために追加作業を行う必要があります。基礎となる計算や送金はすべてプログラム内の生の金額を使用して行われます。
リソース:
要約
- エンドユーザーは可能な限り、トークン価格、トークン残高、トークン金額にUIAmount(生の金額 × 乗数)を使用する必要があります
- dAppやサービスプロバイダーはすべての計算に生の金額と非スケール価格を使用し、ユーザー向けの表示時に変換する必要があります
- より簡単な統合のために、スケールされた金額と非スケールの金額の両方の履歴価格フィードを提供する必要があります
- 正確な履歴データのために、履歴乗数値にアクセスできるようにする必要があります
用語の定義
- 乗数:UI金額計算に使用される静的で更新可能な乗数
- UI金額:乗数 × 生の金額(別名:スケールされた金額)
- 生の金額:金額(別名:非スケールの金額)
現在の残高
表示用の現在の金額
- スケールドUI金額拡張機能を使用するトークンの金額をエンドユーザーに表示する場合は、以下のいずれかを使用する必要があります:
- UIAmount/UIAmountString(推奨)
- 生の金額 × 乗数の手動計算
- この値はトークンの小数点以下の桁数に基づいて切り捨てることをお勧めします。
- 例:yUSDが6桁の小数点を持ち、ユーザーのUI金額が1.123456789の場合、「1.123456」と表示する必要があります
このデータの入手先:
- ユーザーのライブバランスについては、getTokenAccountBalanceまたはgetAccountInfoを呼び出すことで上記の金額に関する最新情報を取得できます
- 任意の金額のUI金額を知る必要がある場合は、
amountToUiAmountForMintWithoutSimulation
(web3.js v1)関数を呼び出すか、amountToUiAmountを使用してトランザクションをシミュレートすることでこの計算を取得できます。- 注意:amountToUiAmountはトランザクションシミュレーションを必要とするため、残高のある有効な手数料支払者も必要です。このため、これはバランスを取得するデフォルトの方法にすべきではありません。
RPC呼び出し
getTokenAccountBalance
- token accountのバランスとmint情報を返します
$ 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
- アカウント情報とmint情報を返します
$ 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}
現在の金額の更新
発行者はいつでも乗数を更新できるため、アカウントバランスを最新の状態に保つために定期的にポーリングすることを検討できます。発行者がこの乗数を1日に複数回更新することはほとんどありません。将来の日付に乗数が設定されている場合は、この更新時間に自動的にポーリングすることができます
トランザクション内のトークン金額(転送/スワップなど)
- ユーザーはスケーリングされた「UIAmount」として解釈される金額を入力する必要があります。これを処理するアプリケーションは、トランザクション用に生のトークン金額に変換する必要があります。
- 丸め問題がある場合は、切り捨てて、トランザクションが失敗するリスクよりもわずかな端数を残すことを優先してください
- この変換を行うには、
uiAmountToAmountForMintWithoutSimulation
(web3.js v1)関数を使用するか、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 */
- ユーザーが「最大」または「すべて」の残高でアクションを要求する場合、アプリケーションは合計の生の金額を使用する必要があります。これにより、ダスト(少額残高)が残らないようになります。
- オプション:「最大」が使用される場合、アカウントを自動的に閉鎖してストレージデポジットをユーザーに返金することを検討できます
トークン価格
- トークン価格は可能な限り常にスケーリングされた価格として表示されるべきです。
- 価格フィードサービスプロバイダー(オラクルなど)の場合、スケーリングされた価格と非スケーリングされた価格の両方を公開する必要があります。
- 可能な限り、スケーリングされたUI金額拡張の複雑さを抽象化するSDK/APIを提供してください。
現在の乗数
- 現在の乗数はいつでもトークンミントから
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の金額拡張機能に対して、スケーリングされた価格と元の価格の両方を保存して表示する必要があります。
- スケーリングされた金額は最も頻繁に使用されると予想されます。これは、従来の金融界がストック分割を持つトークンに関連するチャートを扱う方法と一致しています。
- 乗数の更新には過去の時間が含まれる場合があります。過去のデータにはブロックのタイムスタンプを使用することをお勧めします。
- 現在のタイムスタンプと新しい乗数がいつアクティブに設定されるかによって、アクティブな乗数は「乗数」または「新しい乗数」のいずれかになる可能性があることに注意してください。
金額の履歴データ
- 過去に転送された残高を表示したい場合は、特定のslotでの乗数にアクセスする必要があります。将来この計算を避けるために、トランザクションを処理する際に転送のUiAmountを保存することもできます。
後方互換性
- デフォルトでは、スケーリングされたUI金額拡張機能を理解していないウォレットやアプリケーションは、非スケーリング価格×生の金額を乗算することで、アクティビティの正確な合計価格を表示します。
- ただし、非スケーリング価格が表示されるため、ユーザーに混乱を招く可能性があります。
- これにより、各チームがスケーリングされたUI金額拡張機能を使用するトークンと互換性を持つようにdappsを更新することを奨励し、このプロセス中のサポートを喜んで提供します。
プラットフォーム別の推奨統合優先事項
一般要件
要件 | 説明 | 優先度 |
---|---|---|
UiAmountを使用したユーザーアクションのサポート | すべてのユーザーアクションは、アプリ全体でUiAmountが有効になっている場合、UiAmountで入力する必要があります。アプリでUiAmountが表示されていない場合は、アプリが更新されるまで生の金額を使用する必要があります。 | P0 |
ウォレット
要件 | 説明 | 優先度 |
---|---|---|
スケーリングされた残高の表示 | スケーリングされた金額(uiAmount)を主要な残高として表示します。 | P0 |
トークン転送のサポート | エンドユーザーはスケーリングされた残高(生の金額 × 残高)で転送金額を入力する必要があります。 | P0 |
スポット価格の表示 | ユーザー向けにスケーリングされたスポット価格を表示します | P0 |
取引履歴メタデータ | 可能な限り、各転送のスケーリングされた金額(UIAmount)を表示します。 | P1 |
取引履歴での乗数更新の表示 | 乗数の更新が発生した場合、獲得した金額を含めてこれをユーザーの取引履歴にイベントとして表示します | P2 |
価格履歴グラフの表示 | 価格グラフにスケーリングされた価格を反映させます | P1 |
オンボーディング/ツールチップ | スケーリングされたUI金額拡張機能を使用するトークンについてユーザーを教育するためのツールチップまたはオンボーディングを提供します | P2 |
エクスプローラー
要件 | 説明 | 優先度 |
---|---|---|
トークン詳細ページの強化 | 総スケール済み時価総額や現在の乗数などのメタデータを表示 | P0 |
残高のスケール済み残高表示 | 現在の残高にスケール済み残高(UiAmount)を表示 | P0 |
取引のスケール済み残高表示 | 過去の取引の送金額にスケール済み残高(UiAmount)を表示 | P0 |
取引のスケール済み価格表示 | 過去の取引のスケール済み価格を表示 | P1 |
乗数更新取引の適切な解析と表示 | 乗数更新に関する詳細を適切に表示 | P2 |
市場データアグリゲーター(例:CoinGecko、Birdeye)
要件 | 説明 | 優先度 |
---|---|---|
スケーリングデータ用のAPI更新 | 時間の経過に伴う乗数の変更とスケーリングされた価格フィードを含むようにAPI機能を拡張する。 | P0 |
スケーリング調整を含む総供給量 | 総供給量と時価総額を表示する際に、スケーリングされた残高を考慮する | P0 |
過去の価格追跡 | 時間の経過に伴うスケーリングされた価格を使用して、価格の履歴チャートを提供する。 | P1 |
過去の乗数追跡 | 利子付きトークンの乗数更新の履歴マーカーを提供する。乗数の更新には過去の時間が含まれる場合があることに注意してください。過去のデータについては、乗数更新で示されたタイムスタンプではなく、ブロックのタイムスタンプを使用することをお勧めします。 | P2 |
教育コンテンツまたは説明 | スケーリングされたトークンの仕組みを説明する簡単な説明やツールチップを含める。 | P2 |
価格フィードプロバイダー
要件 | 説明 | 優先度 |
---|---|---|
スケーリングされた価格フィードとスケーリングされていない価格フィード | スケーリングされた価格とスケーリングされていない価格の両方の価格フィードを提供します。 | P0 |
過去の乗数データ | 過去の乗数変更を含むAPIを提供します。乗数の更新には過去の時間が含まれる場合があることに注意してください。過去のデータについては、乗数更新で示された時間ではなく、ブロックのタイムスタンプを使用することをお勧めします。 | P0 |
過去の価格データ | スケーリングされた金額とスケーリングされていない金額の両方に基づいた過去の価格を提供するAPIを提供します。 | P0 |
DEX(分散型取引所)
要件 | 説明 | 優先度 |
---|---|---|
リベース済みトークン残高の表示 | UI上で取引や流動性提供のためのスケーリングされた残高を表示する(バックエンドでは生の金額を使用可能) | P0 |
トークンアクションのサポート | エンドユーザーはUiAmount残高(乗数 * 生の金額)でアクション量を入力する必要がある | P0 |
価格フィードの適応 | 現在の価格を表示するために価格フィードが使用される場所では、スケーリングされた価格をエンドユーザーに提供する | P1 |
価格履歴グラフの表示 | 価格グラフにスケーリングされた価格を反映する | P1 |
CEX(中央集権型取引所)
要件 | 説明 | 優先度 |
---|---|---|
乗数の更新を追跡 | スケーリングされたUI金額拡張機能を使用するトークンの乗数更新を追跡する | P0 |
リベース済みトークン残高の表示 | UI上で取引や流動性提供のためのスケーリングされた残高を表示する(バックエンドでは生の金額を使用可能) | P0 |
トークンアクションのサポート | エンドユーザーはUiAmount残高(乗数 * 生の金額)でアクション量を入力する必要がある | P0 |
過去のアクションは再スケーリングしない | 取引などの過去のアクションは、アクション時点の正確なスケーリングされた金額と価格を使用して表示する必要がある | P1 |
内部的に生の残高を追跡 | オンチェーントランザクションのために生の残高を追跡する。これはより正確で長期的に管理しやすい | P1 |
価格フィードの適応 | 現在の価格を表示するために価格フィードが使用される場所では、スケーリングされた価格をエンドユーザーに提供する | P1 |
価格履歴グラフの表示 | 価格グラフにスケーリングされた価格を反映する。これには過去の価格を現在の乗数に再スケーリングすることも含まれる | P1 |
コストベースのスケーリング | 株あたりのコストは現在の乗数にスケーリングする必要がある | P1 |
Is this page helpful?