Scaled UI Amount 통합 가이드

Solana에서 Scaled UI Amount 확장 지원하기

배경

Scaled UI Amount 확장은 토큰 발행자가 사용자의 토큰 잔액 UI 금액을 계산할 때 사용할 승수를 지정할 수 있게 합니다. 이를 통해 발행자는 리베이싱 토큰을 생성하고 주식 분할과 같은 기능을 활성화할 수 있습니다. 이 확장은 이자 발생 토큰 확장과 마찬가지로 순수하게 시각적인 UI 금액을 제공하므로, 팀은 좋은 사용자 경험을 제공하기 위해 추가 작업을 수행해야 합니다. 기본 계산 및 전송은 모두 프로그램의 원시 금액을 사용하여 이루어집니다.

리소스:

요약

  • 최종 사용자는 가능한 한 토큰 가격, 토큰 잔액 및 토큰 금액에 대해 UIAmount(원시 금액 * 승수)와 상호작용해야 합니다
  • dApp 및 서비스 제공자는 모든 계산에 원시 금액과 비스케일 가격을 사용하고 엣지에서 사용자를 위해 변환해야 합니다
  • 더 쉬운 통합을 위해 스케일 및 비스케일 금액 모두에 대한 과거 가격 피드를 제공해야 합니다
  • 정확한 과거 데이터를 위해 과거 승수 값에 액세스할 수 있어야 합니다

용어 정의

  • 승수: 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
    • token account 잔액과 민트 정보를 반환합니다
$ 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
    • 계정 정보와 민트 정보를 반환합니다
$ 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
}

현재 금액 업데이트

발행자는 언제든지 승수를 업데이트할 수 있으므로 계정 잔액을 최신 상태로 유지하기 위해 주기적으로 폴링하는 것을 고려할 수 있습니다. 발행자가 이 승수를 하루에 한 번 이상 업데이트할 가능성은 낮습니다. 승수가 미래 날짜로 설정된 경우 이 업데이트 시간에 자동으로 폴링할 수 있습니다

트랜잭션의 토큰 금액 (전송 / 스왑 등)

  • 사용자는 스케일링된 “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 */
  • 사용자가 잔액의 '최대' 또는 '전체'로 작업을 요청할 때 앱은 총 원시 금액을 사용해야 합니다. 이렇게 하면 먼지(dust)가 남지 않습니다.
    • 선택 사항: '최대'를 사용할 때 계정을 자동으로 닫아 사용자에게 스토리지 예치금을 환불하는 것을 고려할 수 있습니다

토큰 가격

  • 토큰 가격은 가능한 한 항상 조정된 가격으로 표시되어야 합니다.
  • 오라클과 같은 가격 피드 서비스 제공자인 경우 조정된 가격과 조정되지 않은 가격을 모두 노출해야 합니다.
    • 가능한 한 조정된 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 금액 확장에 대해 조정된 가격과 조정되지 않은 가격을 모두 저장하고 표시해야 합니다.
  • 조정된 금액은 전통적인 금융 세계에서 주식 분할과 관련된 차트를 처리하는 방식과 일치하므로 가장 자주 사용될 것으로 예상됩니다.
  • 승수 업데이트에는 과거의 타임스탬프가 포함될 수 있습니다. 과거 데이터에는 블록 타임스탬프를 사용하는 것이 좋습니다.
  • 활성 승수는 현재 타임스탬프와 새 승수가 활성화되도록 설정된 시점에 따라 "multiplier" 또는 "newMultiplier"일 수 있습니다.

금액에 대한 과거 데이터

  • 과거에 전송된 잔액을 표시하려면 해당 slot에서의 승수에 대한 액세스가 필요합니다. 또한 향후 이 계산을 피하기 위해 트랜잭션을 처리할 때 전송에 대한 UiAmount를 저장할 수 있습니다.

하위 호환성

  • 기본적으로 조정된 UI 금액 확장을 이해하지 못하는 지갑과 애플리케이션은 조정되지 않은 가격 * 원시 금액을 곱하여 활동의 올바른 총 가격을 표시합니다.
  • 그러나 조정되지 않은 가격을 표시하여 일부 사용자 혼란을 야기할 수 있습니다.
  • 우리는 이것이 팀들이 조정된 UI 금액 확장을 사용하는 토큰과 호환되도록 dapp을 업데이트하도록 장려하기를 바라며 이 과정에서 기꺼이 지원을 제공할 것입니다.

플랫폼별 권장 통합 우선순위

일반 요구사항

요구사항설명우선순위
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?

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기