No delivery means a refund path.
If the project deadline passes and the builder has not submitted any work, the client becomes eligible to recover the locked payment.
PayNode protects the client when work is not delivered and protects the builder when delivered work is ignored.
Clients lock the agreed payment in a smart contract. Builders submit their work through the platform. Clear deadlines, review periods, refunds, revisions, and settlement rules keep either side from holding complete control.
What PayNode solves
A builder may finish the work and never get paid. A client may fund a project and receive nothing. PayNode replaces open-ended trust with clear rules that both sides can understand before the project begins.
If the project deadline passes and the builder has not submitted any work, the client becomes eligible to recover the locked payment.
After delivery, the client has 7 days to respond. If no action is taken, the builder becomes eligible to claim the escrowed payment.
Balanced by design
The builder cannot receive payment without delivering the work, and the client cannot keep a completed delivery unpaid forever.
Before delivery
The builder must submit work before the agreed project deadline.
After delivery
The client must approve, request a revision, or raise a dispute within 7 days.
During revision
Revised work starts a fresh 7-day review period.
The core of PayNode
These four rules are the foundation of the contract and explain how PayNode protects both participants.
If the builder does not submit any work before the project deadline, the client becomes eligible to refund the locked payment from the smart contract.
Result: the client can recover the escrowed funds.
When the builder submits the work, a separate 7-day review period begins. During those 7 days, the client can approve, request a revision, or raise a dispute.
Result: if the client takes no action before the review period ends, the builder becomes eligible to claim the escrowed USDC directly from the smart contract.
A revision request closes the current review period. The payment remains securely locked while the builder works on the requested changes.
Result: no payment is released while the project is in revision.
After the builder submits the updated delivery, a new 7-day review period begins for the revised work.
Result: the client receives a fresh review window, while the builder is protected from an endless unpaid review cycle.
Two different clocks
The project deadline applies before delivery. The 7-day review period applies only after the builder submits work.
Project deadline
This is the agreed amount of time the builder has to submit the project. It can be 5 days, 10 days, or another duration selected for that project.
No delivery by this deadline → the client can refund.
7-day review period
Once work is submitted, the client receives exactly 7 days to approve it, request a revision, or raise a dispute.
No response within 7 days → the builder can claim.
One link for builders
It brings skills, completed projects, client ratings, social links, and wallet-based payments together in one shareable professional identity.
Share one profile on X, Discord, Telegram, LinkedIn, GitHub, or a personal website.
Receive project invitations through the same public link.
Accept USDC tips from people who want to support your work.
Build visible reputation through completed projects and ratings.

Product walkthrough
The user-facing process stays simple, while the contract applies the rules in the background.
The client defines the project, budget, project deadline, delivery expectations, and revision limit. The payment is priced in USDC.

The client funds the smart contract before work begins. The builder can see that the agreed payment is secured.

The builder submits delivery notes and links to the final work. This action begins the 7-day review period.

The client can approve the work, request a revision, or raise a dispute. If the client does nothing for 7 days, the builder becomes eligible to claim the payment.

Builder reputation
Every completed project and client rating can strengthen the builder's profile and help future clients make a more confident hiring decision.
High ratings and successful project history act as visible proof of reliability. Builders can keep sharing the same link as their reputation grows.

Dispute resolution
Raising a dispute moves the project to Disputed and suspends the review period. From there, funds leave escrow through one of three resolution paths, or, if nobody acts for 30 days, through a permissionless circuit breaker. The contract has no reachable state that holds funds indefinitely.
The client may call raiseDispute only while the project is Delivered. A stale dispute over undelivered work refunds the client in full, so allowing earlier disputes would let a client freeze a builder on day one and reclaim the escrow while work was still in progress.
From Funded, InRevision, or Delivered. This lets a builder put an unresponsive client in front of an adjudicator and be awarded partial payment for work performed. It cannot be abused, because every pre-delivery stale outcome favours the client.
| Resolution | Contract function | DisputeResolved.resolutionPath |
|---|---|---|
| Path C · Named arbitrator | resolveDispute | 0 |
| Path A · AI resolver | resolveDisputeWithAttestation | 1 |
| Path B · Mutual settlement | acceptSettlement | 2 |
| Stale-dispute breaker | forceResolveStaleDispute | 3 |
Every path settles through the same internal function. The builder's share is paid net of the protocol fee snapshotted when the project was funded, the remainder is refunded to the client with no fee, and any pending settlement offer is cleared. A project that settles reaches a terminal status and can never be disputed or resolved again.
Three ways out
Which paths are open is a property of the project, fixed before any dispute exists. Path A and Path C are mutually exclusive: every project has exactly one adjudicator. Path B is open on every project.
Contract path 2 · resolveDisputeWithAttestation
Gemini reads the brief, every deliverable on record, the verified on-chain timeline, and both parties' statements, then divides the escrow anywhere from 0% to 100% to the builder. The ruling is signed as an EIP-712 attestation and executed on-chain.
Contract path 3 · proposeSettlement / acceptSettlement
One party proposes a percentage split on-chain and the other accepts it. No arbitrator, no AI, no waiting period. The escrow pays out in the same transaction as the acceptance.
Contract path 1 · resolveDispute
A third-party wallet, designated by the client when the project is created, reads the case and rules: release to the builder, refund the client, or any split between the two.
proposeSettlement(projectId, builderBps) records an offer. A new proposal overwrites the previous one.withdrawSettlement(projectId) retracts it. Only the proposer can withdraw.acceptSettlement(projectId, builderBps) must be called by the counterparty and must restate the exact split. If the proposer changed the terms in the meantime, the acceptance reverts with SettlementMismatch instead of binding the accepter to terms they never saw.builderCancel at any funded stage to return 100% to the client, so builders should check the arbitrator before starting work.Path A · Gemini engine
Disputes on the default path are adjudicated by Google Gemini (gemini-3.5-flash) against a frozen, versioned rubric, with a JSON-Schema-constrained response. The resolver never moves funds itself: it produces a signed ruling that the contract verifies and executes.
A party calls POST /api/dispute/request-resolution with their SIWE session. The route admits only the project's client or builder, and enforces the evidence window. Operators and cron jobs use POST /api/dispute/resolve, authenticated with a server-side secret that never reaches a browser.
Before any model call, the resolver reads the contract: the project must exist, be Disputed, have no designated arbitrator, and have a non-zero key for its resolver epoch that matches the key this service signs with. Eligibility is never decided from the database.
A pending row is inserted into the ruling ledger, keyed uniquely on the on-chain project id. Of two concurrent requests, exactly one wins the insert. The loser, and every later request, is served the winner's result.
Verified on-chain facts, the agreed scope, the builder's submissions, and each party's statements are rendered in a fixed order inside fenced sections. The client's section always comes first, regardless of who raised the dispute.
Gemini evaluates the case under a frozen rubric supplied as the system instruction, and returns a schema-constrained JSON ruling.
builderBps is re-checked to be an integer in 0–10,000. Out-of-range values are rejected, never clamped. The ruling is signed as an EIP-712 attestation and checked against the contract's own digest before it is stored.
The ruling, reasoning, full evidence analysis, signature, model version, and token usage are written to the ledger. Both parties are notified, and either of them (or anyone else) submits the attestation on-chain.
The resolver rules on the balance of probabilities, against the agreed scope, weighing in order:
Splits are rounded to the nearest 250 bps (2.5%) unless the evidence justifies a specific figure. A party who files no statement does not automatically lose.
{
"evidenceAnalysis": [
{
"source": "agreed_scope" | "verified_facts" | "builder_submissions"
| "client_statement" | "builder_statement",
"finding": string,
"weighsToward": "client" | "builder" | "neither",
"weight": "decisive" | "strong" | "moderate" | "slight"
}
],
"reasoning": string, // 4–8 sentences, shown to both parties
"manipulationDetected": boolean,
"confidence": "low" | "medium" | "high",
"builderBps": integer // 0–10000, emitted last
}The output shape is fully deterministic: the schema constrains every field. The verdict itself is pinned as far as the provider allows (temperature 0, fixed seed, fixed evidence order), but identical inputs can still diverge occasionally across a serving fleet. The guarantee PayNode relies on is structural instead: one ruling per project, ever. Run-to-run variance cannot be exploited when no party can request a second run. The builderBps field is emitted last so the split is a conclusion drawn from the analysis above it, not a number the reasoning is written to justify.
| Outcome | Meaning |
|---|---|
| signed | Attestation issued and stored. Every later request replays this exact signature. |
| pending | Another request is mid-arbitration. The caller receives HTTP 202 and polls. |
| failed | The model refused to rule (safety block or refusal finish reason). Terminal for Path A. Path B and the 30-day breaker remain open. |
| ineligible | A preflight gate refused: not disputed, arbitrator assigned, resolver disabled, or epoch mismatch. Not persisted, so the project's ruling slot is not consumed. |
| transient error | RPC failure, rate limit, or a ruling truncated at the output budget. The claim is released and the request can be retried. |
Cryptographic flow
A ruling becomes enforceable only as an EIP-712 structured signature from the resolver key that governs the project's epoch. The contract verifies that signature itself. It does not trust the API, the database, or the party who submits it.
domain: {
name: "PayNodeEscrow",
version: "2",
chainId, // Arc network chain id
verifyingContract // PayNodeEscrowV2 address
}
Resolution(
uint256 projectId, // on-chain project id
uint16 builderBps, // 0–10000
uint256 deadline // unix seconds; signing time + 7 days
)function resolveDisputeWithAttestation(
uint256 projectId,
uint16 builderBps,
uint256 deadline,
bytes calldata signature
) external;
// Helper views
resolutionDigest(projectId, builderBps, deadline) → bytes32
resolverFor(projectId) → address // key for the project's epochbuilderBps is re-validated as an integer in 0–10,000. Out-of-range values are rejected, never clamped.resolutionDigest. This catches a wrong chain id or contract address before a party is handed an attestation that would revert.ArbitratorAssignedblock.timestamp is not past the deadline → AttestationExpiredbuilderBps is at most 10,000 → BpsTooHighDisputed → BadStateResolverDisabledresolverAt[p.resolverEpoch] → BadAttestationSettlement moves the project to a terminal status that can never return to Disputed, so a project can be resolved at most once. No nonce is needed.
The attestation can be relayed by any address, so neither party needs the resolver to hold gas. The resolver key never transacts and holds no balance.
The signed deadline gives a ruling 7 days to be submitted. An expired ruling is not re-issued. The dispute continues through Path B or the 30-day breaker.
Security model
Both parties write text that the model reads, and both have a financial incentive to influence the ruling. The resolver assumes every statement may contain an attack and is designed so that none can change who wins.
Timelocks, lifecycles & fallback breakers
Several of these are 7 days long but control different things. Durations marked on-chain are bytecode constants that no owner can change.
On-chain · REVIEW_PERIOD
Starts at each delivery. If the client does not approve, request a revision, or dispute before it ends, the builder can claim the escrow.
On-chain · REVISION_GRACE
Each revision request extends the delivery deadline to at least 7 days from now, so asking for more work always grants time to do it.
Off-chain · resolver API
Minimum time after a dispute is raised before an AI ruling can be requested, unless both parties have already filed a statement.
Signed deadline field
A signed ruling must be submitted before its deadline or the contract rejects it with AttestationExpired.
On-chain · RESOLVER_TIMELOCK
Mandatory public notice between announcing and applying a resolver signing-key rotation.
On-chain · DISPUTE_TIMEOUT
After this, anyone can settle the dispute with forceResolveStaleDispute on the contract's fixed terms.
The AI resolver's signing key is versioned by resolverEpoch. Rotating it is a two-step, publicly announced process, and a rotation never reaches back into escrow that is already locked.
initiateResolverUpdate(newSigner)
→ emits ResolverUpdateInitiated(newSigner, eta) // eta = now + 7 days
→ calling again replaces the pending key and restarts the clock
→ cancelResolverUpdate() abandons it
applyResolverUpdate() // reverts ResolverTimelockActive before eta
→ resolverEpoch += 1
→ resolverAt[resolverEpoch] = newSigner
→ emits ResolverUpdated(newEpoch, oldSigner, newSigner)
fundProject(projectId)
→ p.resolverEpoch = resolverEpoch // snapshotted at fundingA client whose project is mid-dispute cannot unilaterally exit during a 7-day notice window, so the notice alone would not protect them. Pinning each project to the key that was live when the client funded it means already-locked escrow is always settled by the key the client agreed to.
Rotating to the zero address retires the AI resolver for projects funded afterwards. A project whose epoch has no key simply has Path A closed; Path B and the 30-day breaker are unaffected. Check a specific project with resolverFor(projectId).
forceResolveStaleDispute(projectId) needs no arbitrator, no resolver key, no owner, and no cooperation from either party. Once 30 days have passed since the dispute was raised, any address, including a keeper bot, can call it. Read the unlock time with staleResolvableAt(projectId).
Work was delivered
If the project was Deliveredwhen the dispute was raised, the builder receives 5,000 bps (net of the project's fee) and the client is refunded the rest.
No work on record
If the dispute was raised from Funded or InRevision, the whole escrow returns to the client.
“Delivered” means the on-chain status captured by raiseDispute (preDispute), which is set only by markDelivered. Deliverable records in the database do not affect this outcome. Pausing the contract does not block the breaker: a pause affects only new projects and new funding.
Claim Center
Deliverables and dispute statements are evidence, not state. Only contract calls move a project. The evidence record is append-only, so what the resolver reads is exactly what each party put on the record, when they put it there.
The builder submits a title, a description, and up to 10 artifact links. The row is written before the on-chain transaction, so the chain can never say Delivered with nothing behind it.
The builder calls markDelivered, which starts the 7-day review period. It reverts once the delivery deadline has passed. Retrying after a rejected wallet prompt reuses the recorded row instead of creating a duplicate.
A client revision request increments revisionsUsed on-chain. The builder's next submission is recorded with revision_index equal to that on-chain counter, so the database cannot disagree with the contract's timeline.
Every submission, in every revision round, appears in the resolver's case file in chronological order. Earlier rounds are never replaced.
After a dispute is raised, both parties file statements in the Claim Center, each up to 20,000 characters with up to 10 supporting links. An AI ruling can be requested once both parties have filed or 72 hours have passed since the dispute was raised, whichever comes first. Until then, a request returns too_early with the remaining time.
The window is measured against block time, the same clock the contract uses, and is enforced by the server rather than the browser. It is a minimum wait, not a cutoff: parties can keep filing until a ruling is issued.
created_at, so nothing can be backdated.Security rules
The most important protections are visible and predictable. Users do not need to understand contract code to understand their rights.
The builder cannot receive the project payment before submitting work.
The client cannot keep a completed delivery unpaid forever.
The client can refund after the project deadline if no delivery exists.
The payment remains locked while a revision is active.
Every revised delivery starts a new 7-day review period.
Project payments, refunds, settlements, and tips use USDC only.
Every dispute ends: after 30 days, anyone can trigger the contract's fixed settlement.
The platform owner cannot resolve disputes, move escrowed funds, or change a funded project's resolver.
Review every wallet request before signing and use only the official PayNode application.
Built on Arc Network
PayNode uses Arc Network to turn deadlines, review periods, revisions, refunds, and settlement into transparent smart contract rules instead of private platform decisions.
Questions
The essential rules to understand before starting a project.
The project deadline is the time the builder has to submit the initial delivery. The 7-day review period starts only after a delivery is submitted and gives the client time to approve, request a revision, or raise a dispute.
If no delivery has been submitted before the project deadline, the client becomes eligible to refund the locked payment from the smart contract.
The client has 7 days to respond. After that review period expires, the builder becomes eligible to claim the escrowed USDC directly from the smart contract.
The current review period closes and the payment remains locked. When the builder submits the revised work, a new 7-day review period begins.
No. The escrow rules require a delivery before the normal approval or review-expiry settlement path can be used.
No. The 7-day review period prevents an inactive client from holding the builder's payment indefinitely.
It is fixed before the dispute exists. If the client named an arbitrator when creating the project, that wallet decides. Otherwise the autonomous AI resolver decides, provided a resolver key was active when the project was funded. In every case, both parties can settle directly by mutual agreement at any time.
No. Each project receives exactly one ruling. Requesting again returns the same signed ruling, and the contract accepts it only once. If you both prefer a different outcome, you can still agree a split through mutual settlement before the ruling is executed on-chain.
A refusal is final for the AI path, and an unsubmitted ruling expires 7 days after it is signed. Either way, the dispute stays open to mutual settlement, and after 30 days anyone can trigger the contract's fixed outcome: 50/50 if the work had been delivered, or a full refund to the client if it had not.
No. The platform owner has no dispute or fund-moving powers in the contract. The owner can rotate the AI resolver's signing key only after a public 7-day timelock, and a rotation applies only to projects funded after it takes effect.
PayNode uses USDC for project escrow, settlement, refunds, and tips. Native network tokens and other ERC-20 tokens are not supported for these payments.
The public GitHub repository contains the contract code, application architecture, implementation details, and development history.
Build your reputation, receive tips, start protected projects, and get paid through a balanced escrow workflow.