Elliptic Integration for Compliance
Elliptic is a Chainalysis competitor with several technical advantages: deeper DeFi coverage, cross-chain tracing (fund tracking between chains via bridges), and Solana support. The API differs from Chainalysis in structure.
Elliptic Lens API (wallet screening)
class EllipticClient {
private readonly BASE_URL = "https://aml.elliptic.co/v2";
async screenWallet(address: string, asset: string): Promise<EllipticWalletRisk> {
const response = await this.post("/wallet/synchronous", {
subject: {
asset,
type: "address",
hash: address,
blockchain: this.getBlockchain(asset),
},
type: "wallet_exposure",
customer_reference: address,
behaviour_classification: true, // includes cluster behavior data
});
return {
riskScore: response.risk_score, // 0-10 (Elliptic has different scale!)
riskBand: response.risk_band, // "low" | "medium" | "high" | "very_high"
exposures: response.exposures, // breakdown of direct and indirect exposure
entities: response.entities,
behaviours: response.behaviours,
};
}
async screenTransaction(txHash: string, asset: string): Promise<EllipticTxRisk> {
return this.post("/transaction/synchronous", {
subject: {
asset,
type: "transaction",
hash: txHash,
blockchain: this.getBlockchain(asset),
},
type: "indirect_exposure",
});
}
private getBlockchain(asset: string): string {
const map: Record<string, string> = {
ETH: "ethereum",
BTC: "bitcoin",
USDT: "ethereum", // or tron
SOL: "solana",
BNB: "bsc",
};
return map[asset] || asset.toLowerCase();
}
}
Risk Score Normalization
Elliptic uses a 0-10 scale, Chainalysis uses 0-100. When using both providers, normalization is needed:
function normalizeRiskScore(score: number, provider: "chainalysis" | "elliptic"): number {
if (provider === "elliptic") return score * 10; // 0-10 → 0-100
return score; // chainalysis already 0-100
}
// Risk band mapping for unified decision making
function getRiskDecision(score: number): "allow" | "review" | "block" {
if (score >= 70) return "block";
if (score >= 40) return "review";
return "allow";
}
Cross-chain Tracing
Elliptic's advantage: tracks funds through bridges (Wormhole, Stargate, LayerZero):
// If funds came through a bridge, Elliptic tracks the origin chain
async function checkCrossChainExposure(
address: string,
inboundTxHash: string
): Promise<CrossChainRisk> {
const walletRisk = await elliptic.screenWallet(address, "ETH");
// exposures.indirect can show risk through bridge
const bridgeExposures = walletRisk.exposures.indirect.filter(
e => e.category === "bridge" && e.riskScore > 40
);
if (bridgeExposures.length > 0) {
// Request details for each bridge hop
for (const exp of bridgeExposures) {
const originRisk = await elliptic.screenWallet(exp.sourceAddress, exp.sourceAsset);
if (originRisk.riskBand === "high" || originRisk.riskBand === "very_high") {
return { hasHighRisk: true, originChain: exp.sourceBlockchain };
}
}
}
return { hasHighRisk: false };
}
Elliptic integration with cross-chain tracing and normalized risk scoring for dual-provider system — 1-2 weeks.







