Code Examples

Working code examples and tutorials for Fairway integration

Cardano Integration

KYC-Gated Liquidity Pool

Build a liquidity pool that only accepts deposits from KYC-verified users

Aiken Validator

use aiken/list
use fairway/compliance.{verify_kyc, PolicyDatum}

validator kyc_gated_pool {
  fn spend(datum: PolicyDatum, _redeemer: Data, ctx: ScriptContext) {
    let tx = ctx.transaction
    let policy_id = datum.policy_id
    
    // Verify all inputs have valid KYC tokens
    list.all(tx.inputs, fn(input) {
      verify_kyc(policy_id, input.output.address)
    })
  }
  
  fn mint(_redeemer: Data, ctx: ScriptContext) {
    let tx = ctx.transaction
    // Only allow minting if depositor is KYC verified
    verify_kyc("institutional_kyc_v1", tx.inputs)
  }
}

TypeScript Integration

import { FairwayClient } from '@fairway/sdk'
import { Lucid, Blockfrost } from 'lucid-cardano'

const fairway = new FairwayClient({
  apiKey: process.env.FAIRWAY_API_KEY
})

const lucid = await Lucid.new(
  new Blockfrost("https://cardano-mainnet.blockfrost.io/api/v0", "your_key"),
  "Mainnet"
)

async function depositToPool(userAddress: string, amount: bigint) {
  // Check KYC eligibility first
  const eligibility = await fairway.checkEligibility(userAddress)
  
  if (!eligibility.eligible) {
    throw new Error(`User not eligible: ${eligibility.reason}`)
  }
  
  // Build transaction with KYC proof
  const tx = lucid.newTx()
    .payToContract(poolAddress, datum, { lovelace: amount })
    .attachMetadata(674, { kyc_proof: eligibility.proof })
  
  return await tx.complete()
}

EVM Integration

ERC-3643 + EAS Verifier

Implement compliance verification using ERC-3643 tokens and Ethereum Attestation Service

Solidity Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@fairway/contracts/PolicyEngine.sol";
import "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";

contract ComplianceDeFi {
    PolicyEngine public immutable policyEngine;
    IEAS public immutable eas;
    bytes32 public immutable kycSchemaUID;
    
    constructor(
        address _policyEngine,
        address _eas,
        bytes32 _kycSchemaUID
    ) {
        policyEngine = PolicyEngine(_policyEngine);
        eas = IEAS(_eas);
        kycSchemaUID = _kycSchemaUID;
    }
    
    modifier onlyCompliant(address user) {
        require(
            policyEngine.isEligible(user, "institutional_kyc"),
            "User not compliant"
        );
        _;
    }
    
    function stake(uint256 amount) external onlyCompliant(msg.sender) {
        // Verify EAS attestation
        bytes32 attestationUID = policyEngine.getAttestationUID(msg.sender);
        Attestation memory attestation = eas.getAttestation(attestationUID);
        
        require(attestation.schema == kycSchemaUID, "Invalid KYC schema");
        require(attestation.expirationTime > block.timestamp, "KYC expired");
        
        // Proceed with staking logic
        _stake(msg.sender, amount);
    }
}

Frontend Integration

import { FairwayClient } from '@fairway/sdk'
import { ethers } from 'ethers'

// Note: API key should be handled server-side for security
// This example shows client-side usage for demonstration only
const fairway = new FairwayClient({
  apiKey: 'your_api_key_here', // Use server-side API for production
  network: 'ethereum'
})

async function checkComplianceAndStake(userAddress: string, amount: string) {
  try {
    // In production, make this call from your backend API
    // Example: const eligibility = await fetch('/api/check-eligibility', { ... })
    const eligibility = await fairway.checkEligibility(userAddress)
    
    if (!eligibility.eligible) {
      throw new Error(`Compliance check failed: ${eligibility.reason}`)
    }
    
    // Connect to contract
    const contract = new ethers.Contract(
      contractAddress,
      contractABI,
      signer
    )
    
    // Execute stake with compliance verification
    const tx = await contract.stake(ethers.parseEther(amount))
    await tx.wait()
    
    return { success: true, txHash: tx.hash }
  } catch (error) {
    return { success: false, error: error.message }
  }
}

Secure Server-Side Implementation

// pages/api/check-eligibility.ts (Next.js API route)
import { FairwayClient } from '@fairway/sdk'

const fairway = new FairwayClient({
  apiKey: process.env.FAIRWAY_API_KEY, // Server-side only
  network: 'ethereum'
})

export default async function handler(req, res) {
  const { userAddress } = req.body
  
  try {
    const eligibility = await fairway.checkEligibility(userAddress)
    res.status(200).json(eligibility)
  } catch (error) {
    res.status(500).json({ error: 'Compliance check failed' })
  }
}

// Frontend usage
async function checkCompliance(userAddress: string) {
  const response = await fetch('/api/check-eligibility', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userAddress })
  })
  return response.json()
}

Real World Assets (RWA)

Cross-Chain RWA Wrapper

Tokenize real-world assets with compliance across Cardano and EVM chains

Multi-Chain Architecture

// Cardano side (Aiken)
validator rwa_wrapper {
  fn mint(redeemer: MintRedeemer, ctx: ScriptContext) {
    let tx = ctx.transaction
    
    expect MintRedeemer { 
      kyc_proof, 
      asset_id, 
      jurisdiction 
    } = redeemer
    
    // Verify KYC for asset jurisdiction
    verify_kyc_jurisdiction(kyc_proof, jurisdiction) &&
    verify_asset_custody(asset_id, tx.mint)
  }
}

// Ethereum side (Solidity)
contract RWABridge {
    mapping(bytes32 => bool) public cardanoProofs;
    
    function mintFromCardano(
        bytes32 cardanoTxHash,
        uint256 amount,
        bytes calldata kycProof
    ) external {
        require(!cardanoProofs[cardanoTxHash], "Already processed");
        require(verifyKYCProof(msg.sender, kycProof), "Invalid KYC");
        
        cardanoProofs[cardanoTxHash] = true;
        _mint(msg.sender, amount);
    }
}

Testing & Development

Unit Testing with Mock Data

Test your compliance integration with mock KYC data

Jest Test Suite

import { FairwayClient } from '@fairway/sdk'

describe('Compliance Integration', () => {
  let fairway: FairwayClient
  
  beforeEach(() => {
    fairway = new FairwayClient({
      apiKey: 'test_key',
      network: 'testnet',
      mockMode: true
    })
  })
  
  test('should allow compliant user to stake', async () => {
    // Mock compliant user
    const mockUser = 'addr_test1compliant'
    fairway.setMockEligibility(mockUser, {
      eligible: true,
      reason: 'KYC1_OK',
      compliance_level: 'institutional'
    })
    
    const result = await fairway.checkEligibility(mockUser)
    expect(result.eligible).toBe(true)
  })
  
  test('should reject non-compliant user', async () => {
    const mockUser = 'addr_test1blocked'
    fairway.setMockEligibility(mockUser, {
      eligible: false,
      reason: 'SANCTIONS_HIT'
    })
    
    const result = await fairway.checkEligibility(mockUser)
    expect(result.eligible).toBe(false)
    expect(result.reason).toBe('SANCTIONS_HIT')
  })
})

Additional Resources

GitHub Repository with full examples
Testnet faucets for development
Developer Discord community
Video tutorials and workshops