Skip to content

fix(wallet): hireErc8183Agent throws a false "job is not ours" error when opts.noWait is set - #42

Merged
dhernz merged 4 commits into
altananetwork:stagingfrom
web3xDev:fix/erc8183-nowait-race
Aug 18, 2026
Merged

fix(wallet): hireErc8183Agent throws a false "job is not ours" error when opts.noWait is set#42
dhernz merged 4 commits into
altananetwork:stagingfrom
web3xDev:fix/erc8183-nowait-race

Conversation

@web3xDev

Copy link
Copy Markdown
Contributor

Bug

hireErc8183Agent's post-funding check reads getErc8183Job immediately after execute() returns to confirm that the predicted jobId actually belongs to the caller.

With opts.noWait: true, execute() returns { status: "PENDING" } as soon as the relay accepts the intent, before the batch is mined. The post-check didn't account for this: it read the pre-inclusion chain state and threw "job is not ours after funding" on every noWait call, even when the funding would succeed a few seconds later.

No test or e2e script in the repo covered hireErc8183Agent with noWait: true.

If a caller retries on that error, it re-runs the entire hire batch and escrows $U a second time for a job that was already successfully funded.

Fix

Only run the post-check when execute() reports CONFIRMED. The default waiting behavior is unchanged. Also updated the docstring, which claimed the function "returns once the job is FUNDED on-chain" — that is no longer true for the noWait path.

Testing

Added 3 tests covering the noWait: true and default paths. The noWait test verifies that the post-check is skipped; the default-path tests verify that a real mismatch still throws and a matching job still succeeds.

The tests were added to sessionKeyRegistration.test.ts instead of a new file because bun shares one module registry across test files. A second mock.module("./internal/relay.js") registration in a separate file leaked into client.balances.test.ts when I tried that approach.

bun test: 74 pass, 0 fail.
bun run typecheck: clean.
bun run build: clean.

dhernz and others added 3 commits August 17, 2026 13:45
…batch unconfirmed

execute() returns status PENDING immediately after the relay accepts the
intent when opts.noWait is set, before the batch is mined. hireErc8183Agent's
post-funding check read getErc8183Job right after that, so it observed
pre-inclusion chain state and threw "job ... is not ours after funding" on
every noWait call regardless of whether the funding would go on to succeed.

Only run the check once execute() reports CONFIRMED. The default (waiting)
path is unchanged.

Adds coverage in sessionKeyRegistration.test.ts, reusing its existing
relay-boundary mock rather than adding a second mock.module("./internal/relay.js")
registration in a new file (that leaked into client.balances.test.ts when tried).
@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown

@web3xDev is attempting to deploy a commit to the Functor Team on Vercel.

A member of the Team first needs to authorize it.

@dhernz
dhernz changed the base branch from main to staging August 18, 2026 10:06

@dhernz dhernz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this — a genuinely excellent first contribution, and welcome!

We verified the report end-to-end before merging, and everything checks out:

  • Bug confirmed in source: execute() with noWait: true returns {status: "PENDING"} before the batch is mined, and hireErc8183Agent's post-funding check ran unconditionally against pre-inclusion state — so every noWait hire threw the false "job is not ours" error, with the double-escrow retry hazard you described.
  • Tests proven meaningful: we applied only your test file to the unpatched branch — the noWait test fails there with exactly the reported error, and passes with your fix. The default-path mismatch protection still throws as intended.
  • Full gates green on your branch: typecheck, build, and all wallet test files pass per-file.

Also appreciated the care around bun's shared module registry — your reasoning for placing the tests in sessionKeyRegistration.test.ts matches a quirk we've documented in our CI config.

One housekeeping note: we've retargeted this PR to staging, which is now the repo's default branch. Our flow is feature branches → staging (accumulates the next SDK release) → main (the published SDK), so your fix will ship with the next version publish. New CONTRIBUTING.md documents this for next time. Hope to see you around!

@dhernz
dhernz merged commit b7154cd into altananetwork:staging Aug 18, 2026
2 of 3 checks passed
dhernz added a commit that referenced this pull request Aug 18, 2026
- CHANGELOG.md: Fixed entry under [Unreleased] for the hireErc8183Agent
  noWait false-error fix (credits @web3xDev, first external contribution).
- CONTRIBUTING.md: user-visible changes require an [Unreleased] entry;
  document the publish step (rename to version+date, publish to npm,
  merge staging -> main).
- PR template: changelog checkbox.
@web3xDev

Copy link
Copy Markdown
Contributor Author

Thanks so much for the kind words and for taking the time to verify everything! Really glad the fix and tests checked out. Looking forward to contributing more!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants