Provider Docs

Provider economics

What you lock up, what you earn, and what you lose when you go offline. All figures are the deployed defaults; stake, windows, and bond are owner-tunable on-chain.

Stake

Registering locks 1,000 KEP (minStake, owner-adjustable) in the ProviderRegistry. You stay listable only while registered, not deactivated, and stake ≥ minStake — top up any time with topUpStake(amount). Exiting is deliberate: deactivate, settle every active deal, then wait the 7-day UNSTAKE_DELAY before withdrawStake() returns the full amount.

Collateral

Accepting a deal locks collateral equal to 50% of the deal's total price (collateralBps = 5000) from your wallet, on top of stake. It is returned in full at settlement — or bled away by faults. Keep enough unlocked KEP for incoming deals or the accept transaction reverts.

Payment vesting

The client escrows the full deal price at creation. From activation, it vests to you linearly per second over the deal duration. withdrawEarnings pays out whatever has vested since the last claim; settleDeal (callable by anyone after endTime, provided no challenge is open) pays the remainder and releases collateral.

Vesting
vested(t)  = totalPrice * (t - startTime) / duration
claimable  = vested(now) - paidOut

withdrawEarnings(dealId)   # provider, any time while Active
settleDeal(dealId)         # anyone, after endTime:
                           # pays remainder + returns collateral

The challenge game

Any KEP holder except the provider can challenge(dealId) an active deal, posting a 10 KEP bond (challengeBond), at most once per 12 h per deal (challengeCooldown). The challenged leaf is not chosen by the challenger: it is pinned from chain entropy — the blockhash of the challenge's commit block, hashed with the deal id and fault count, selects a pseudo-random chunk index only after the challenge is issued. If the blockhash lookback lapses before the index is pinned, rebaseChallenge restarts the window instead of slashing — a provider is never punished for a leaf it could not have learned.

You then have 8 h (proofWindow) to submitProof with the chunk bytes and a Merkle path. Success pays the bond to you. Failure lets anyone call reportFault:

Slashing math
collateral     = totalPrice * 50%          # locked at accept
slashPerFault  = collateral / 3            # fixed at accept time

per fault:
  challenger  ← slashPerFault / 2  + 10 KEP bond
  client      ← slashPerFault / 2

3rd fault (termination):
  client      ← unvested escrow + all remaining collateral
  provider    ← nothing further

Each fault slashes a third of the original collateral, split half to the challenger and half to the client. The third fault terminates the deal: the client is refunded all unvested escrow plus every remaining wei of collateral, and your unvested earnings are gone.

iNote
The daemon answers challenges automatically. For an honest, online provider the challenge game is strictly profitable: every challenge is a 10 KEP tip.

Gas-aware withdrawals

The daemon checks vested earnings on every maintenance pass, but claims only when it is economically sensible. A claim goes out when both hold:

Claim rule
claimable ≥ MIN_WITHDRAW_KEP            # worth checking at all
claimable > 2 × estimated tx cost       # worth spending gas on

tx cost = L2 gas × gas price
        + L1 data fee                   # NodeInterface.gasEstimateL1Component
                                        # on Arbitrum Nitro chains

The cost estimate covers L2 execution and, on Arbitrum Nitro chains, the L1 data-fee component queried from the NodeInterface precompile — so small drips are left to accumulate instead of being burned as gas. Earnings that are never individually worth claiming are still paid in full at settleDeal. Tune the floor with MIN_WITHDRAW_KEP.

Config knobs

All daemon behavior is set with environment variables (packages/provider-node/src/config.ts):

VariableDefaultMeaning
PROVIDER_PRIVATE_KEY— (required)Provider EOA key; signs register/accept/activate/proof/withdraw transactions.
KEPTO_CHAINlocalChain key to connect to (e.g. robinhoodTestnet).
RPC_URLchain defaultJSON-RPC endpoint override.
TOKEN_ADDRESS / KEPTO_TOKENfrom deploymentKeptoToken address when no generated deployment exists for the chain.
REGISTRY_ADDRESS / KEPTO_REGISTRYfrom deploymentProviderRegistry address override.
MARKET_ADDRESS / KEPTO_MARKETfrom deploymentStorageMarket address override.
PORT8747HTTP listen port for the /v1/* daemon API.
PUBLIC_URLhttp://127.0.0.1:<port>Base URL registered on-chain; must be the public HTTPS endpoint clients can reach.
DATA_DIR./provider-dataStorage root: chunks under <dataDir>/content/<merkleRoot>, manifest at <dataDir>/deals.json.
AUTO_REGISTERtrueApprove the stake and register in the ProviderRegistry on boot if not yet registered.
AUTO_ACCEPTtrueAccept incoming deals automatically when they pass policy.
MIN_PRICE_PER_GIB_EPOCH10 KEPAuto-accept policy: minimum deal price per GiB per 30-day epoch (decimal KEP).
MAX_DEAL_SIZE_BYTES1 GiBAuto-accept policy: largest single deal accepted.
CAPACITY_BYTES10 GiBAdvertised capacity; deals are refused when used + incoming would exceed it.
POLL_INTERVAL_MS3000Chain polling cadence for events and maintenance (challenges, vesting, settlement).
LOG_CHUNK_BLOCKS10000Maximum block range per getLogs call when catching up on events.
MIN_WITHDRAW_KEP0.5Minimum claimable KEP before a withdrawEarnings transaction is even considered.

For the deploy that sets these for you, go back to the provider guide.