Complete API documentation for @pons-network/pons.js.
The Pons Network SDK enables cross-chain transfers and action execution with decentralized operators and dynamic fees.
import {
PonsClient,
Chain,
calculateFeesSync,
ActionBuilder,
TransferStatus
} from '@pons-network/pons.js';Source Chain ──────► Pons Network ──────► Destination Chain
│ │ │
Message Relay & Message
Sent Attestation Indexed
│
Action Executed
Calculate fees with dynamic fee rates.
Parameters:
| Name | Type | Description |
|---|---|---|
sendAmount |
bigint |
Amount of USDC to send (6 decimals) |
options.indexerFee |
bigint? |
Indexer fee - DYNAMIC (default: 100000n) |
options.resolverFee |
bigint? |
Resolver fee - DYNAMIC (default: 150000n) |
options.protocolFeeBps |
bigint? |
Protocol fee in basis points (default: 10n) |
Returns:
{
burnAmount: bigint; // Input send amount
cctpFee: bigint; // Network fee
expectedAmount: bigint; // Amount arriving at Smart Account
protocolFee: bigint; // Protocol fee
indexerFee: bigint; // Indexer operator fee (dynamic)
resolverFee: bigint; // Resolver operator fee (dynamic)
totalFees: bigint; // Sum of all fees after network fee
amountForAction: bigint; // Available for action
}Example:
import { calculateFeesSync } from '@pons-network/pons.js';
import { parseUnits } from 'viem';
// Standard speed
const standard = calculateFeesSync(parseUnits('15', 6));
// Fast speed (higher fees = faster)
const fast = calculateFeesSync(parseUnits('15', 6), {
indexerFee: parseUnits('0.2', 6),
resolverFee: parseUnits('0.3', 6),
});
// Economy (lower fees = slower but cheaper)
const economy = calculateFeesSync(parseUnits('15', 6), {
indexerFee: parseUnits('0.05', 6),
resolverFee: parseUnits('0.08', 6),
});Reverse calculation: determine send amount needed for a specific action amount.
Parameters:
| Name | Type | Description |
|---|---|---|
actionAmount |
bigint |
Amount needed for action |
options |
Same as calculateFeesSync |
Fee configuration |
Returns: Same structure, but amountForAction equals input actionAmount
Example:
// I need exactly 10 USDC for my action - how much to send?
const fees = calculateBurnForAction(parseUnits('10', 6));
// With fast execution
const fastFees = calculateBurnForAction(parseUnits('10', 6), {
indexerFee: parseUnits('0.2', 6),
resolverFee: parseUnits('0.3', 6),
});Validate if send amount is sufficient for an action.
Returns:
{
feasible: boolean; // Is it possible?
burnAmount: bigint; // Input send amount
amountForAction: bigint; // Available after fees
actionCost: bigint; // Input action cost
surplus: bigint; // Extra amount if feasible
shortfall: bigint; // Missing amount if not feasible
minimumBurn: bigint; // Minimum send needed
message: string; // Human-readable message
}Default fee constants (standard market rate).
const DEFAULT_FEES = {
CCTP_FEE_BPS: 1n, // ~0.01% network fee
PROTOCOL_FEE_BPS: 10n, // ~0.1% protocol fee
INDEXER_FEE: 100000n, // 0.1 USDC (standard rate)
RESOLVER_FEE: 150000n, // 0.15 USDC (standard rate)
};Main client for cross-chain operations.
new PonsClient(config: PonsClientConfig)Config:
interface PonsClientConfig {
from: string | Chain; // Source chain
to: string | Chain; // Destination chain
sourceRpcUrl: string; // Source chain RPC
destinationRpcUrl: string; // Destination chain RPC
gatewayUrl?: string; // Pons gateway URL
factoryAddress?: Address; // SmartAccountFactory address
}Create and initialize a PonsClient instance.
const pons = await PonsClient.create({
from: Chain.SEPOLIA,
to: Chain.ARC_TESTNET,
sourceRpcUrl: '...',
destinationRpcUrl: '...',
});Execute a cross-chain transfer with action.
This method:
- Has user sign EIP-712 action
- Sends message on source chain
- Publishes to Pons Network
- Returns immediately (decentralized operators complete the rest)
Parameters:
interface CCTPTransferParams {
amount: bigint; // Amount to send
action: ActionOptions; // Action to execute on destination
}Returns:
{
txHash: Hex; // Source chain TX hash
smartAccountAddress: Address; // User's Smart Account
nonce: bigint; // Transfer nonce
}Create a transfer tracker to monitor execution.
const tracker = pons.trackTransfer(
result.txHash,
result.smartAccountAddress,
result.nonce
);Calculate the deterministic Smart Account address.
const address = await pons.calculateSmartAccountAddress(
'0x1234...',
0n
);Cleanup and close connections.
await pons.stop();Build complex cross-chain actions.
new ActionBuilder()Add a contract call to the action.
builder.addCall(
'0xContract...',
'0x...', // Encoded calldata
0n // Optional ETH value
);Set fee configuration (dynamic fees).
// Standard fees
builder.withFees(USDC_ADDRESS, parseUnits('0.1', 6), parseUnits('0.15', 6));
// Fast fees
builder.withFees(USDC_ADDRESS, parseUnits('0.2', 6), parseUnits('0.3', 6));Request ETH from resolver.
builder.needsEth(
parseEther('0.1'), // ETH needed for action
parseUnits('250', 6) // USDC reimbursement to resolver
);Request tokens from resolver.
builder.needsTokens(
[TOKEN_ADDRESS],
[parseUnits('100', 18)],
parseUnits('50', 6)
);Build the final action object.
const action = builder.build(
BigInt(Date.now()),
BigInt(Math.floor(Date.now() / 1000) + 3600),
expectedAmount
);Create a no-action (simple bridge) configuration.
const action = ActionBuilder.noAction(parseUnits('100', 6));Track cross-chain transfer status through decentralized execution.
| Event | Callback Type | Description |
|---|---|---|
statusChange |
(status: TransferStatus, data?: any) => void |
Any status change |
sent |
(data: { txHash: Hex }) => void |
Message sent |
indexed |
(data: { txHash: Hex }) => void |
Message indexed |
executed |
(data: { txHash: Hex }) => void |
Action executed |
failed |
(error: Error) => void |
Transfer failed |
Subscribe to events.
tracker.on('statusChange', (status) => {
console.log(status);
});
tracker.on('indexed', (data) => {
console.log('Message indexed:', data.txHash);
});
tracker.on('executed', (data) => {
console.log('Action executed:', data.txHash);
});Wait for a specific status.
await tracker.waitForStatus(TransferStatus.EXECUTED, {
timeout: 30 * 60 * 1000, // 30 minutes
});import { arcTestnet, sepolia, Chain } from '@pons-network/pons.js';
const pons = await PonsClient.create({
from: Chain.SEPOLIA,
to: Chain.ARC_TESTNET,
// ...
});
// Chain properties
console.log(sepolia.id); // 11155111
console.log(sepolia.domain); // 0
console.log(sepolia.usdc); // '0x...'const customChain = createChainConfig({
id: 42161,
name: 'Arbitrum One',
domain: 3,
rpcUrl: 'https://arb1.arbitrum.io/rpc',
usdc: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
tokenMessenger: '0x...',
messageTransmitter: '0x...',
});// Action configuration
interface ActionOptions {
target: Address;
callData: Hex;
value?: bigint;
feeConfig: FeeConfig;
permit2Setup?: Permit2Setup[];
funding?: Funding;
}
// Fee configuration (DYNAMIC fees)
interface FeeConfig {
paymentToken: Address;
indexerFee: bigint; // Dynamic - set by user
resolverFee: bigint; // Dynamic - set by user
}
// Funding requirements
interface Funding {
ethNeeded: bigint;
tokensNeeded: Address[];
tokenAmounts: bigint[];
maxReimbursement: bigint;
}
// Transfer result
interface TransferResult {
txHash: Hex;
smartAccountAddress: Address;
nonce: bigint;
}enum TransferStatus {
PENDING = 'pending', // Waiting for source confirmation
SENT = 'sent', // Message sent on source
ATTESTED = 'attested', // Attestation verified
INDEXING = 'indexing', // Indexer processing
INDEXED = 'indexed', // Message indexed on destination
EXECUTING = 'executing', // Resolver processing
EXECUTED = 'executed', // Action complete
FAILED = 'failed', // Action failed
}const Chain = {
SEPOLIA: 'sepolia',
ARC_TESTNET: 'arc-testnet',
ETHEREUM: 'ethereum',
} as const;const DEFAULT_FEES = {
CCTP_FEE_BPS: 1n, // Network fee
PROTOCOL_FEE_BPS: 10n, // Protocol fee
INDEXER_FEE: 100000n, // 0.1 USDC (standard)
RESOLVER_FEE: 150000n, // 0.15 USDC (standard)
};const FEE_LEVELS = {
fast: {
indexerFee: parseUnits('0.2', 6),
resolverFee: parseUnits('0.3', 6),
},
standard: {
indexerFee: parseUnits('0.1', 6),
resolverFee: parseUnits('0.15', 6),
},
economy: {
indexerFee: parseUnits('0.05', 6),
resolverFee: parseUnits('0.08', 6),
},
};Pons Network is permissionless - anyone can earn fees by running operators:
- Monitor for messages
- Index on destination chain
- Earn indexer fee (dynamic)
- Execute user actions
- Provide ETH/tokens if needed
- Earn resolver fee (dynamic)
- Users choose speed vs cost
- Operators compete for profitable transactions
- Market equilibrium finds fair prices
- No fixed fees - adapts to network demand
# Run indexer
docker run pons/resolver:latest --mode indexer
# Run resolver
docker run pons/resolver:latest --mode executor
# Run both
docker run pons/resolver:latest --mode bothSee Resolver Documentation for setup details.