Skip to main content

Implementation Examples

This page provides code examples and patterns from real node implementations.

Example 1: Simple API Integration

A basic node that integrates with a simple REST API:

class SimpleApiNode implements Node {
private apiKey: string;
private baseUrl: string = "https://api.example.com";
supportedTokens: ChainToken[] = [];
supportedChainIds: string[] = [];

constructor(apiKey: string) {
this.apiKey = apiKey;
}

async syncState(): Promise<NodeResult<void>> {
try {
const response = await fetch(`${this.baseUrl}/tokens`, {
headers: { 'Authorization': `Bearer ${this.apiKey}` }
});
const data = await response.json();

this.supportedTokens = data.tokens.map(token => ({
chain_id: token.chainId,
address: token.address,
decimals: token.decimals
}));

this.supportedChainIds = [...new Set(data.tokens.map(t => t.chainId))];

} catch (error) {
return new NodeError("Failed to sync tokens", NodeError.errorCodes.NetworkError);
}
}

// Implement other methods...
}

Example 2: Multi-Mode Node

A node that supports multiple modes with different configurations:

enum MyNodeMode {
FAST,
CHEAP,
SECURE
}

class MyNode implements Node {
constructor(private mode: MyNodeMode) {
// Initialize based on mode
switch (mode) {
case MyNodeMode.FAST:
this.nodeConfig.timeout = 10000;
break;
case MyNodeMode.CHEAP:
this.nodeConfig.timeout = 60000;
break;
case MyNodeMode.SECURE:
this.nodeConfig.timeout = 30000;
break;
}
}

// Mode-specific implementations...
}

Real-World References

NEAR Intents Integration

Location: ts/src/nodes/near/common.ts

Key patterns:

  • Parameter shaping for quotes
  • Address validation
  • Multi-chain calldata generation
  • Asset ID resolution with fallbacks
// Example: Address validation
private validateAndFormatAddress(address: string): string {
// NEAR-specific address validation and formatting
}

// Example: Asset ID resolution
private findAssetId(token: ChainToken): string | null {
// Resolve asset IDs with multiple fallback strategies
}

Meson Swapping Integration

Location: ts/src/nodes/meson/common.ts

Key patterns:

  • Price and limits checking
  • Transaction data encoding
  • Error code decoding
  • Cache management for limits
// Example: Price quote with limits check
private async getPriceQuote(input: SwapRequest): Promise<NodeResult<any>> {
// Check limits first
const limits = await this.getLimits();
// Then get price quote
// Handle API errors with decoded error codes
}

GasZip Native Bridging

Location: ts/src/nodes/gaszip/common.ts and ts/src/nodes/gaszip/solana-calldata.ts

Key patterns:

  • Native token handling
  • Chain ID mapping (name ↔ ID)
  • Solana transaction construction
  • Capacity validation
// Example: Chain ID normalization
private normalizeChainId(chainId: string): string {
// Map between numeric IDs and human-readable names
}

// Example: Solana calldata generation
private generateSolanaCalldata(request: SwapRequest): string {
// Construct Solana transaction instructions
}

Common Patterns

Token Address Normalization

private normalizeTokenAddress(address: string, chainId: string): string {
// Handle native tokens
if (address === '0x0000000000000000000000000000000000000000') {
return this.getNativeTokenAddress(chainId);
}

// Normalize EVM addresses
if (address.startsWith('0x')) {
return address.toLowerCase();
}

return address;
}

Chain ID Normalization

private normalizeChainId(chainId: string): string {
const chainIdMap: Record<string, string> = {
'1': 'ethereum',
'137': 'polygon',
'56': 'bsc',
};

return chainIdMap[chainId] || chainId.toLowerCase();
}

API Call with Retry Logic

private async makeApiCall<T>(url: string, options: RequestInit): Promise<NodeResult<T>> {
const maxRetries = this.nodeConfig.retryConfig?.maxRetries || 3;
let lastError: Error;

for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, {
...options,
timeout: this.nodeConfig.timeout,
});

if (response.ok) {
return await response.json();
}

lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);

// Don't retry on client errors
if (response.status >= 400 && response.status < 500) {
break;
}

} catch (error) {
lastError = error as Error;
}

// Wait before retry
if (attempt < maxRetries - 1) {
await new Promise(resolve =>
setTimeout(resolve, this.nodeConfig.retryConfig?.retryDelay || 1000)
);
}
}

return new NodeError(
`API call failed after ${maxRetries} attempts: ${lastError.message}`,
NodeError.errorCodes.NetworkError
);
}

Next Steps