import { PChainOwner } from '../../serializable'; import { TransferableOutput } from '../../serializable/avax'; import { Utxo } from '../../serializable/avax/utxo'; import { getPVMManager } from '../../serializable/pvm/codec'; import { hexToBuffer, parse } from '../../utils'; import type { GetAssetDescriptionResponse } from '../common/apiModels'; import { AvaxApi } from '../common/avaxApi'; import { createDimensions } from '../common/fees/dimensions'; import type { GetL1ValidatorResponse, L1ValidatorDetails, FeeConfig, FeeConfigResponse, FeeState, FeeStateResponse, GetBalanceParams, GetBalanceResponse, GetBlockchainsResponse, GetBlockchainStatusResponse, GetCurrentSupplyResponse, GetCurrentValidatorsParams, GetCurrentValidatorsResponse, GetHeightResponse, GetMaxStakeAmountParams, GetMinStakeResponse, GetPendingValidatorsParams, GetPendingValidatorsResponse, GetRewardUTXOsParams, GetRewardUTXOsResponse, GetStakeParams, GetStakeResponse, GetStakingAssetIDParams, GetStakingAssetIDResponse, GetSubnetParams, GetSubnetResponse, GetSubnetsParams, GetSubnetsResponse, GetTimestampResponse, GetTotalStakeResponse, GetTxStatusParams, GetTxStatusResponse, GetValidatorsAtParams, GetValidatorsAtResponse, SampleValidatorsParams, SampleValidatorsResponse, ValidatedByParams, ValidatedByResponse, ValidatesParams, ValidatesResponse, } from './models'; import type { GetRewardUTXOsServerResponse, GetStakeServerResponse, } from './privateModels'; export class PVMApi extends AvaxApi { constructor(baseURL?: string) { super(baseURL, '/ext/bc/P', 'platform', getPVMManager()); } getAssetDescription(assetID: string): Promise { return this.callRpc('getAssetDescription', { assetID, }); } getCurrentValidators( getCurrentValidatorsParams?: GetCurrentValidatorsParams, ): Promise { return this.callRpc( 'getCurrentValidators', getCurrentValidatorsParams, ); } getPendingValidators( getPendingValidatorsParams?: GetPendingValidatorsParams, ): Promise { return this.callRpc( 'getPendingValidators', getPendingValidatorsParams, ); } async getRewardUTXOs( getRewardUTXOsParams: GetRewardUTXOsParams, ): Promise { const resp = await this.callRpc( 'getRewardUTXOs', getRewardUTXOsParams, ); return { ...resp, utxos: resp.utxos.map((bytes) => getPVMManager().unpack(hexToBuffer(bytes), Utxo), ), }; } async getStake(getStakeParams: GetStakeParams): Promise { const resp = await this.callRpc( 'getStake', getStakeParams, ); return { ...resp, stakedOutputs: resp.stakedOutputs.map((bytes) => getPVMManager().unpack(hexToBuffer(bytes), TransferableOutput), ), }; } getValidatorsAt( getValidatorsAtParams: GetValidatorsAtParams, ): Promise { return this.callRpc( 'getValidatorsAt', getValidatorsAtParams, ); } getCurrentSupply(): Promise { return this.callRpc('getCurrentSupply'); } getMaxStakeAmount( getMaxStakeAmountParams: GetMaxStakeAmountParams, ): Promise { return this.callRpc( 'getMaxStakeAmount', getMaxStakeAmountParams, ); } /** * @link https://docs.avax.network/apis/avalanchego/apis/p-chain#platformgetbalance * * @param GetBalanceParams * @returns GetBalanceResponse */ async getBalance( GetBalanceParams: GetBalanceParams, ): Promise { const resp = await this.callRpc<{ balance: string; unlocked: string; lockedStakeable: string; lockedNotStakeable: string; utxoIDs: { txID: string; outputIndex: number; }[]; }>('getBalance', GetBalanceParams); return { balance: BigInt(resp.balance), unlocked: BigInt(resp.unlocked), lockedStakeable: BigInt(resp.lockedStakeable), lockedNotStakeable: BigInt(resp.lockedNotStakeable), utxoIDs: resp.utxoIDs, }; } getBlockchains(): Promise { return this.callRpc('getBlockchains'); } getBlockchainStatus( blockchainID: string, ): Promise { return this.callRpc('getBlockchainStatus', { blockchainID, }); } getHeight(): Promise { return this.callRpc('getHeight'); } getMinStake(): Promise { return this.callRpc('getMinStake'); } getStakingAssetID( getStakingAssetIDParams: GetStakingAssetIDParams, ): Promise { return this.callRpc( 'getStakingAssetID', getStakingAssetIDParams, ); } getSubnet(getSubnetParams: GetSubnetParams): Promise { return this.callRpc('getSubnet', getSubnetParams); } getSubnets(getSubnetsParams: GetSubnetsParams): Promise { return this.callRpc('getSubnets', getSubnetsParams); } getTimestamp(): Promise { return this.callRpc('getTimestamp'); } getTotalStake(subnetID: string): Promise { return this.callRpc('getTotalStake', { subnetID }); } getTxStatus( getTxStatusParams: GetTxStatusParams, ): Promise { return this.callRpc('getTxStatus', getTxStatusParams); } sampleValidators( sampleValidatorsParams: SampleValidatorsParams, ): Promise { return this.callRpc( 'sampleValidators', sampleValidatorsParams, ); } validatedBy( validatedByParams: ValidatedByParams, ): Promise { return this.callRpc('validatedBy', validatedByParams); } validates(validatesParams: ValidatesParams): Promise { return this.callRpc('validates', validatesParams); } // Post-Etna API // get feeConfig for P-Chain async getFeeConfig(): Promise { const resp = await this.callRpc('getFeeConfig'); const { weights, maxCapacity, maxPerSecond, targetPerSecond, minPrice, excessConversionConstant, } = resp; const [bandwidth, dbRead, dbWrite, compute] = weights; return { weights: createDimensions({ bandwidth, dbRead, dbWrite, compute, }), maxCapacity: BigInt(maxCapacity), maxPerSecond: BigInt(maxPerSecond), targetPerSecond: BigInt(targetPerSecond), minPrice: BigInt(minPrice), excessConversionConstant: BigInt(excessConversionConstant), }; } async getFeeState(): Promise { const resp = await this.callRpc('getFeeState'); return { capacity: BigInt(resp.capacity), excess: BigInt(resp.excess), price: BigInt(resp.price), timestamp: resp.timestamp, }; } async getL1Validator(validationID: string): Promise { const resp = await this.callRpc('getL1Validator', { validationID, }); const deactivationOwner = PChainOwner.fromNative( resp.deactivationOwner.addresses.map((a) => parse(a)[2]), Number(resp.deactivationOwner.threshold), ); const remainingBalanceOwner = PChainOwner.fromNative( resp.remainingBalanceOwner.addresses.map((a) => parse(a)[2]), Number(resp.remainingBalanceOwner.threshold), ); return { balance: BigInt(resp.balance), nodeID: resp.nodeID, publicKey: resp.publicKey, subnetID: resp.subnetID, weight: BigInt(resp.weight), deactivationOwner, remainingBalanceOwner, startTime: BigInt(resp.startTime), height: BigInt(resp.height), minNonce: BigInt(resp.minNonce), }; } }