잔액 및 자산 쿼리
Permissioned Asset Standard (PAS)는 SDK에서 dedicated read API를 노출하지 않는다. 이는 의도된 설계다. PAS는 deterministic address가 있는 표준 Sui object에 자산을 저장하므로, 다른 address-owned data(예: balance query와 owned object query)에 사용하는 동일한 RPC method로 조회한다.
Sui의 wallet address는 두 종류의 잔액을 보유할 수 있다.
-
일반 잔액: wallet address가 직접 소유한다.
-
PAS 잔 액: wallet address를 대신해 PAS가 관리한다.
사용자 관점에서는 둘 다 같은 address에 속한다. PAS 잔액은 derived Account object에 보관되지만, transfer는 항상 Account address가 아니라 wallet address를 대상으로 한다. SDK는 underlying Account를 투명하게 resolve한다.
PAS 잔액 쿼리
wallet의 PAS 잔액을 읽으려면 PAS SDK를 사용해 wallet address에서 internal Account address를 derive한 다음(derivation은 deterministic), core SDK balance method로 쿼리한다.
다음 diagram은 derivation flow를 보여준다.
Wallet Address (for example, 0xAlice)
│
▼
┌──────────────────────────────┐
│ client.pas │
│ .deriveAccountAddress( │
│ '0xAlice' │
│ ) │
└──────────────────────────────┘
│
▼
Account Address (deterministic, same every time)
derived address는 network마다(Mainnet과 Testnet) 다르다. PAS namespace object가 각 network에서 다른 ID를 갖기 때문이다. SDK는 client 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',
});
wallet에 PAS Account가 있는지 확인
derived address에 대해 getObject가 null을 반환하면 wallet에는 아직 PAS Account가 없다.
const { object } = await client.core.getObject({ objectId: accountAddress });
if (!object) {
// No PAS account
}
Account의 non-policy asset
Account는 PAS policy가 관리하지 않는 asset type도 보유할 수 있다. 예를 들어 direct balance::send_funds call을 통해 Balance<SUI>가 Account에 들어갈 수 있다. getAllBalances를 호출하면 이런 잔액은 policy-managed asset과 함께 표시된다.
핵심 사항
- Wallet 중심: PAS 잔액은 wallet address에 속한다. Account는 SDK가 처리하는 내부 detail이다.
- Deterministic: 같은 wallet address는 항상 같은 Account로 resolve된다.
- 표준 RPC:
getBalance와getAllBalances는 derived address에서 동작한다. custom endpoint가 필요하지 않다. - Indexing 불필요: derivation은 client-side에서 수행된다. event subscription이나 custom indexer가 필요하지 않다.