Running an Agentic Economic Flow on Arc with ERC-8183

Summary
ERC-8183 is an open standard for the agentic economy that defines how work is scoped, funds are escrowed, deliverables are submitted, and outcomes are resolved onchain. This post walks through how that flow works on Arc Testnet with USDC and Circle Wallets, from job creation and funding to payout or refund.
Agentic economic systems need a reliable way to define work, escrow payment, submit deliverables, and resolve outcomes based on whether that work was accepted.
That is the problem ERC-8183 is designed to address.
ERC-8183 is an open standard for the agentic economy, built around job definition, escrowed payment, deliverable submission, and evaluator attestation. A client creates a job, funds it once terms are set. A provider submits work, and an evaluator determines, according to contract logic, whether payment is released or refunded. Instead of every application inventing its own logic for job funding, submission, and outcome resolution, ERC-8183 provides a common flow developers can build around.
On Arc (currently in testnet), that model becomes especially practical. Developers can define jobs, escrow USDC, release payment, and process refunds in a stablecoin-native environment, then use Circle Wallets to drive the full lifecycle from inside an application.
At a high level, an ERC-8183 job follows a structured flow between a client, provider, and evaluator, with escrow managed onchain.
The diagram below shows how that flow works from job creation to payout or refund.

We’ll walk through each step of this flow in practice, using Circle Wallets and an ERC-8183 contract on Arc Testnet.
What ERC-8183 actually does
ERC-8183 focuses on a flow with structured job definition, escrowed funds, deliverable submission, and an evaluator-driven outcome.
A job moves through this lifecycle:
Open → Funded → Submitted → Completed / Rejected / Expired
In the current reference implementation, the core contract surface looks like this:
createJob(address provider, address evaluator, uint256 expiredAt, string description, address hook)setProvider(uint256 jobId, address provider_)setBudget(uint256 jobId, uint256 amount, bytes optParams)fund(uint256 jobId, bytes optParams)submit(uint256 jobId, bytes32 deliverable, bytes optParams)complete(uint256 jobId, bytes32 reason, bytes optParams)reject(uint256 jobId, bytes32 reason, bytes optParams)claimRefund(uint256 jobId)getJob(uint256 jobId)
That is the heart of the protocol. Discovery, pricing, evaluation logic, and reputation systems can all be layered around that common flow.
Starting the flow with Circle Wallets
Let’s walk through a minimal end-to-end flow.
Imagine a client wants an AI agent to review a market brief on stablecoin adoption in Asia. They already know which provider they want to work with, and for a first implementation, they are comfortable acting as evaluator too.
We start by creating wallets for each participant with Circle Wallets:
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";
const circleClient = initiateDeveloperControlledWalletsClient({
apiKey: process.env.CIRCLE_API_KEY!,
entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
});
const walletSet = await circleClient.createWalletSet({
name: "ERC8183 Wallets",
});
const walletsResponse = await circleClient.createWallets({
blockchains: ["ARC-TESTNET"],
count: 3,
walletSetId: walletSet.data?.walletSet?.id ?? "",
accountType: "SCA",
});
const [clientWallet, providerWallet, evaluatorWallet] =
walletsResponse.data?.wallets ?? [];
Before the job flow begins, developers need an ERC-8183 contract instance. You can deploy your own or use the existing deployment on Arc Testnet.
CIRCLE_API_KEY=YOUR_API_KEY
CIRCLE_ENTITY_SECRET=YOUR_ENTITY_SECRET
ERC_8183=0x0747EEf0706327138c69792bF28Cd525089e4583
USDC=0x3600000000000000000000000000000000000000
Defining the job
The client begins by defining the job. This is where the provider, evaluator, expiry, and description become explicit onchain.
const createJobTx = await circleClient.createContractExecutionTransaction({
walletAddress: clientWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.ERC_8183!,
abiFunctionSignature: "createJob(address,address,uint256,string,address)",
abiParameters: [
providerWallet.address,
evaluatorWallet.address,
`${Math.floor(Date.now() / 1000) + 3600}`,
"Review a market brief on stablecoin payments in Asia.",
"0x0000000000000000000000000000000000000000",
],
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
At this point, the relationship exists, but funds have not moved yet.
That separation matters. Defining work and locking funds do not have to happen in the same transaction, which allows negotiation, pricing, and validation to happen before capital is committed.
Setting the budget
Once the job exists, the provider sets a budget:
const setBudgetTx = await circleClient.createContractExecutionTransaction({
walletAddress: providerWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.ERC_8183!,
abiFunctionSignature: "setBudget(uint256,uint256,bytes)",
abiParameters: ["1", "5000000", "0x"], // 5 USDC
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
This allows pricing to be set explicitly before funds move into escrow.
Funding the job
Once the budget is set, the client approves the contract to spend USDC and funds the job into escrow.
const approveTx = await circleClient.createContractExecutionTransaction({
walletAddress: clientWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.USDC!,
abiFunctionSignature: "approve(address,uint256)",
abiParameters: [
process.env.ERC_8183!,
"5000000",
],
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
const fundTx = await circleClient.createContractExecutionTransaction({
walletAddress: clientWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.ERC_8183!,
abiFunctionSignature: "fund(uint256,bytes)",
abiParameters: ["1", "0x"],
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
After fund(), the job enters the Funded state. The contract is now holding escrowed value until an outcome is determined.
Submitting work
Once the provider completes the work, they submit a deliverable:
const submitTx = await circleClient.createContractExecutionTransaction({
walletAddress: providerWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.ERC_8183!,
abiFunctionSignature: "submit(uint256,bytes32,bytes)",
abiParameters: [
"1",
"0x56f2c5a6adee8c37f3d40bd77c97a5e2395569d45ed60f9cb8a2f9a1ef39ecb1",
"0x",
],
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
ERC-8183 represents the deliverable as a bytes32 commitment rather than storing the full output onchain.
In practice, this is usually a hash pointing to offchain data such as an IPFS file, a signed artifact, or another evaluation output. That keeps the economic flow onchain without forcing the full payload onchain too.
Resolving the outcome
Once work is submitted, the evaluator decides whether the provider should be paid. If the work is accepted, they call `complete()` and attach a reason hash.
const completeTx = await circleClient.createContractExecutionTransaction({
walletAddress: evaluatorWallet.address!,
blockchain: "ARC-TESTNET",
contractAddress: process.env.ERC_8183!,
abiFunctionSignature: "complete(uint256,bytes32,bytes)",
abiParameters: [
"1",
"0x8cb041751f669292ed4ab602ac4c8f9fcba9cc493e46ffca2c482e45b65ce532",
"0x",
],
fee: {
type: "level",
config: { feeLevel: "MEDIUM" },
},
});
That reason hash can represent an attestation or structured evaluation explaining why the work was accepted.
If the work is rejected, the evaluator can call reject() instead.
And if a funded or submitted job passes expiredAt without resolution, claimRefund(jobId) gives the protocol a timeout-based refund path.
At that point, ERC-8183 has done what it was designed to do: resolve escrow based on an evaluation outcome.
Why this matters on Arc
This model works if the settlement layer is predictable.
On Arc, ERC-8183 flows can be priced, escrowed, paid out, and refunded in stablecoins. There is no need to introduce volatility or separate settlement rails.
Combined with Circle Wallets, developers can move from job definition to payment resolution entirely within their application backend.
The stack becomes straightforward:
- ERC-8183 gives you the job escrow and evaluator flow
- Arc provides a stablecoin-native settlement environment
- Circle Wallets provide the execution path
For developers building in the agentic economy, that combination is practical. You can define work, lock funds, submit outcomes, and resolve payment using stablecoins from end to end.
Where ERC-8004 fits in
ERC-8183 solves the transaction flow. It answers a specific question: how should an agent get paid only when work is accepted?
A related question comes right after that: once an agent is registered, how do others decide to trust it?
That is where ERC-8004 becomes useful.
If ERC-8183 structures the economic event itself, ERC-8004 helps developers reason about the agent before and after that event through identity, validation, and reputation. It provides a way to register agents and, over time, connect identity, validation, and reputation to real job outcomes.
In other words, ERC-8183 handles the flow of work and payment. ERC-8004 can help make those outcomes reusable in future trust decisions.
Together, they point toward a broader model for the agentic economy on Arc: structured settlement during the transaction, and reusable trust around it.
Get started on Arc
If you want to explore the ERC-8183 flow itself, start with the quickstart and walk through job creation, funding, submission, completion, rejection, and refund on Arc.
If you want to go one step further and think about how agents are registered and discovered, continue with the ERC-8004 quickstart.
Circle Technology Services, LLC (“CTS”) is a software provider and does not provide regulated financial or advisory services. You are solely responsible for services you provide to users, including obtaining any necessary licenses or approvals and otherwise complying with applicable laws. For additional details, please click here to see the Circle Developer terms of service.
USDC is issued by regulated affiliates of Circle. See Circle’s list of regulatory authorizations.
Circle Wallets are provided by Circle Technology Services, LLC (“CTS”). CTS is a software provider and does not provide regulated financial or advisory services. You are solely responsible for services you provide to users, including obtaining any necessary licenses or approvals and otherwise complying with applicable laws. For additional details, refer to the Circle Developer Terms of Service.
EURC is issued by regulated affiliates of Circle. See Circle’s list of regulatory authorizations.
Arc testnet is offered by Circle Technology Services, LLC (“CTS”). CTS is a software provider and does not provide regulated financial or advisory services. You are solely responsible for services you provide to users, including obtaining any necessary licenses or approvals and otherwise complying with applicable laws.
Arc has not been reviewed or approved by the New York State Department of Financial Services.
The product features described in these materials are for informational purposes only. All product features may be modified, delayed, or cancelled without prior notice, at any time and at the sole discretion of Circle Technology Services, LLC. Nothing herein constitutes a commitment, warranty, guarantee or investment advice.
