# IMD worker-routing feasibility report

Checked 2026-09-27 UTC. This is public, read-only research. I did not pair, revoke,
pay, submit, execute a downloaded worker/job, or call a state-changing route.

## Executive verdict

The requested marketplace is **not supported by the currently evidenced payout
routes**. It requires protocol changes before funds are handled. IMD has enough
identity and work metadata to be a useful input: an NFT seat (`tokenId`), paired
device key, job/node IDs, wallet, and bounded launch-reward snapshots. Those
records do not establish that all covered earnings are paid into a contract
receiver, nor that one NFT can be the sole accounting key when a wallet hosts
several seats.

The smallest safe design is a new, permissionless agreement layer that makes the
payment source call an immutable per-agreement splitter/ledger. The NFT remains
in its owner wallet; the host receives only a device authorization. Every
agreement version is accepted by both parties, and every earning is tagged with
`agreementId`, `version`, `tokenId`, `deviceKey`, `jobId` or reward epoch, and
the immutable recipient terms at the time work is accepted.

## Sources, snapshots, and confidence

* [IMD API docs](https://imd.fun/docs/) — live documentation read 2026-09-27;
  docs state protocol version is exposed by `/version`, identify the public
  earnings, seat, pairing, and launch routes, and document x402/Permit2 intake.
* [Live API version](https://api.imd.fun/version) — fetched 2026-09-27;
  commit `a073ba4efbfaf6de4b73d808e1542617eaf31412`, branch `master`, protocol
  version `1`, `deployedAt: null`, features scheduling/verificationQueue/
  startCommitAttribution.
* [Live API health](https://api.imd.fun/health) — fetched 2026-09-27;
  Ethereum identity chain, collection
  `0x0000ec93127baa929e58e97dd0095a2bfb38ec1d`, and payment counters were
  live. Counters are not individual worker payment receipts.
* [Live payment capabilities](https://api.imd.fun/requests/capabilities) —
  fetched 2026-09-27. Four enabled actions each require 0.5 IMD on Ethereum
  mainnet and pay to `0x4e0fa57bde726079356537e2f34d671e9f41adbc` through
  Permit2/x402.
* [IdentityMD worker repository](https://github.com/Identity-md/worker) —
  `main` read 2026-09-27. README describes worker pairing, one NFT authorizing
  one active device, `imd unlink`, and no earnings contract or payout method.
  The current release notes name worker `0.1.0+5cdc3b11` (source commit
  `5cdc3b11cdd6`).
* [One bounded public earnings sample](https://api.imd.fun/wallets/0x6d2f9da1911e88a116c6228f07e7cab9a927be9e/earnings?limit=5)
  — fetched 2026-09-27, five records. It returned Sepolia launch IDs,
  token addresses, amounts, and timestamps for a wallet. This is evidence of a
  public allocation/earnings record, not proof that a token transfer or claim
  occurred.
* [Sample launch record](https://api.imd.fun/launches/5af340ea-6022-40a8-b2c0-861d59a51fff)
  — fetched 2026-09-27. It contains a reward snapshot (`from`, `to`, `version`)
  and allocations keyed by `deviceKey` and `wallet`, with `shareBps: 49`,
  `amount`, and `policyVersion: 4`; it does not expose a verified payout/claim
  contract interface in the public response.
* [POOL4 docs](https://pool4.imd.fun/docs) — read 2026-09-27. The page names
  the deployed mainnet IMD/POOL4 contracts and states that node allocations are
  reserves while the node program and payout contract are being built.
* [ERC-8004 EIP-8004](https://eips.ethereum.org/EIPS/eip-8004) and the
  [ERC-8004 contracts repository](https://github.com/erc-8004/erc-8004-contracts)
  — primary standard/implementation references read 2026-09-27. `agentWallet`
  is a verified receiving-wallet metadata field, not a payment mandate; the
  standard explicitly leaves payment rails out of scope and clears the field on
  NFT transfer.

Where a source does not document a behavior, this report says “unverified”; it
does not infer impossibility.

## 1. Earnings that are evidenced today

| Stream | Asset / chain | Route or contract | Eligibility and recipient | Evidence and status |
|---|---|---|---|---|
| Customer request intake | IMD ERC-20 `0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7`, Ethereum mainnet | x402 exact payment using Permit2; live `payTo` is `0x4e0f...1adbc` | A wallet paying `job.open`, `launch.open`, `oracle.request`, or `workflow.open`; recipient is the configured operator/gas wallet, not a worker seat | Capabilities documents 0.5 IMD per action. Health reported 172 confirmed paid attempts at the check time. This confirms intake, not worker distribution; no individual worker payout tx was found in the cited public routes. |
| Worker/launch allocations | Project ERC-20s on Sepolia; sample included `ICE`, `OCTEST`, `FARE447`, `TOLL`-style launch records | Public `/wallets/:address/earnings` and `/launches/:id` records; payout/claim contract and verified source are not identified by those responses | Sample launch allocations name a `deviceKey`, wallet, share basis points, amount, and policy version; exact payment eligibility and claim path are undocumented | The five-record sample and launch snapshot are confirmed API records only. Accepted jobs are not treated as proof of payment. |
| POOL4 node reserve | IMD on Ethereum mainnet, token `0xD34a...263B7` | `RewardDistributor` `0x9046739E1535B40EfBe6AB3f45d0024b690eCA30` books the node share; POOL4 says the node payout contract has not shipped | Planned NFT inference nodes; not a live worker payout recipient | POOL4 describes 4.5% of each retired batch as reserved for NFT nodes and tracked as `heldNft`. It expressly calls this a reserve, not a live node program. |
| Staking return | IMD on Ethereum mainnet; sIMD ERC-4626 vault `0x9efa934d9fad4ae28c998a40195646b965a97247` and `RewardDripper` `0xe6D3De6daEAf327fCA42745f1998FcD989e00884` | POOL4 hook `0xc6c965bd164c483e87d0b550671798e9a3602840` → distributor → dripper → sIMD vault | A wallet that stakes IMD and holds sIMD shares; recipient is the vault position, not an NFT worker | POOL4 says 4.5% of retired batches streams to stakers, with no separate claim. This is a live staking return, not attributable to a worker NFT. Current UI counters were blank at the check, so no amount is asserted. |
| Sepolia project-token allocations | ERC-20 project token on Sepolia | Launch-specific deployment/allocation route is not sufficiently documented as a claim contract | Public allocation record names wallet/device key; claim eligibility, recipient control, and transfer proof remain unverified | Treat as an allocation ledger until a deployed, verified payout/claim contract and transfer receipts are supplied. |

The live sources therefore establish payment intake, staking mechanics, and
allocation records. They do **not** establish a current, immutable mainnet
worker-payment contract. No “accepted” or “completed” job is counted as a paid
worker earning.

## 2. Can earnings be bound to a contract receiver?

Not on the evidence available today.

ERC-8004 `agentWallet` can be set to a contract wallet after the required proof
of control, but the standard does not require an application to pay there. IMD's
documented mainnet intake has an explicit operator `payTo`; the docs do not say
that it resolves through the seat's ERC-8004 `agentWallet`. The worker pairing
flow also binds a device to a seat and agent; it does not document a payout
call.

An immutable splitter would protect only funds that actually enter it. It cannot
capture:

* direct payment to the IMD operator wallet;
* an off-chain allocation followed by manual forwarding;
* a Permit2 allowance that can be revoked or redirected;
* a contract whose owner can change its destination; or
* an `agentWallet` metadata change that the payer ignores.

The required invariant is stronger: the source contract must take an immutable
agreement/seat/epoch reference and transfer or credit the earning to the
agreement receiver in the same authoritative accounting path. If IMD keeps the
current operator-wallet or off-chain-forwarding route, a splitter is advisory
and the answer is no.

## 3. Per-seat attribution and delayed earnings

There is partial identity evidence but no sufficient financial join.

* `/seats/:tokenId` exposes `tokenId`, owner, agent ID, device presence, jobs,
  attempts, and collaborators.
* `/seats/records` is keyed by seat token ID.
* The sample launch allocation is keyed by `deviceKey` and wallet, not by
  `tokenId`; `/wallets/:address/earnings` aggregates by wallet.
* A wallet can hold multiple seats, and the public allocation response gives no
  demonstrated rule that maps every earning back to exactly one token ID.

The launch `rewardSnapshot` has an epoch-like `from`/`to`, version, and
`policyVersion`. That may support reporting, but it is not yet a demonstrated
immutable entitlement key surviving host exit, amendment, delayed payout, or
NFT transfer. In particular, a later wallet-level payout cannot safely decide
which prior seat/version it belongs to from the wallet alone.

Minimum protocol changes:

1. At job acceptance, bind an earning to `(chainId, collection, tokenId,
   deviceKey, jobId, acceptedAt/epoch, agreementId, agreementVersion)`.
2. Store the exact split and recipient addresses in an immutable version record;
   amendments create a new version and never rewrite old versions.
3. Make delayed rewards claim by that version/epoch record, not by current NFT
   owner, current device, or aggregated wallet balance.
4. Define transfer policy explicitly: either old-version balances remain owed to
   the recorded owner/recipient, or a transfer event changes only future work;
   never infer this from the current wallet.
5. Emit authoritative events and expose a read route that proves the source
   amount, seat, job/epoch, version, and claim status.

## 4. Exit, balances, and owner revocation

Ending future participation and unlinking an already paired device are separate
operations.

The worker README documents `imd unlink`, and the API exposes device enrollment,
standing, pairing state, and disconnect reasons such as `revoked`,
`nft_transferred`, and `agent_unregistered`. That is evidence that the control
plane can observe or enforce some disconnection states. It does not document a
wallet-owner unilateral revoke endpoint, a payout-balance withdrawal invariant,
or a proof that an owner can revoke a hosted device if the host disappears.

A viable agreement must make either-party exit a non-financial state transition:
`active` → `endedAt` for future work. It must not change or freeze already
credited balances. Both owner and host need independent `withdraw(version or
claimId)` operations, and a host going offline must not prevent either party
from withdrawing.

For owner control, IMD needs a signed owner action that revokes exactly the
`(tokenId, deviceKey, agreementId)` binding, plus an on-chain or otherwise
authoritative standing check that dispatch rejects after the revocation. NFT
transfer/unregistration may be additional safety conditions, but they are not
the same as confirmed worker unlinking and must not be used as a substitute for
the explicit revoke path.

## 5. Smallest viable architecture

1. A portable static frontend reads IMD public APIs and publishes signed offer
   objects. No platform token, swap, bridge, escrow, shared wallet, or
   credential sharing.
2. An offer names one collection/token ID, host device key, asset/chain, split,
   expiry, withdrawal rules, and the source adapter it accepts. Anyone may
   publish an offer.
3. Owner and host each sign the same canonical offer. The agreement factory
   creates an immutable `AgreementVersion` (or deterministically addressed
   splitter) containing both parties, token ID, device key, percentages, and
   version hash. An amendment creates a new mutually accepted version.
4. The IMD payout adapter is the only accepted source for covered earnings. It
   records a job/epoch entitlement against the active version and forwards funds
   to that version's splitter/ledger. If a source cannot do this, it is excluded
   from the “guaranteed split” product until integrated.
5. `endFutureWork()` is callable by either party and closes only future
   acceptance. `withdraw(claimId)` is callable independently by each recipient.
   Old claim IDs retain their original terms forever.
6. `revokeDevice()` is owner-authorized and scoped to the token/device binding;
   it prevents new dispatch while leaving old claims withdrawable. The host can
   independently exit without owner cooperation.
7. No privileged sweep, upgrade, or destination-change key exists. If an
   operational adapter must be upgradeable, it is not part of the trustless
   guarantee and must be clearly excluded or replaced by a fixed version.

Remaining trust: IMD must correctly and honestly classify accepted work and
fund the adapter; the host must do the work and protect its device key; the
owner must sign the intended agreement; token/project issuers must honor their
token rules; and users must verify the deployed bytecode and source. The
contract can enforce routing after receipt, but cannot force an external IMD
operator wallet or an undocumented manual forwarder to send funds into it.

## Implementation gates before handling funds

* Obtain verified source and exact addresses for every covered payout contract,
  including mainnet worker pay, Sepolia allocation/claim, and POOL4 node payout.
* Prove with fork tests that each source transfer/credit reaches the fixed
  receiver and cannot use `agentWallet`, owner changes, direct forwarding, or
  revocable allowance to bypass it.
* Test two seats in one wallet; delayed claims after host exit; amendment
  between acceptance and payment; NFT transfer; owner revoke while host is
  offline; host exit while balances are nonzero; duplicate claims; partial
  claims; zero/rounding amounts; and unsupported assets/chains.
* Test event/indexer reconstruction from logs alone: every claim must be
  attributable to exactly one token ID, device key, job/epoch, and agreement
  version.
* Test independent withdrawals when either counterparty is unavailable and
  confirm no admin sweep/upgrade/destination escape hatch in deployed bytecode.
* Before production, obtain independent review of the adapter and splitter and
  a live dry-run using worthless test assets. A successful API response or
  accepted job is not a payment test.

## Unsent question for IMD developers

> Which exact verified contracts and transaction/event examples currently pay
> worker hosts for accepted work (mainnet IMD, POOL4 node reserve, staking, and
> Sepolia project-token allocations), and for each one: what is the immutable
> source of eligibility, does it read ERC-8004 `agentWallet`, can the owner or
> operator change the payout destination, how is `(tokenId, deviceKey, jobId or
> epoch)` persisted for delayed claims, and what signed owner action revokes one
> hosted device without affecting already credited balances?

