In both integration patterns, you’ll have a Predicated Function on your smart contract - this is the function that requires a ‘Predicate Message’ Attestation.
The Predicate Function contains your protected business logic and ensures compliance before execution.You can see this commented in the Complete Integration Example
Complete Integration Example
Complete Integration Example
Copy
Ask AI
import {PredicateClient, PredicateRequest, packFunctionArgs, signaturesToBytes} from '@predicate/core';import { ethers } from 'ethers';const predicateClient = new PredicateClient({ apiUrl: 'https://api.predicate.io/', apiKey: process.env.PREDICATE_API_KEY!});const contractABI = [ "function sendCoin(address to, uint256 amount, tuple(string, uint256, address[], bytes[]) predicateMessage)"];const provider = new ethers.JsonRpcProvider(process.env.RPC);const wallet = new ethers.Wallet(process.env.PRIVATE_KEY || "", provider);const contract = new ethers.Contract("YOUR_CONTRACT_ADDRESS", contractABI, wallet);async function sendCompliantTransaction() { const functionArgs = [receiverAddress, amount]; const contractAddress = await contract.getAddress(); // Encode the private function that is invoked by the Predicate function const data = packFunctionArgs("_sendCoin(address,uint256)", functionArgs); const request: PredicateRequest = { from: wallet.address, to: contractAddress, data: data, msg_value: '0' }; const evaluationResult = await predicateClient.evaluatePolicy(request); if (!evaluationResult.is_compliant) { console.error("Transaction not compliant"); return; } const predicateMessage = signaturesToBytes(evaluationResult); const tx = await contract.sendCoin( functionArgs[0], functionArgs[1], [ predicateMessage.taskId, predicateMessage.expireByBlockNumber, predicateMessage.signerAddresses, predicateMessage.signatures ] ); const receipt = await tx.wait(); console.log("Transaction successful:", receipt);}