Direct Integration

Working with Contracts

Direct contract integration for real-time reads, writes, and authoritative data validation.

Contract Addresses (Base Mainnet)

RelationalResolver: 0xdaabbfc98a09f542f5f3f13694284ca96dd32934
IlluminationRegistry: 0x2aaca41ef9bb156ce3c302e696cff5e7e2b974bf
TokenLinkRegistry (V2): 0xE07869Fd7625e83bb3FBbEe32F9B9110d8a9b8dD
VisualizationAssembler: 0x6f22fd8df7c23fd4686baebef05c3d7665da5425
IlluminationAnalyzer: 0x4b2f2a03ed6744df981198fc3c231953179db699
EAS: 0x4200000000000000000000000000000000000021

Using the SDK Client

The easiest way to interact with contracts is through the RelationalClient. Note: The SDK defaults to Base Sepolia, so for Base Mainnet you must pass custom contract addresses:

import { JsonRpcProvider } from 'ethers';
import { createRelationalClient } from '@influence-protocol/sdk';

// For Base Mainnet, pass custom config
const provider = new JsonRpcProvider('https://mainnet.base.org');
const client = createRelationalClient(provider, {
  visualizationAssembler: '0x...', // Base Mainnet address (TBD)
  relationalResolver: '0xdaabbfc98a09f542f5f3f13694284ca96dd32934',
  illuminationAnalyzer: '0x4b2f2a03ed6744df981198fc3c231953179db699',
});

// Get participant graph
const graph = await client.getParticipantGraph('0x...');

// Get creator topology
const topology = await client.getCreatorTopology('0x...');

// Get attestation record
const attestation = await client.getAttestationRecord('0x...');

// Get influence metrics
const metrics = await client.getInfluencerMetrics('0x...');

Direct Contract Calls

For more control, interact with contracts directly using ethers:

import { Contract, JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://mainnet.base.org');

// RelationalResolver ABI (simplified)
const resolverAbi = [
  'function getAttestationRecord(bytes32 uid) view returns (...)',
  'function participantAttestations(address) view returns (bytes32[])',
  'function creatorTokenAttestations(address) view returns (bytes32[])',
];

const resolver = new Contract(
  '0xdaabbfc98a09f542f5f3f13694284ca96dd32934',
  resolverAbi,
  provider
);

// Get all attestations for a participant
const uids = await resolver.participantAttestations('0x...');

// Get attestation record
const record = await resolver.getAttestationRecord(uids[0]);

Reading Attestations

Query attestation data from RelationalResolver:

// Get all attestations for a participant
const participantUids = await client.getParticipantAttestations('0x...');

// Get all attestations for a creator token
const creatorUids = await client.getCreatorTokenAttestations('0x...');

// Get single attestation record
const record = await client.getAttestationRecord(participantUids[0]);

// Batch get multiple attestations
const records = await client.batchGetAttestations([
  participantUids[0],
  participantUids[1],
]);

// Get paginated summaries
const summaries = await client.getParticipantSummaries('0x...', {
  offset: 0,
  limit: 50,
});

Querying Relationships

Check relationships between participants and creators:

// Check if relationship exists
const hasRel = await client.hasRelationship(
  '0xParticipant...',
  '0xCreatorToken...'
);

// Get relationship total (total attestations)
const total = await client.relationshipTotal(
  '0xParticipant...',
  '0xCreatorToken...'
);

// Get all creator tokens for a participant
const tokens = await client.getParticipantCreatorTokens('0x...');

// Get all participants for a creator token
const participants = await client.getCreatorTokenParticipants('0x...');

Building Visualization Graphs

Use VisualizationAssembler to build graph structures:

// Get participant graph (nodes + edges)
const graph = await client.getParticipantGraph('0x...');
// Returns: { nodes: [...], edges: [...] }

// Get temporal journey (chronological nodes)
const journey = await client.getParticipantJourney('0x...');
// Returns: nodes in chronological order

// Get creator topology
const topology = await client.getCreatorTopology('0xCreatorToken...');
// Returns: { node: CreatorNode, participants: string[] }

// Build creator network (multiple creators)
const network = await client.getCreatorNetwork([
  '0xCreator1...',
  '0xCreator2...',
  '0xCreator3...',
]);
// Returns: edges connecting creators

Calculating Influence Metrics

Use IlluminationAnalyzer to get influence breakdown:

// Get influencer metrics
const metrics = await client.getInfluencerMetrics('0x...');

// Returns:
// {
//   breakdown: {
//     creatorPillar: bigint,      // Creator influence score
//     portfolioPillar: bigint,    // Portfolio diversity
//     networkPillar: bigint,      // Network connectivity
//     consistencyPillar: bigint,  // Temporal consistency
//   },
//   totalScore: bigint,
//   rank: bigint,
// }

console.log('Creator Pillar:', metrics.breakdown.creatorPillar);
console.log('Total Score:', metrics.totalScore);

Checking Token Link Registry

Query linked creator tokens:

import { Contract, JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://mainnet.base.org');

const registryAbi = [
  'function getLink(address token) view returns (address admin, bytes32 metadataHash, uint64 linkedAt, uint64 updatedAt, bool active)',
  'function isLinked(address token) view returns (bool)',
  'function getAdmin(address token) view returns (address)',
];

const registry = new Contract(
  '0xc882d94b4aec1c2aaff68a9dd9cb31d708f16a84',
  registryAbi,
  provider
);

// Check if token is linked
const isLinked = await registry.isLinked('0x...');

// Get link details
const link = await registry.getLink('0x...');
// Returns: { admin, metadataHash, linkedAt, updatedAt, active }

// Get admin address
const admin = await registry.getAdmin('0x...');

Writing Transactions

Use SDK writers to build transaction payloads:

import { Wallet } from 'ethers';
import { buildIlluminateTx, buildMintInfluenceTx } from '@influence-protocol/sdk';

const signer = new Wallet(process.env.PRIVATE_KEY!, provider);

// Build illumination transaction
const illumTx = buildIlluminateTx({
  registry: '0x2aaca41ef9bb156ce3c302e696cff5e7e2b974bf',
  attestationUid: '0x...',
  radiantAmount: 1n * 10n ** 18n,
});

// Send transaction
await signer.sendTransaction(illumTx);

// Build mint with attestation
const mintTx = buildMintInfluenceTx({
  tokenAddress: '0x...',
  to: '0x...',
  amount: 100n * 10n ** 18n,
  request: {
    attestor: '0x...',
    includeAttestation: true,
    captureContext: true,
    snapshotData: '0x',
    payload: {
      workId: '0x...',
      attestationUri: 'ipfs://...',
      lens: 'creator_mint',
      schemaId: '0x...',
      isPublic: true,
      fip2Target: '0x',
    },
  },
});

await signer.sendTransaction(mintTx);

Error Handling

Always handle contract errors gracefully:

try {
  const record = await client.getAttestationRecord('0x...');
} catch (error) {
  if (error.message.includes('AttestationNotFound')) {
    // Handle missing attestation
  } else if (error.message.includes('revert')) {
    // Handle contract revert
  } else {
    // Handle other errors
  }
}

Agent Notes

  • Contract calls are synchronous and return current on-chain state immediately.
  • Use batch methods (batchGetAttestations) when querying multiple records to save gas.
  • All amounts are in wei (18 decimals); convert to human-readable format for display.
  • Timestamps are Unix epoch seconds; convert to Date objects for display.
  • Addresses should be checksummed; use getAddress from ethers to normalize.
  • For read-only operations, use a provider; for writes, use a signer.