UPC — Universal Private ComplianceASP Operators

ASP Setup

Step-by-step guide to deploying an ASP using upc-asp-whitelist.

ASP Setup

Prerequisites

  • Node.js 18+
  • An Ethereum account with enough ETH for gas (registration + root publishing)
  • An RPC endpoint for the target chain

Install

npm install @permissionless-technologies/upc-asp-whitelist

Configuration

Create a .env file:

# Required
PRIVATE_KEY=0x...              # ASP operator private key
RPC_URL=https://...            # Ethereum RPC URL
REGISTRY_ADDRESS=0x...         # AttestationHub contract address

# Optional
PORT=3000                      # REST API port (default: 3000)
DB_PATH=./asp.db               # SQLite database path (default: :memory:)
ROOT_PUBLISH_INTERVAL=3600000  # Root publish interval in ms (default: 1 hour)
ROOT_TTL=86400000              # Root TTL in ms (default: 24 hours)

Start the ASP Service

import { createWhitelistASP } from '@permissionless-technologies/upc-asp-whitelist'
import { createPublicClient, createWalletClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(process.env.RPC_URL),
})

const walletClient = createWalletClient({
  chain: mainnet,
  transport: http(process.env.RPC_URL),
  account: privateKeyToAccount(process.env.PRIVATE_KEY),
})

const asp = createWhitelistASP({
  registryAddress: process.env.REGISTRY_ADDRESS,
  publicClient,
  walletClient,
  port: Number(process.env.PORT),
  publishInterval: Number(process.env.ROOT_PUBLISH_INTERVAL),
})

// Register on-chain (first time only)
const { aspId } = await asp.register({
  name: 'My Compliance ASP',
  description: 'OFAC-screened addresses for DeFi protocol',
  url: 'https://my-asp.example.com',
})

console.log('ASP ID:', aspId)

// Start the service
await asp.start()
console.log(`ASP service running on port ${process.env.PORT}`)

Managing Members

Via CLI:

# Add a member
npx upc-asp add-member --aspId 1 --address 0x...

# Remove a member
npx upc-asp remove-member --aspId 1 --address 0x...

# List all members
npx upc-asp list-members --aspId 1

# Publish root now
npx upc-asp publish-root --aspId 1

Via API (once service is running):

# Add member
curl -X POST https://my-asp.example.com/api/members \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address": "0x..."}'

# List members
curl https://my-asp.example.com/api/members

Verify Setup

# Check ASP is registered on-chain
curl https://my-asp.example.com/api/status

# Get current root
curl https://my-asp.example.com/api/root

Production Checklist

Before going live:

  • Use a production-grade database (PostgreSQL, not SQLite)
  • Set up monitoring for root publish failures
  • Configure alerts for unexpected membership changes
  • Enable API authentication
  • Set up a backup operator key
  • Test the full proof generation + verification flow

On this page