### Quick Start: Propose, Accept, and Execute Coordination Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Demonstrates the core workflow of the CoordinationClient: proposing a coordination intent, having participants accept it, and finally executing the coordinated action. It requires setting up viem clients and providing contract addresses. ```typescript import { CoordinationClient, BoundedClient } from '@erc8001/sdk'; import { createPublicClient, createWalletClient, http } from 'viem'; import { baseSepolia } from 'viem/chains'; import { privateKeyToAccount } from 'viem/accounts'; // Setup clients const account = privateKeyToAccount('0x...'); const publicClient = createPublicClient({ chain: baseSepolia, transport: http() }); const walletClient = createWalletClient({ account, chain: baseSepolia, transport: http() }); // Create coordination client const coordination = new CoordinationClient({ contractAddress: '0x...', // Your deployed AgentCoordination contract publicClient, walletClient, }); // Propose a coordination const { intentHash, payload } = await coordination.propose({ agentId: account.address, participants: ['0xAlice...', '0xBob...'], coordinationType: 'TRADE_V1', payload: { version: '0x' + '01'.padStart(64, '0'), coordinationType: '0x...', coordinationData: '0x...', conditionsHash: '0x' + '0'.repeat(64), metadata: '0x', }, }); console.log('Proposed:', intentHash); // Accept as a participant const { txHash } = await coordination.accept(intentHash); console.log('Accepted:', txHash); // Wait for all participants to accept const status = await coordination.waitForReady(intentHash); console.log('Ready for execution!'); // Execute const { txHash: execTx } = await coordination.execute(intentHash, payload); console.log('Executed:', execTx); ``` -------------------------------- ### Install @erc8001/sdk and viem Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Installs the necessary packages for using the ERC-8001 SDK and interacting with the Ethereum blockchain via viem. ```bash npm install @erc8001/sdk viem ``` -------------------------------- ### Interact with ERC-8001 Contracts using ABIs (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Demonstrates how to import and use raw ABI definitions (AGENT_COORDINATION_ABI, BOUNDED_EXECUTION_ABI) from the ERC-8001 SDK with viem for direct contract interaction. This includes creating contract instances, performing read and write operations, and setting up event watchers. Requires viem and the ERC-8001 SDK packages. ```typescript import { AGENT_COORDINATION_ABI, BOUNDED_EXECUTION_ABI } from '@erc8001/sdk'; import { getContract } from 'viem'; // Create contract instance with full ABI const agentCoordination = getContract({ address: '0x1234567890123456789012345678901234567890', abi: AGENT_COORDINATION_ABI, client: { public: publicClient, wallet: walletClient }, }); // Direct read calls const nonce = await agentCoordination.read.getAgentNonce(['0xAgent...']); const domainSeparator = await agentCoordination.read.DOMAIN_SEPARATOR(); // Direct write calls const hash = await agentCoordination.write.cancelCoordination([ '0xintentHash...', 'Cancelled by user', ]); // Bounded execution contract const boundedExecution = getContract({ address: '0x9876543210987654321098765432109876543210', abi: BOUNDED_EXECUTION_ABI, client: { public: publicClient, wallet: walletClient }, }); // Watch for events const unwatch = agentCoordination.watchEvent.CoordinationProposed({ onLogs: (logs) => { for (const log of logs) { console.log('New coordination:', log.args.intentHash); console.log('Proposer:', log.args.proposer); console.log('Type:', log.args.coordinationType); } }, }); ``` -------------------------------- ### ERC-8001 CoordinationClient: Propose, Accept, Execute, Cancel Intents Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Demonstrates the full lifecycle management of coordination intents using the CoordinationClient. This includes proposing a new intent, having participants accept it, executing the coordinated action, and canceling if necessary. Requires viem clients and an ERC-8001 contract address. ```typescript import { CoordinationClient } from '@erc8001/sdk'; import { createPublicClient, createWalletClient, http } from 'viem'; import { baseSepolia } from 'viem/chains'; import { privateKeyToAccount } from 'viem/accounts'; // Setup viem clients const account = privateKeyToAccount('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'); const publicClient = createPublicClient({ chain: baseSepolia, transport: http() }); const walletClient = createWalletClient({ account, chain: baseSepolia, transport: http() }); // Create coordination client const coordination = new CoordinationClient({ contractAddress: '0x1234567890123456789012345678901234567890', publicClient, walletClient, }); // Propose a new coordination const { intentHash, txHash, payload } = await coordination.propose({ agentId: account.address, participants: ['0xAlice1234567890123456789012345678901234', '0xBob12345678901234567890123456789012345'], coordinationType: 'TRADE_V1', coordinationValue: 0n, ttlSeconds: 3600, // 1 hour payload: { version: '0x' + '01'.padStart(64, '0'), coordinationType: '0x' + 'TRADE_V1'.padStart(64, '0'), coordinationData: '0x1234', conditionsHash: '0x' + '0'.repeat(64), metadata: '0x', }, }); console.log('Proposed coordination:', intentHash); // Accept as a participant const { txHash: acceptTx } = await coordination.accept(intentHash, { ttlSeconds: 3600, }); console.log('Accepted:', acceptTx); // Wait for all participants to accept const status = await coordination.waitForReady(intentHash, { pollIntervalMs: 2000, timeoutMs: 60000, }); console.log('All participants accepted, status:', status.status); // Execute the coordination const { txHash: execTx } = await coordination.execute(intentHash, payload); console.log('Executed:', execTx); // Or cancel if needed const { txHash: cancelTx } = await coordination.cancel(intentHash, 'Changed plans'); console.log('Cancelled:', cancelTx); ``` -------------------------------- ### Generate Merkle Roots and Proofs for Bounded Execution (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Computes Merkle leaves, roots, and proofs for actions within a bounded execution system. Requires the '@erc8001/sdk' package. Outputs are logged to the console, and proofs can be used to verify action inclusion. ```typescript import { computeActionLeaf, computeBoundsRoot, generateProof } from '@erc8001/sdk'; // Define allowed actions const actions = [ { target: '0xVault123456789012345678901234567890123456', selector: '0xa9059cbb' }, // transfer { target: '0xVault123456789012345678901234567890123456', selector: '0x095ea7b3' }, // approve { target: '0xSwap1234567890123456789012345678901234567', selector: '0x38ed1739' }, // swapExactTokensForTokens { target: '0xSwap1234567890123456789012345678901234567', selector: '0x7ff36ab5' }, // swapExactETHForTokens ]; // Compute individual action leaf const leaf = computeActionLeaf(actions[0]); console.log('Action leaf:', leaf); // keccak256(abi.encodePacked(target, selector)) // Compute Merkle root for all actions const boundsRoot = computeBoundsRoot(actions); console.log('Bounds root:', boundsRoot); // Generate proof for a specific action (index 2 = swapExactTokensForTokens) const proof = generateProof(actions, 2); console.log('Merkle proof:', proof); // Array of sibling hashes needed to verify inclusion // Use in bounded execution // const bounded = new BoundedClient({ contractAddress: '0x...', publicClient, walletClient }); // Verify bounds before execution // const isValid = await bounded.verifyBounds( // policyId, // '0xSwap1234567890123456789012345678901234567', // '0x38ed1739...', // callData starting with selector // 0n, // proof // ); // console.log('Action within bounds:', isValid); ``` -------------------------------- ### Retrieve Policy Details with BoundedClient (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Retrieves detailed policy information, including spending limits, current amount spent, time window, and remaining calls. This is useful for monitoring policy usage and validating actions before execution. Requires an initialized BoundedClient instance. ```typescript import { BoundedClient } from '@erc8001/sdk'; const bounded = new BoundedClient({ contractAddress: '0x9876543210987654321098765432109876543210', publicClient, }); const policyId = '0xpolicyid1234567890123456789012345678901234567890123456789012345678'; const policy = await bounded.getPolicy(policyId); console.log('Policy details:'); console.log(' Bounds root:', policy.boundsRoot); console.log(' Spending limit:', policy.spendingLimit); console.log(' Amount spent:', policy.spent); console.log(' Remaining:', policy.spendingLimit - policy.spent); console.log(' Window start:', new Date(Number(policy.windowStart) * 1000)); console.log(' Window end:', new Date(Number(policy.windowEnd) * 1000)); console.log(' Calls remaining:', policy.callsRemaining); console.log(' Active:', policy.active); // Check if policy is still valid const isValid = await bounded.isPolicyValid(policyId); console.log('Policy valid:', isValid); ``` -------------------------------- ### Bounded Execution: Register Policy and Execute Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Illustrates how to use the BoundedClient to enforce spending limits and policy constraints on agent actions. This involves registering a policy with specific conditions and then executing actions within those defined bounds. ```typescript import { BoundedClient } from '@erc8001/sdk'; import { parseEther, encodeFunctionData } from 'viem'; const bounded = new BoundedClient({ contractAddress: '0x...', // Your deployed BoundedExecution contract publicClient, walletClient, }); // Register a policy const { policyId } = await bounded.registerPolicy({ agent: '0xAgent...', actions: [ { target: '0xVault...', selector: '0xa9059cbb' }, // transfer { target: '0xVault...', selector: '0x095ea7b3' }, // approve ], spendingLimit: parseEther('10'), maxCalls: 100, durationSeconds: 86400, // 1 day }); // Execute within bounds const callData = encodeFunctionData({ abi: [...], functionName: 'transfer', args: [recipient, amount], }); const { success } = await bounded.execute(policyId, { target: '0xVault...', callData, value: parseEther('1'), }); ``` -------------------------------- ### Manage Agent Policies with BoundedClient (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Manages policy-enforced bounded agent execution by registering spending limits and action constraints. It allows executing actions within these bounds using Merkle proofs for verification. Requires an initialized BoundedClient instance and utility functions like parseEther and encodeFunctionData. ```typescript import { BoundedClient } from '@erc8001/sdk'; import { parseEther, encodeFunctionData } from 'viem'; const bounded = new BoundedClient({ contractAddress: '0x9876543210987654321098765432109876543210', publicClient, walletClient, }); // Register a policy with spending limits const { policyId, txHash, boundsRoot } = await bounded.registerPolicy({ agent: '0xAgent12345678901234567890123456789012345', actions: [ { target: '0xVault123456789012345678901234567890123456', selector: '0xa9059cbb' }, // transfer { target: '0xVault123456789012345678901234567890123456', selector: '0x095ea7b3' }, // approve { target: '0xSwap1234567890123456789012345678901234567', selector: '0x38ed1739' }, // swap ], spendingLimit: parseEther('10'), // Max 10 ETH total maxCalls: 100, // Max 100 calls durationSeconds: 86400, // Valid for 1 day }); console.log('Policy registered:', policyId); console.log('Bounds root:', boundsRoot); // Execute an action within policy bounds const callData = encodeFunctionData({ abi: [{ name: 'transfer', type: 'function', inputs: [{ name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' }], outputs: [{ name: '', type: 'bool' }] }], functionName: 'transfer', args: ['0xRecipient23456789012345678901234567890123', parseEther('1')], }); const { txHash: execTx, success } = await bounded.execute(policyId, { target: '0xVault123456789012345678901234567890123456', callData, value: 0n, }); console.log('Execution success:', success); // Check remaining budget const remaining = await bounded.getRemainingBudget(policyId); console.log('Remaining budget:', remaining); // Revoke policy when done const { txHash: revokeTx } = await bounded.revokePolicy(policyId); console.log('Policy revoked:', revokeTx); ``` -------------------------------- ### Create Agent Intents and Acceptance Attestations (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Provides builder functions to create AgentIntent and AcceptanceAttestation objects. It automatically handles participant canonicalization, nonce management, expiry calculation, and payload hashing. Requires the '@erc8001/sdk' package. ```typescript import { createIntent, createAttestation, validateIntent, validateAttestation } from '@erc8001/sdk'; // Create an intent with automatic handling of: // - Participant canonicalization (sorting) // - Ensuring agentId is in participants // - Payload hash computation // - Expiry calculation from TTL const currentNonce = 5n; // Fetch with getAgentNonce() const { intent, payload } = createIntent({ agentId: '0xProposer12345678901234567890123456789012', participants: ['0xBob...', '0xAlice...'], // Will be sorted automatically coordinationType: 'TRADE_V1', // String or hash coordinationValue: 1000000000000000000n, ttlSeconds: 7200, // 2 hours payload: { version: '0x' + '01'.padStart(64, '0'), coordinationType: '0x' + 'TRADE_V1'.padStart(64, '0'), coordinationData: '0x1234', conditionsHash: '0x' + '0'.repeat(64), metadata: '0x', }, }, currentNonce); console.log('Intent nonce:', intent.nonce); // currentNonce + 1 console.log('Intent expiry:', new Date(Number(intent.expiry) * 1000)); console.log('Participants (sorted):', intent.participants); // Validate intent before signing validateIntent(intent); // Throws if invalid // Create acceptance attestation const attestation = createAttestation({ intentHash: '0xintent...', participant: '0xAlice1234567890123456789012345678901234', conditionsHash: '0x' + '0'.repeat(64), // Optional conditions ttlSeconds: 3600, // 1 hour }); console.log('Attestation expiry:', new Date(Number(attestation.expiry) * 1000)); // Validate attestation (requires signature to be added first) // validateAttestation(signedAttestation, intent.participants); ``` -------------------------------- ### EIP-712 Signing Utilities (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Provides low-level functions for EIP-712 compliant signing, including creating domains, computing struct hashes for intents and acceptances, and signing operations. These are useful for custom signing workflows. ```typescript import { createDomain, signIntent, signAcceptance, computeIntentStructHash, computeAcceptanceStructHash, computePayloadHash, AGENT_INTENT_TYPEHASH, ACCEPTANCE_TYPEHASH, } from '@erc8001/sdk'; // Create EIP-712 domain const domain = createDomain( 84532n, // chainId (Base Sepolia) '0x1234567890123456789012345678901234567890' // contract address ); console.log('Domain:', domain); // { name: 'ERC-8001', version: '1', chainId: 84532n, verifyingContract: '0x...' } // Compute payload hash const payloadHash = computePayloadHash({ version: '0x' + '01'.padStart(64, '0'), coordinationType: '0x' + 'TRADE_V1'.padStart(64, '0'), coordinationData: '0x1234', conditionsHash: '0x' + '0'.repeat(64), timestamp: BigInt(Math.floor(Date.now() / 1000)), metadata: '0x', }); // Build intent const intent = { payloadHash, expiry: BigInt(Math.floor(Date.now() / 1000) + 3600), nonce: 1n, agentId: '0xProposer12345678901234567890123456789012', coordinationType: '0x' + 'TRADE_V1'.padStart(64, '0'), coordinationValue: 0n, participants: ['0xAlice...', '0xBob...', '0xProposer...'], }; // Compute intent struct hash (used in acceptances) const intentHash = computeIntentStructHash(intent); console.log('Intent hash:', intentHash); // Sign intent // const signature = await signIntent(walletClient, domain, intent); // console.log('Intent signature:', signature); // Create and sign acceptance attestation const unsignedAttestation = { intentHash, participant: '0xAlice1234567890123456789012345678901234', nonce: 0n, expiry: BigInt(Math.floor(Date.now() / 1000) + 3600), conditionsHash: '0x' + '0'.repeat(64), }; // const signedAttestation = await signAcceptance(walletClient, domain, unsignedAttestation); // console.log('Attestation with signature:', signedAttestation); ``` -------------------------------- ### BoundedClient API Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Client for managing and interacting with ERC-8001 bounded execution policies. ```APIDOC ## BoundedClient ### Description Provides methods for registering, executing within, revoking, and querying policies for bounded execution. ### Methods #### `registerPolicy(options)` - **Description**: Register a new policy for bounded execution. - **Parameters**: `options` (object) - Configuration for the new policy. #### `execute(policyId, action)` - **Description**: Execute a specific action within the bounds of a registered policy. - **Parameters**: - `policyId` (string) - The ID of the policy to execute within. - `action` (object) - The action to be executed. #### `revokePolicy(policyId)` - **Description**: Revoke an existing policy. - **Parameters**: `policyId` (string) - The ID of the policy to revoke. #### `getPolicy(policyId)` - **Description**: Retrieve details of a specific policy. - **Parameters**: `policyId` (string) - The ID of the policy to retrieve. #### `verifyBounds(...)` - **Description**: Check if a given action is allowed under the current bounds. - **Parameters**: `...` (arguments) - Parameters defining the action and context to verify. ``` -------------------------------- ### CoordinationClient API Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Client for managing and interacting with ERC-8001 coordinations. ```APIDOC ## CoordinationClient ### Description Provides methods to propose, accept, execute, cancel, and query the status of ERC-8001 coordinations. ### Methods #### `propose(options)` - **Description**: Propose a new coordination. - **Parameters**: `options` (object) - Configuration for the new coordination. #### `accept(intentHash)` - **Description**: Accept an existing coordination. - **Parameters**: `intentHash` (string) - The hash of the coordination intent to accept. #### `execute(intentHash, payload)` - **Description**: Execute a coordination that is ready to be executed. - **Parameters**: - `intentHash` (string) - The hash of the coordination intent to execute. - `payload` (object) - The data required for execution. #### `cancel(intentHash, reason)` - **Description**: Cancel a coordination. - **Parameters**: - `intentHash` (string) - The hash of the coordination intent to cancel. - `reason` (string) - The reason for cancellation. #### `getStatus(intentHash)` - **Description**: Get the current status of a coordination. - **Parameters**: `intentHash` (string) - The hash of the coordination intent to query. #### `getAgentNonce(agentId)` - **Description**: Get the current nonce for a given agent. - **Parameters**: `agentId` (string) - The ID of the agent. #### `waitForReady(intentHash)` - **Description**: Wait until a coordination is ready for execution (all acceptances received). - **Parameters**: `intentHash` (string) - The hash of the coordination intent to wait for. ``` -------------------------------- ### Utilities Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Helper functions for common ERC-8001 related tasks. ```APIDOC ## Utilities ### Description A collection of utility functions to assist with creating and managing ERC-8001 intents and attestations. ### Functions #### `canonicalizeParticipants(addresses)` - **Description**: Sorts a list of participant addresses in ascending order. - **Parameters**: `addresses` (array) - An array of address strings. - **Returns**: `array` - A new array with sorted addresses. #### `createIntent(options, nonce)` - **Description**: Builds an `AgentIntent` object. - **Parameters**: - `options` (object) - Options for creating the intent. - `nonce` (number) - The nonce for the intent. - **Returns**: `object` - The created `AgentIntent` object. #### `createAttestation(options)` - **Description**: Builds an `AcceptanceAttestation` object. - **Parameters**: `options` (object) - Options for creating the attestation. - **Returns**: `object` - The created `AcceptanceAttestation` object. #### `computeBoundsRoot(actions)` - **Description**: Computes the Merkle root for a list of actions. - **Parameters**: `actions` (array) - An array of actions. - **Returns**: `string` - The computed Merkle root. #### `generateProof(actions, index)` - **Description**: Generates a Merkle proof for a given action at a specific index. - **Parameters**: - `actions` (array) - The list of actions. - `index` (number) - The index of the action for which to generate the proof. - **Returns**: `object` - The generated Merkle proof. ``` -------------------------------- ### EIP-712 Signing Utilities Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Provides functions for creating EIP-712 domains, signing intents, signing acceptance attestations, and computing the hash of an intent structure. These are crucial for secure and verifiable agent coordination. ```typescript import { createDomain, signIntent, signAcceptance, computeIntentStructHash, } from '@erc8001/sdk'; // Create domain const domain = createDomain(84532n, '0xContract...'); // Sign intent const signature = await signIntent(walletClient, domain, intent); // Compute intent hash (for acceptances) const intentHash = computeIntentStructHash(intent); // Sign acceptance const attestation = await signAcceptance(walletClient, domain, { intentHash, participant: account.address, nonce: 0n, expiry: BigInt(Math.floor(Date.now() / 1000) + 3600), conditionsHash: '0x' + '0'.repeat(64), }); ``` -------------------------------- ### Contract Addresses Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Addresses for deployed ERC-8001 contracts on Base Sepolia. ```APIDOC ## Contract Addresses ### Base Sepolia (84532) | Contract Name | Address | |----------------------|---------| | AgentCoordination | `0x...` | | BoundedExecution | `0x...` | ``` -------------------------------- ### Build Intent with CoordinationClient (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Builds an intent and its payload without submitting to the blockchain. This is useful for multi-party signature collection workflows where intent data needs to be shared before on-chain submission. It requires an initialized CoordinationClient instance. ```typescript import { CoordinationClient } from '@erc8001/sdk'; const coordination = new CoordinationClient({ contractAddress: '0x1234567890123456789012345678901234567890', publicClient, walletClient, }); // Build intent without submitting const { intent, payload, intentHash } = await coordination.buildIntent({ agentId: '0xProposer12345678901234567890123456789012', participants: [ '0xAlice1234567890123456789012345678901234', '0xBob12345678901234567890123456789012345', ], coordinationType: 'SWAP_V1', coordinationValue: 1000000000000000000n, // 1 ETH ttlSeconds: 7200, // 2 hours payload: { version: '0x' + '01'.padStart(64, '0'), coordinationType: '0x' + 'SWAP_V1'.padStart(64, '0'), coordinationData: '0xswapdata', conditionsHash: '0x' + '0'.repeat(64), metadata: '0x', }, }); console.log('Intent hash:', intentHash); console.log('Intent expiry:', new Date(Number(intent.expiry) * 1000)); console.log('Participants (sorted):', intent.participants); // Sign separately for offline/multi-party workflows const signature = await coordination.signIntent(intent); console.log('Signature:', signature); ``` -------------------------------- ### Manage Coordination Types (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Allows for the creation and use of coordination types, which categorize multi-party actions like trades or swaps. It supports both predefined types from `CoordinationTypes` and custom types generated using `coordinationType()`. ```typescript import { coordinationType, CoordinationTypes } from '@erc8001/sdk'; // Use built-in coordination types console.log('TRADE:', CoordinationTypes.TRADE); console.log('SWAP:', CoordinationTypes.SWAP); console.log('PAYMENT:', CoordinationTypes.PAYMENT); console.log('GAME_ACTION:', CoordinationTypes.GAME_ACTION); console.log('DAO_PROPOSAL:', CoordinationTypes.DAO_PROPOSAL); // Create custom coordination type const customType = coordinationType('MY_APP.AUCTION_V1'); console.log('Custom type:', customType); // Output: keccak256("MY_APP.AUCTION_V1") // Use in intent creation // const { intentHash } = await coordination.propose({ // agentId: account.address, // participants: ['0xBidder1...', '0xBidder2...'], // coordinationType: customType, // or use string: 'MY_APP.AUCTION_V1' // payload: { /* ... */ }, // }); ``` -------------------------------- ### Coordination Types: Built-in and Custom Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Defines and utilizes coordination types, including built-in constants like TRADE, SWAP, and PAYMENT, as well as the ability to define custom coordination types using the `coordinationType` function. ```typescript import { CoordinationTypes, coordinationType } from '@erc8001/sdk'; // Built-in types CoordinationTypes.TRADE // keccak256("ERC8001.TRADE_V1") CoordinationTypes.SWAP // keccak256("ERC8001.SWAP_V1") CoordinationTypes.PAYMENT // keccak256("ERC8001.PAYMENT_V1") // Custom types const myType = coordinationType('MY_CUSTOM_COORD_V1'); ``` -------------------------------- ### ERC-8001 CoordinationClient.getStatus(): Retrieve Intent Status Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Fetches the current status of a coordination intent, including participant details, acceptance status, and expiry. It returns a `CoordinationStatus` object which contains an enum for the status (None, Proposed, Ready, Executed, Cancelled, Expired). ```typescript import { CoordinationClient, Status } from '@erc8001/sdk'; const coordination = new CoordinationClient({ contractAddress: '0x1234567890123456789012345678901234567890', publicClient, walletClient, }); const intentHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890'; const status = await coordination.getStatus(intentHash); console.log('Status:', Status[status.status]); // "Proposed", "Ready", etc. console.log('Proposer:', status.proposer); console.log('Participants:', status.participants); console.log('Accepted by:', status.acceptedBy); console.log('Expiry:', new Date(Number(status.expiry) * 1000)); // Check if ready for execution if (status.status === Status.Ready) { console.log('Ready to execute!'); } ``` -------------------------------- ### Canonicalize and Validate Participants (TypeScript) Source: https://context7.com/kbryan/erc8001-sdk/llms.txt Sorts and deduplicates participant addresses according to ERC-8001 specifications for deterministic intent hashing. It also includes a utility to validate if a list of participants is already in canonical form. ```typescript import { canonicalizeParticipants, isCanonical } from '@erc8001/sdk'; const participants = [ '0xBob12345678901234567890123456789012345', '0xAlice1234567890123456789012345678901234', '0xCharlie234567890123456789012345678901234', '0xAlice1234567890123456789012345678901234', // duplicate ]; // Sort and deduplicate const sorted = canonicalizeParticipants(participants); console.log('Canonical participants:', sorted); // Output: ['0xAlice...', '0xBob...', '0xCharlie...'] (sorted by uint160) // Validate canonical order console.log('Is canonical:', isCanonical(sorted)); // true console.log('Is canonical (unsorted):', isCanonical(participants)); // false ``` -------------------------------- ### Participant Canonicalization Source: https://github.com/kbryan/erc8001-sdk/blob/main/README.md Sorts a list of participant addresses in ascending order, which is a requirement for certain operations within the ERC-8001 framework. This ensures consistent ordering for participants. ```typescript import { canonicalizeParticipants } from '@erc8001/sdk'; const sorted = canonicalizeParticipants(['0xBob...', '0xAlice...']); // Returns ['0xAlice...', '0xBob...'] (sorted by uint160) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.