On this page
Source: paxeer-network/precompiles/setup.go and each precompile's abi.json and Go implementation.

Fixed addresses and interfaces

Paxeer implements precompiles natively in the node. Call them with their matching ABI rather than expecting deployed Solidity bytecode. Match your client bindings to the node revision you use.

AddressCapabilityCurrent interface
0x1001BankNative balances, metadata, supply, pointer-authorized sends, native value transfers
0x1002CosmWasminstantiate, execute, execute_batch, query
0x1003JSONExtract bytes, byte lists, unsigned integers, and array elements
0x1004Address associationgetPaxAddr, getEvmAddr, associate, associatePubKey
0x1005StakingDelegation and validator transactions, queries, pagination, pool, and parameters
0x1006Governancevote, voteWeighted, deposit, submitProposal
0x1007DistributionReward queries, withdrawals, withdrawal address, and validator commission
0x1008OracleRegistered, but both price-query methods revert as retired
0x1009IBC transfertransfer, transferWithDefaultTimeout
0x100aPointer lookupNative, CW20, CW721, and CW1155 pointer address, version, and existence
0x100bPointer creationaddNativePointer, addCW20Pointer, addCW721Pointer, addCW1155Pointer
0x100cSolo asset claimsclaim(bytes), claimSpecific(bytes) using signed Cosmos transaction payloads
0x1011P-256 signaturesverify(bytes)

Addresses in the table are shortened for readability. Pad them to 20 bytes, for example 0x0000000000000000000000000000000000001001. precompiles/common/ supplies shared gas, payment, ABI, and error handling; it is not another callable precompile.

Address association

getPaxAddr(address) resolves an existing EVM-to-Paxeer association. getEvmAddr(string) performs the reverse lookup. Account addresses use pax1; validator operator addresses use paxvaloper1. These lookups can fail when no association exists; they are not interchangeable with a bech32 encoding of the same 20 bytes.

The manual association methods derive both addresses from a public key or signature. Use the key belonging to the account being linked. Creating a new random wallet would associate a different account. Signature construction must match the exact message bytes expected by addr.go; an application timestamp is not a replay-protection mechanism enforced by that method.

Bank balances and transfers

Bank amounts are integers in the supplied base denomination. The native bank denomination is uhpx: one PAX equals 1,000,000 uhpx, while EVM transaction value uses 10^18 wei per PAX. The internal human-unit identifier is hpx; see network parameters for the unit mapping.

// Minimal ABI for a read; use the full bank/abi.json for other methods.
import { Contract, JsonRpcProvider, formatUnits } from 'ethers'

const provider = new JsonRpcProvider(process.env.PAXEER_EVM_RPC_URL)
if ((await provider.getNetwork()).chainId !== 125n) throw new Error('Wrong chain')
const bank = new Contract(
  '0x0000000000000000000000000000000000001001',
  ['function balance(address,string) view returns (uint256)',
   'function decimals(string) view returns (uint8)'],
  provider,
)
const account = process.env.PAXEER_ACCOUNT_ADDRESS
if (!account) throw new Error('Set PAXEER_ACCOUNT_ADDRESS')
const amount = await bank.balance(account, 'uhpx')
console.log('bank base units:', amount.toString())
console.log('PAX:', formatUnits(amount, 6))
console.log('bank denomination decimals:', await bank.decimals('uhpx')) // 0

bank.decimals(denom) returns 0 because the ABI represents base-denomination integers. It does not return the display exponent of PAX. The name and symbol methods require bank denomination metadata.

  • send(address from, address to, string denom, uint256 amount) is nonpayable and restricted to the registered ERC-20 native pointer for that denomination. An arbitrary wrapper or wallet cannot call it successfully just by supplying a sender.
  • sendNative(string toAddress) is payable, sends EVM value to a Paxeer bech32 recipient, and preserves both whole uhpx and the smaller wei remainder. The caller must be associated; delegatecall is rejected.
  • all_balances(address) and supply(string) also expose base-denomination amounts.

Staking and distribution

Staking writes act for the immediate caller's associated account. A contract wrapper therefore controls its own position; querying its deployer's delegation does not inspect that position. Delegatecall is rejected.

Operation or resultUnits and behavior
delegate / createValidator valueWei; must be an exact multiple of 10^12. Fractional uhpx is rejected.
redelegate / undelegate amountInteger native staking denomination, normally uhpx.
delegation balanceInteger amount with its denomination; delegation shares have a separate 18-digit fixed-point scale.
distribution.rewards coin amount18-digit fixed-point amount of the returned denomination. For uhpx, divide by 10^18 for uhpx or 10^24 for PAX.
Withdrawn reward amountNative integer denomination. For uhpx, divide by 10^6 for PAX.

The staking ABI also exposes validator creation and editing; validator, delegation, unbonding, and redelegation queries; historical information; pool; and params. Read current parameters for unbonding time and entry limits. Paginated queries return a bytes cursor: with ethers, an empty cursor is 0x, whose JavaScript string length is two.

Distribution supports setWithdrawAddress, withdrawDelegationRewards, withdrawMultipleDelegationRewards, withdrawValidatorCommission, and rewards. The withdrawal target must be associated. Some validator addresses are indexed strings in EVM events; an indexed string topic is a hash, not the original bech32 text.

Governance transactions

The governance ABI exposes writes only. Use the native module query APIs to inspect proposals and live deposit or voting parameters. voteWeighted takes option/decimal-string tuples; weights must be valid, use distinct options, and sum exactly to one. A new vote can replace the same voter's existing vote while the proposal is active.

deposit and submitProposal receive the native deposit through EVM value, with exact whole-uhpx payment conversion. submitProposal accepts the JSON shape implemented by gov/handler.go and returns a proposal ID in ABI return data. It does not emit a ProposalSubmitted EVM event, so do not search receipt logs for that invented event.

JSON extraction

The JSON ABI provides extractAsBytes(bytes,string), extractAsBytesList(bytes,string), extractAsUint256(bytes,string), and extractAsBytesFromArray(bytes,uint16). Keys select a literal top-level field. To read a nested field, first extract its containing object.

Byte-list results preserve each element's JSON representation, including quotes around strings. Decode returned hex bytes before parsing JSON. Integer extraction accepts decimal integers and quoted integer strings, rejects negative or oversized values, and does not implement floating-point conversion.

// With json connected to the current precompiles/json/abi.json:
const document = toUtf8Bytes(JSON.stringify({ user: { count: '42' }, tags: ['one'] }))
const user = await json.extractAsBytes(document, 'user')
const count = await json.extractAsUint256(user, 'count') // 42n
const tags = await json.extractAsBytesList(document, 'tags')
const firstTag = JSON.parse(toUtf8String(tags[0])) // 'one'

The helper functions toUtf8Bytes and toUtf8String above are ethers exports. The implementation charges 100 gas per ABI argument byte, excluding the selector; total transaction gas includes other execution and transaction costs.

P-256 signature verification

At 0x1011, verify(bytes) takes exactly 160 payload bytes: a 32-byte digest followed by 32-byte r, s, public-key x, and public-key y. Valid signatures return ABI-encoded bytes containing a 32-byte word with value one. Invalid signatures return empty low-level call data rather than an ABI-encoded result; handle that case before decoding. Malformed payload length reverts.

This is an ABI call with a dynamic bytes argument. The 160-byte payload occupies 224 argument bytes after its offset and length words, so the precompile charges 224 × 300 = 67,200 precompile execution gas, before other call or transaction costs. P-256 verification is one part of a passkey flow; challenge, origin, authenticator data, and replay handling belong to the complete application ceremony.

Cross-runtime and cross-chain calls

The CosmWasm guide covers matching the native coin list to payable EVM value. WASM bindings expose calls in the other direction. The IBC guide covers the transfer ABI, which does not expose channel queries.

Pointer lookup returns the pointer address, a version, and an existence flag for one supplied native denomination or CosmWasm address. It does not provide a list-all query. Solo claims consume signed Cosmos transaction payloads; they are asset-claim operations rather than a general administrative interface.

Retired Oracle API

getExchangeRates and getOracleTwaps at 0x1008 revert with oracle precompile is retired; oracle data queries are disabled. See the Oracle module guide for native query interfaces.

ABI and failure handling

Use the matching precompiles/<name>/abi.json, simulate the real caller and value, and inspect revert data before sending a transaction. Most module precompiles meter native execution dynamically; sample gas figures are not fixed limits. An off-chain read needs no funded signer, while an on-chain call still consumes gas.

In particular, address lookup is getPaxAddr in this tree. An SDK package targeting another chain can carry different selectors, chain IDs, prefixes, or addresses even when its API looks similar.

Paxeer Network · Developer documentationBack to top ↑

Ask Paxeer Docs

Answers from the documentation.

What would you like to know?

Ask a question, find a guide, or get help with your next step.

Enter to send · Shift+Enter for a new line