본문으로 건너뛰기

잔액 및 자산 쿼리

Permissioned Asset Standard (PAS)는 SDK에서 dedicated read API를 노출하지 않는다. 이는 의도된 설계다. PAS는 deterministic 주소가 있는 표준 Sui 객체에 자산을 저장하므로, 다른 주소 소유 data(예: 잔액 쿼리와 소유 객체 쿼리)에 사용하는 동일한 RPC method로 조회한다.

Sui의 지갑 주소는 두 종류의 잔액을 보유할 수 있다.

  • 일반 잔액: 지갑 주소가 직접 소유한다.

  • PAS 잔액: 지갑 주소를 대신해 PAS가 관리한다.

사용자 관점에서는 둘 다 같은 주소에 속한다. PAS 잔액은 derived Account 객체에 보관되지만, transfer는 항상 Account 주소가 아니라 지갑 주소를 대상으로 한다. SDK는 underlying Account를 투명하게 해결한다.

PAS 잔액 쿼리

지갑의 PAS 잔액을 읽으려면 PAS SDK를 사용해 지갑 주소에서 internal Account 주소를 derive한 다음(derivation은 deterministic), core SDK 잔액 method로 쿼리한다.

다음 diagram은 derivation flow를 보여준다.

Wallet Address (for example, 0xAlice)


┌──────────────────────────────┐
│ client.pas │
│ .deriveAccountAddress( │
│ '0xAlice' │
│ ) │
└──────────────────────────────┘


Account Address (deterministic, same every time)

derived 주소는 network마다(Mainnet과 Testnet) 다르다. PAS namespace 객체가 각 network에서 다른 ID를 갖기 때문이다. SDK는 클라이언트 network configuration을 기반으로 이를 처리한다.

다음 예시는 일반 잔액과 PAS 관리 잔액을 모두 쿼리하는 방법을 보여준다.

import { SuiGrpcClient } from '@mysten/sui/grpc';
import { pas } from '@mysten/pas';
const client = new SuiGrpcClient({ network: 'testnet' }).$extend(pas());
const walletAddress = '0xAlice';
// Regular balances — query the wallet address directly
const regularBalances = await client.core.getAllBalances({
owner: walletAddress,
});
// PAS-managed balances — derive the Account address, then query it
const pasBalances = await client.core.getAllBalances({
owner: client.pas.deriveAccountAddress(walletAddress),
});
// Single asset type
const { balance } = await client.core.getBalance({
owner: client.pas.deriveAccountAddress(walletAddress),
coinType: '0xabc...::my_coin::MY_COIN',
});

지갑에 PAS Account가 있는지 확인

derived 주소에 대해 getObjectnull을 반환하면 지갑에는 아직 PAS Account가 없다.

const { object } = await client.core.getObject({ objectId: accountAddress });
if (!object) {
// No PAS account
}

Account의 non-정책 자산

Account는 PAS 정책이 관리하지 않는 자산 type도 보유할 수 있다. 예를 들어 direct Balance<SUI> call을 통해 balance::send_funds가 Account에 들어갈 수 있다. getAllBalances를 호출하면 이런 잔액은 정책-managed 자산과 함께 표시된다.

핵심 사항

  • Wallet 중심: PAS 잔액은 지갑 주소에 속한다. Account는 SDK가 처리하는 내부 detail이다.
  • Deterministic: 같은 지갑 주소는 항상 같은 Account로 해결된다.
  • 표준 RPC: getBalancegetAllBalances는 derived 주소에서 동작한다. custom endpoint가 필요하지 않다.
  • Indexing 불필요: derivation은 클라이언트-side에서 수행된다. event subscription이나 custom indexer가 필요하지 않다.