npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@polymerdao/polymer-api-client

v0.3.0

Published

TypeScript client library for interacting with Polymer's proof API and blockchain verification

Readme

Polymer API Client

TypeScript client library for interacting with Polymer's proof API and blockchain verification. Provides a complete SDK for requesting proofs, verifying cryptographic signatures, and accessing blockchain data.

npm version

🚀 Installation

npm install @polymerdao/polymer-api-client

🎯 Quick Start

import { PolymerOpenRpcClient, ProofVerifier, ChainlistClient } from '@polymerdao/polymer-api-client';

// Initialize the client
const client = new PolymerOpenRpcClient('your-api-key', 'https://api.polymer.zone/v1');

// Request a proof
const proofRequest = await client.proofRequest({
  srcChainId: 1, // Ethereum
  globalLogIndex: 12345,
  srcBlockNumber: 19000000
});

// Query proof status
const status = await client.proofQueryJob({ id: proofRequest.jobId });

// Verify a proof
const verifier = new ProofVerifier('0x4632e987c6f31d6351e39324dec6f1404af56209', 444);
const isValid = await verifier.verifyProof(proofData);

📚 API Reference

PolymerOpenRpcClient

Main client for interacting with Polymer's API.

import { PolymerOpenRpcClient } from '@polymerdao/polymer-api-client';

const client = new PolymerOpenRpcClient(apiKey, baseUrl);

Proof Methods

Request a proof:

const request = await client.proofRequest({
  srcChainId: number,        // Source chain ID (e.g., 1 for Ethereum)
  globalLogIndex: number,    // Global log index of the event
  srcBlockNumber: number     // Block number containing the event
});
// Returns: { jobId: number, status: string }

Query proof job:

const status = await client.proofQueryJob({
  id: number                 // Job ID from proof request
});
// Returns: { jobId: number, status: string, proof?: string, ... }

Query with filters:

const results = await client.proofQueryWithFilter({
  chainId?: number,
  status?: string,
  limit?: number,
  offset?: number
});

Get job statistics:

const stats = await client.proofQueryJobStats();

Execution Methods

Submit execution request:

const execution = await client.executeRequest({
  proofRequest: {
    srcChainId: 11155420,         // Optional: request proof generation on the fly
    srcBlockNumber: 29540611,
    globalLogIndex: 5,
  },
  executeRequest: {
    destChainId: 84532,
    destContractAddress: '0xdda9a457771534eDba705E1D79B1ed0f732d642E',
    methodSignature: 'setValueFromSource(string,bytes,bytes)',
    args: ['tester', '0x1234', '$proof'], // '$proof' is replaced with the generated proof bytes
    gasLimit: 1_000_000,
  },
  // Alternatively, omit proofRequest and provide a pre-generated proof:
  // proof: 'base64_proof_payload'
});

Query execution:

const status = await client.executeQuery({
  id: number                 // Execution job ID
});

Info Methods

Get connected chains:

const chains = await client.infoGetConnectedChains();

Get client updates:

const updates = await client.infoGetClientUpdates();

ProofVerifier

Cryptographic proof verification utilities.

import { ProofVerifier } from '@polymerdao/polymer-api-client';

const verifier = new ProofVerifier(
  validationKey,     // Ethereum address for ECDSA verification
  polymerChainId     // Polymer chain ID (default: 444)
);

Verify a proof:

const isValid = await verifier.verifyProof(proofData);
// Returns: boolean

Parse proof data:

const parsed = verifier.parseProof(proofData);
// Returns: { appHash: string, peptideHeight: number, signature: {...}, ... }

Verify ECDSA signature:

const isValidSig = verifier.verifySignature(messageHash, signature, expectedAddress);

ChainlistClient

Client for accessing blockchain RPC endpoints and chain information.

import { ChainlistClient } from '@polymerdao/polymer-api-client';

const chainlist = new ChainlistClient();

Get chain information:

const chains = await chainlist.getChains();
// Returns: Array of chain objects with RPC endpoints

Get RPC endpoints for a chain:

const rpcs = await chainlist.getChainRpcs('ethereum');
// Returns: Array of RPC endpoint objects

Execute RPC call:

const result = await chainlist.executeRpc(
  'ethereum',           // Chain name
  'eth_getBlockByNumber', // RPC method
  ['latest', false]     // Method parameters
);

Cache management:

// Get cache statistics
const stats = chainlist.getCacheStats();

// Clear cache
chainlist.clearCache();

🔧 Configuration

Environment Setup

// Using environment variables
process.env.POLYMER_API_KEY = 'your-api-key';
process.env.POLYMER_API_BASE = 'https://api.polymer.zone/v1';

const client = new PolymerOpenRpcClient(
  process.env.POLYMER_API_KEY!,
  process.env.POLYMER_API_BASE
);

Custom Configuration

const client = new PolymerOpenRpcClient(
  'your-api-key',
  'https://staging.polymer.zone/v1',  // Custom API base
  {
    timeout: 30000,                    // 30 second timeout
    retries: 3,                        // Retry failed requests
    headers: {                         // Custom headers
      'User-Agent': 'MyApp/1.0'
    }
  }
);

📊 Examples

Complete Proof Workflow

import { PolymerOpenRpcClient, ProofVerifier } from '@polymerdao/polymer-api-client';

async function completeProofWorkflow() {
  const client = new PolymerOpenRpcClient('your-api-key');
  const verifier = new ProofVerifier('0x4632e987c6f31d6351e39324dec6f1404af56209', 444);

  // 1. Request proof
  const request = await client.proofRequest({
    srcChainId: 1,           // Ethereum
    globalLogIndex: 12345,   
    srcBlockNumber: 19000000
  });

  console.log(`Proof requested: Job ID ${request.jobId}`);

  // 2. Poll for completion
  let status;
  do {
    await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
    status = await client.proofQueryJob({ id: request.jobId });
    console.log(`Status: ${status.status}`);
  } while (status.status === 'pending');

  // 3. Verify proof if completed
  if (status.status === 'completed' && status.proof) {
    const isValid = await verifier.verifyProof(status.proof);
    console.log(`Proof valid: ${isValid}`);
    
    // Parse proof details
    const parsed = verifier.parseProof(status.proof);
    console.log('Proof details:', parsed);
  }
}

Cross-Chain Execution

async function executecrossChain() {
  const client = new PolymerOpenRpcClient('your-api-key');

  // Prepare execution envelope
  const envelope = {
    proof: 'base64_encoded_proof_data',
    executeRequest: {
      destChainId: 137,  // Polygon
      destContractAddress: '0x...', // Target contract
      methodSignature: 'setProof(bytes)',
      args: ['$proof'], // '$proof' gets replaced with proof bytes
    }
  };

  // Submit execution
  const execution = await client.executeRequest(envelope);
  console.log(`Execution submitted: ${execution.jobId}`);

  // Monitor execution
  const result = await client.executeQuery({ id: execution.jobId });
  console.log('Execution result:', result);
}

Blockchain Data Access

async function accessBlockchainData() {
  const chainlist = new ChainlistClient();

  // Get latest Ethereum block
  const latestBlock = await chainlist.executeRpc(
    'ethereum',
    'eth_getBlockByNumber',
    ['latest', false]
  );

  console.log('Latest block:', latestBlock);

  // Get contract events
  const logs = await chainlist.executeRpc(
    'ethereum',
    'eth_getLogs',
    [{
      fromBlock: '0x1234567',
      toBlock: 'latest',
      address: '0x...',
      topics: ['0x...']
    }]
  );

  console.log('Contract events:', logs);
}

Error Handling

import { PolymerApiError } from '@polymerdao/polymer-api-client';

async function handleErrors() {
  try {
    const client = new PolymerOpenRpcClient('invalid-key');
    await client.proofRequest({ srcChainId: 1, globalLogIndex: 1, srcBlockNumber: 1 });
  } catch (error) {
    if (error instanceof PolymerApiError) {
      console.error('API Error:', error.message);
      console.error('Status Code:', error.statusCode);
      console.error('Response:', error.response);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

🧪 Testing

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run specific test file
npm test -- chainlist.test.ts

Example Test

import { PolymerOpenRpcClient } from '@polymerdao/polymer-api-client';

describe('PolymerOpenRpcClient', () => {
  it('should request a proof', async () => {
    const client = new PolymerOpenRpcClient('test-key');
    
    // Mock the API call
    const mockResponse = { jobId: 123, status: 'pending' };
    jest.spyOn(client, 'proofRequest').mockResolvedValue(mockResponse);

    const result = await client.proofRequest({
      srcChainId: 1,
      globalLogIndex: 12345,
      srcBlockNumber: 19000000
    });

    expect(result.jobId).toBe(123);
    expect(result.status).toBe('pending');
  });
});

🔧 Development

Building from Source

# Clone the monorepo
git clone https://github.com/polymerdao/mcp-polymer.git
cd mcp-polymer/packages/api-client

# Install dependencies
npm install

# Build
npm run build

# Generate client from OpenRPC spec
npm run generate-client

Project Structure

src/
├── index.ts              # Main exports
├── client.ts             # PolymerOpenRpcClient implementation
├── verification.ts       # ProofVerifier implementation
├── chainlist.ts          # ChainlistClient implementation
├── types.ts              # TypeScript type definitions
└── generated-client.ts   # Auto-generated from OpenRPC spec

Code Generation

The client includes auto-generated methods from Polymer's OpenRPC specification:

# Regenerate client methods
npm run generate-client

📄 Type Definitions

Core Types

interface ProofRequest {
  srcChainId: number;
  globalLogIndex: number;
  srcBlockNumber: number;
}

interface ProofResponse {
  jobId: number;
  status: 'pending' | 'completed' | 'failed';
  proof?: string;
  error?: string;
}

interface ExecuteEnvelope {
  proof: string;
  executeRequest: {
    chainId: number;
    payload: string;
  };
}

interface ChainInfo {
  chainId: number;
  name: string;
  rpc: string[];
  nativeCurrency: {
    name: string;
    symbol: string;
    decimals: number;
  };
}

🤝 Contributing

See the main repository README for contribution guidelines.

Adding New Features

  1. Add feature to appropriate client class
  2. Update type definitions in types.ts
  3. Add tests for new functionality
  4. Update this README with examples

📄 License

Apache 2.0 License - see LICENSE for details.