Skip to main content

Overview

Code examples and integration guides for building on Paxeer Network. All examples work with standard Ethereum tools and libraries.

Wallet Connection

Connect Wallet with wagmi

React component for connecting wallets to Paxeer Network.
WalletConnect.tsx
'use client'

import { useAccount, useConnect, useDisconnect } from 'wagmi'
import { Button } from '@/components/ui/button'

export function WalletConnect() {
  const { address, isConnected } = useAccount()
  const { connect, connectors } = useConnect()
  const { disconnect } = useDisconnect()

  if (isConnected) {
    return (
      <div className="space-y-2">
        <p>Connected: {address}</p>
        <Button onClick={() => disconnect()}>
          Disconnect
        </Button>
      </div>
    )
  }

  return (
    <div className="space-y-2">
      {connectors.map((connector) => (
        <Button
          key={connector.id}
          onClick={() => connect({ connector })}
        >
          Connect {connector.name}
        </Button>
      ))}
    </div>
  )
}
Make sure you’ve configured wagmi with Paxeer Network in your wagmi-config.ts file.

Send Transactions

Send Native PAX Tokens

SendPax.tsx
'use client'

import { useSendTransaction } from 'wagmi'
import { parseEther } from 'viem'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { useState } from 'react'

export function SendPax() {
  const [to, setTo] = useState('')
  const [amount, setAmount] = useState('')
  const { sendTransaction, data, isPending, isSuccess } = useSendTransaction()

  const handleSend = () => {
    sendTransaction({
      to: to as `0x${string}`,
      value: parseEther(amount),
    })
  }

  return (
    <div className="space-y-4">
      <Input
        placeholder="Recipient address (0x...)"
        value={to}
        onChange={(e) => setTo(e.target.value)}
      />
      <Input
        placeholder="Amount (PAX)"
        type="number"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
      />
      <Button 
        onClick={handleSend} 
        disabled={isPending || !to || !amount}
      >
        {isPending ? 'Sending...' : 'Send PAX'}
      </Button>
      {isSuccess && (
        <p className="text-green-600">
          Transaction: {data}
        </p>
      )}
    </div>
  )
}

Contract Interactions

Read Contract Data

TokenBalance.tsx
'use client'

import { useReadContract } from 'wagmi'
import { formatUnits } from 'viem'

const ERC20_ABI = [
  {
    name: 'balanceOf',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'owner', type: 'address' }],
    outputs: [{ name: 'balance', type: 'uint256' }],
  },
  {
    name: 'decimals',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint8' }],
  },
] as const

export function TokenBalance({ 
  address, 
  tokenAddress 
}: { 
  address: string; 
  tokenAddress: string 
}) {
  const { data: balance, isLoading: balanceLoading } = useReadContract({
    address: tokenAddress as `0x${string}`,
    abi: ERC20_ABI,
    functionName: 'balanceOf',
    args: [address as `0x${string}`],
  })

  const { data: decimals } = useReadContract({
    address: tokenAddress as `0x${string}`,
    abi: ERC20_ABI,
    functionName: 'decimals',
  })

  if (balanceLoading) return <div>Loading...</div>

  const formattedBalance = balance && decimals 
    ? formatUnits(balance, decimals)
    : '0'

  return (
    <div>
      Balance: {formattedBalance} tokens
    </div>
  )
}

Event Listening

Listen to Contract Events

useTokenTransfers.ts
import { useWatchContractEvent } from 'wagmi'
import { useState } from 'react'

const ERC20_ABI = [
  {
    name: 'Transfer',
    type: 'event',
    inputs: [
      { indexed: true, name: 'from', type: 'address' },
      { indexed: true, name: 'to', type: 'address' },
      { indexed: false, name: 'value', type: 'uint256' }
    ],
  },
] as const

export function useTokenTransfers(tokenAddress: string) {
  const [transfers, setTransfers] = useState<any[]>([])

  useWatchContractEvent({
    address: tokenAddress as `0x${string}`,
    abi: ERC20_ABI,
    eventName: 'Transfer',
    onLogs(logs) {
      setTransfers(prev => [...prev, ...logs])
    },
  })

  return transfers
}

Complete dApp Example

Here’s a complete example of a token transfer dApp:
App.tsx
'use client'

import { useState } from 'react'
import { useAccount, useReadContract, useWriteContract } from 'wagmi'
import { parseUnits, formatUnits } from 'viem'
import { WalletConnect } from './WalletConnect'

const TOKEN_ADDRESS = '0xYourTokenAddress'
const ERC20_ABI = [
  {
    name: 'balanceOf',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'owner', type: 'address' }],
    outputs: [{ name: '', type: 'uint256' }],
  },
  {
    name: 'transfer',
    type: 'function',
    stateMutability: 'nonpayable',
    inputs: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' }
    ],
    outputs: [{ name: '', type: 'bool' }],
  },
] as const

export default function TokenTransferApp() {
  const { address, isConnected } = useAccount()
  const [recipient, setRecipient] = useState('')
  const [amount, setAmount] = useState('')

  const { data: balance } = useReadContract({
    address: TOKEN_ADDRESS,
    abi: ERC20_ABI,
    functionName: 'balanceOf',
    args: address ? [address] : undefined,
  })

  const { writeContract, isPending } = useWriteContract()

  const handleTransfer = () => {
    if (!recipient || !amount) return
    
    writeContract({
      address: TOKEN_ADDRESS,
      abi: ERC20_ABI,
      functionName: 'transfer',
      args: [recipient as `0x${string}`, parseUnits(amount, 18)],
    })
  }

  if (!isConnected) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <WalletConnect />
      </div>
    )
  }

  return (
    <div className="container mx-auto p-4 max-w-md">
      <h1 className="text-2xl font-bold mb-4">Token Transfer</h1>
      
      <div className="bg-gray-100 p-4 rounded-lg mb-4">
        <p className="text-sm text-gray-600">Your Balance</p>
        <p className="text-2xl font-bold">
          {balance ? formatUnits(balance, 18) : '0'} tokens
        </p>
      </div>

      <div className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-2">
            Recipient Address
          </label>
          <input
            type="text"
            value={recipient}
            onChange={(e) => setRecipient(e.target.value)}
            placeholder="0x..."
            className="w-full p-2 border rounded"
          />
        </div>

        <div>
          <label className="block text-sm font-medium mb-2">
            Amount
          </label>
          <input
            type="number"
            value={amount}
            onChange={(e) => setAmount(e.target.value)}
            placeholder="0.0"
            className="w-full p-2 border rounded"
          />
        </div>

        <button
          onClick={handleTransfer}
          disabled={isPending || !recipient || !amount}
          className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 disabled:bg-gray-300"
        >
          {isPending ? 'Transferring...' : 'Transfer Tokens'}
        </button>
      </div>
    </div>
  )
}

Best Practices

Always handle errors gracefully:
try {
  const tx = await writeContract({...});
  await tx.wait();
} catch (error) {
  if (error.code === 'ACTION_REJECTED') {
    console.log('User rejected transaction');
  } else if (error.code === 'INSUFFICIENT_FUNDS') {
    console.log('Insufficient funds');
  } else {
    console.error('Transaction failed:', error);
  }
}
Show loading states for better UX:
const { isPending, isLoading, isSuccess } = useWriteContract();

if (isPending) return <div>Confirm in wallet...</div>;
if (isLoading) return <div>Transaction pending...</div>;
if (isSuccess) return <div>Success!</div>;
Estimate gas before transactions:
const gasEstimate = await contract.transfer.estimateGas(
  toAddress,
  amount
);

const gasLimit = gasEstimate * 120n / 100n; // 20% buffer

Next Steps