ogpu.protocol¶
1:1 wrappers around the OGPU contract ABIs. This is the layer that
actually talks to the chain — everything above it (ogpu.client,
ogpu.agent, ogpu.events) eventually funnels here.
The protocol layer exposes two parallel API styles:
- Instance classes (
Source,Task,Response,Provider,Master) — stateless live proxies bound to a single contract address. Clean for dashboards and any code that already holds a concept of "this task" or "this provider". Every method is a fresh RPC call; onlyself.addressis persisted. - Module functions (
nexus,controller,terminal,vault) — function-style wrappers on the four singleton contracts. Use when you want to do a single call without constructing an instance, or when iterating many addresses.
Every write function takes a signer= keyword argument that accepts
a hex private key string, an eth_account.LocalAccount, or None
(env-var fallback via resolve_signer). Vault operations have no
env-var fallback — they require explicit signer= to prevent
accidental cross-role transactions.
Revert decoding is handled uniformly by TxExecutor: every known
Solidity revert reason maps to a typed OGPUError subclass, and
unknown reverts fall through to a generic TxRevertError(reason=...).
See error handling for the full mapping.
Instance classes¶
Source¶
ogpu.protocol.source.Source
¶
Live, stateless proxy to an on-chain Source contract.
Holds only self.address and self.chain — no cached state.
Every method is a fresh RPC call. This makes method semantics
predictable (you always read current chain state) and instance
construction cheap (no RPC at __init__).
Two construction modes:
Source(address)— lazy. No RPC. Use when you trust the address and want to defer validation until the first read.Source.load(address)— eager. Runs a cheapget_status()probe and raisesSourceNotFoundErrorif the address isn't a valid source contract.
Equality is address-based and case-insensitive. Hashing matches
equality, so Source instances can be used as dict keys or in
sets.
Example
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str
|
Checksummed contract address. |
chain |
Optional chain binding (defaults to None — most code
uses the globally-active chain from |
Construct a lazy Source instance (no RPC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Source contract address. Checksummed automatically. |
required |
chain
|
object
|
Optional chain binding for future multi-chain support. |
None
|
load
classmethod
¶
load(address: str, chain: object = None) -> Source
Eager constructor — validate that the address is a Source contract.
Runs a cheap get_status() probe. If the probe reverts, the
address is either not a contract or not a Source, and
SourceNotFoundError is raised immediately.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Source contract address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
Returns:
| Type | Description |
|---|---|
Source
|
A |
Raises:
| Type | Description |
|---|---|
SourceNotFoundError
|
If the probe call fails. |
get_client
¶
Return the address that owns (published) this source.
Only this address can call set_status, set_params, or
inactivate.
Returns:
| Type | Description |
|---|---|
str
|
Owner's checksummed address. |
get_status
¶
get_status() -> SourceStatus
Return the current lifecycle status of the source.
Returns:
| Type | Description |
|---|---|
SourceStatus
|
|
get_params
¶
get_params() -> SourceParams
Fetch the full on-chain SourceParams tuple.
Returns the raw parameters stored on the contract — name,
description, environment bitmask, min payment, etc. — without
touching IPFS. For the human-readable metadata (including
logoUrl and description), call get_metadata().
Returns:
| Type | Description |
|---|---|
SourceParams
|
|
SourceParams
|
contract. |
get_metadata
¶
Fetch the off-chain SourceMetadata JSON from IPFS.
Makes two calls: one to read SourceParams.imageMetadataUrl
from chain, and one HTTP GET to fetch the pointed-at JSON.
Returns the parsed dict — typically matches the structure of
the SourceMetadata dataclass (cpu, nvidia, amd, name,
description, logoUrl).
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Parsed metadata dict. |
Raises:
| Type | Description |
|---|---|
IPFSFetchError
|
Network error, timeout, or invalid JSON. |
IPFSGatewayError
|
Gateway returned non-200. |
get_task_count
¶
Return the total number of tasks ever published against this source.
Returns:
| Type | Description |
|---|---|
int
|
Integer task count. |
get_tasks
¶
get_tasks(lower: int = 0, upper: int | None = None) -> list[Task]
Return the tasks published against this source, as Task instances.
Paginated — omit upper (or pass None) to fetch all
tasks via internal chunking. Results are returned as live
Task proxies ready for further reads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lower
|
int
|
Start index (inclusive). Defaults to 0. |
0
|
upper
|
int | None
|
End index (exclusive). Defaults to all. |
None
|
Returns:
| Type | Description |
|---|---|
list[Task]
|
List of |
get_registrant_count
¶
Return the number of providers currently registered to this source.
Returns:
| Type | Description |
|---|---|
int
|
Integer registrant count. |
get_registrants
¶
Return the addresses of providers registered to this source.
Paginated — omit upper to fetch all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lower
|
int
|
Start index (inclusive). |
0
|
upper
|
int | None
|
End index (exclusive). Defaults to all. |
None
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of provider addresses. |
get_registrant_id
¶
Return the slot index of a provider in the registrant list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to look up. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The integer slot index, or 0 if the provider is not registered. |
get_preferred_environment_of
¶
get_preferred_environment_of(provider: str) -> Environment
Return the hardware environment a provider registered with.
Every Nexus.register call records which environment the
provider registered for (CPU, NVIDIA, or AMD). This reader
returns the choice as a typed Environment flag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address. |
required |
Returns:
| Type | Description |
|---|---|
Environment
|
The provider's preferred |
set_status
¶
set_status(status: SourceStatus, *, signer: Signer | None = None) -> Receipt
Set the source's status by calling Source.setStatus(uint8) directly.
Goes straight to the instance contract (owner route) rather
than through Nexus.setSourceStatus (admin route). Must be
called by the source's owner.
Most client code uses inactivate() for the common transition
to INACTIVE; set_status is the lower-level primitive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status
|
SourceStatus
|
The target |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotSourceOwnerError
|
If the signer isn't the source's owner. |
set_params
¶
set_params(params: SourceParams, *, signer: Signer | None = None) -> Receipt
Update the source's parameters by calling Nexus.updateSource.
Goes through Nexus (rather than the source contract directly)
so the SourceUpdated event fires. Must be called by the
source's owner.
Typically you'd build a fresh SourceInfo and pass it through
client.update_source — that wrapper builds the SourceParams
for you. Use this instance method when you already have a
SourceParams tuple.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
SourceParams
|
The new |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotSourceOwnerError
|
If the signer isn't the source's owner. |
inactivate
¶
inactivate(*, signer: Signer | None = None) -> Receipt
Inactivate the source by calling Nexus.inactivateSource.
One-way transition — there is no reactivation. After this call,
publishing new tasks against the source reverts with
SourceInactiveError. Existing tasks continue their natural
lifecycle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotSourceOwnerError
|
If the signer isn't the source's owner. |
snapshot
¶
snapshot() -> SourceSnapshot
Return a frozen capture of every non-paginated field.
Issues one RPC per view call in sequence (not parallel) and
bundles the results into a SourceSnapshot dataclass.
Omits paginated reads (get_tasks, get_registrants) and
IPFS reads (get_metadata) — call those explicitly if you
need them.
Use snapshot() for dashboards, logging, and atomic reads
where you want all the fields to come from roughly the same
block. For single-field reads, use the getter directly.
Returns:
| Type | Description |
|---|---|
SourceSnapshot
|
|
SourceSnapshot
|
task_count, registrant_count. |
Task¶
ogpu.protocol.task.Task
¶
Live, stateless proxy to an on-chain Task contract.
Holds only self.address and self.chain — no cached state.
Every method is a fresh RPC call.
A task's lifecycle: NEW → ATTEMPTED (first attempt arrives)
→ RESPONDED (first response submitted) → FINALIZED (response
confirmed or first-response auto-finalization). Alternative exits:
CANCELED (client canceled before any attempts) or EXPIRED
(expiryTime passed without resolution).
Two construction modes:
Task(address)— lazy, no RPC.Task.load(address)— eager, probesget_status()and raisesTaskNotFoundErroron failure.
Equality is case-insensitive address comparison; hashing matches,
so Task instances are usable as dict keys or in sets.
Example
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str
|
Checksummed contract address. |
chain |
Optional chain binding. |
Construct a lazy Task instance (no RPC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Task contract address. Checksummed automatically. |
required |
chain
|
object
|
Optional chain binding. |
None
|
load
classmethod
¶
load(address: str, chain: object = None) -> Task
Eager constructor — validate that the address is a Task contract.
Runs a cheap get_status() probe. If the probe reverts,
raises TaskNotFoundError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Task contract address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
Returns:
| Type | Description |
|---|---|
Task
|
A |
Raises:
| Type | Description |
|---|---|
TaskNotFoundError
|
If the probe call fails. |
get_source
¶
get_source() -> Source
Navigate from this task back to its parent source.
Returns a fresh Source instance (no RPC beyond the one
that reads the address). Useful for chaining reads:
task.get_source().get_status().
Returns:
| Type | Description |
|---|---|
Source
|
A |
get_status
¶
get_status() -> TaskStatus
Return the current lifecycle status of the task.
Returns:
| Type | Description |
|---|---|
TaskStatus
|
One of |
TaskStatus
|
|
get_params
¶
get_params() -> TaskParams
Fetch the full on-chain TaskParams tuple.
Includes the source address, IPFS config URL, expiry time, and
payment. For the actual task input (function name + data), use
get_metadata() which follows the IPFS URL.
Returns:
| Type | Description |
|---|---|
TaskParams
|
|
get_metadata
¶
Fetch the task's config JSON from IPFS.
Reads TaskParams.config (an IPFS URL) and fetches the
pointed-at JSON body. The returned dict typically matches the
structure of the TaskInput that was uploaded when the
task was published — function_name, data, and any
extra fields the client added.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Parsed config dict. |
Raises:
| Type | Description |
|---|---|
IPFSFetchError / IPFSGatewayError
|
On fetch failure. |
get_payment
¶
Return the payment offered by this task, in wei.
Returns:
| Type | Description |
|---|---|
int
|
Payment amount in wei. |
get_expiry_time
¶
Return the task's expiry as a Unix timestamp.
After this time, attempts and responses revert. Nexus will
mark the task EXPIRED on the next attempt.
Returns:
| Type | Description |
|---|---|
int
|
Unix timestamp. |
get_delivery_method
¶
get_delivery_method() -> DeliveryMethod
Return the delivery method inherited from the source.
Tasks inherit their delivery method from the source at publish time — it cannot be changed after publication.
Returns:
| Type | Description |
|---|---|
DeliveryMethod
|
|
DeliveryMethod
|
|
get_attempt_count
¶
Return the number of providers who've attempted this task.
Returns:
| Type | Description |
|---|---|
int
|
Integer attempt count. |
get_attempters
¶
Return the addresses of providers who attempted this task.
Paginated — omit upper to fetch all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lower
|
int
|
Start index (inclusive). |
0
|
upper
|
int | None
|
End index (exclusive). Defaults to all. |
None
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of provider addresses. |
get_attempter_id
¶
Return the slot index of a provider in the attempter list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The integer slot index, or 0 if the provider hasn't attempted. |
get_attempt_timestamps
¶
Return the timestamps at which attempts were submitted.
Each attempter has a corresponding timestamp, stored at the same
index as in get_attempters. Useful for latency analysis or
dispatching timeouts based on how long ago a provider claimed
the task.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lower
|
int
|
Start index. |
0
|
upper
|
int | None
|
End index. Defaults to all. |
None
|
Returns:
| Type | Description |
|---|---|
list[int]
|
List of Unix timestamps. |
get_responses
¶
get_responses(lower: int = 0, upper: int | None = None) -> list[Response]
Return all responses submitted for this task, as Response instances.
Paginated — omit upper to fetch all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lower
|
int
|
Start index. |
0
|
upper
|
int | None
|
End index. Defaults to all. |
None
|
Returns:
| Type | Description |
|---|---|
list[Response]
|
List of |
get_confirmed_response
¶
get_confirmed_response() -> Response | None
Return the confirmed response for this task, if any.
Chain-only replacement for the old HTTP-based
get_confirmed_response(task_address) function. Iterates
through get_responses() and returns the first one with
is_confirmed() == True. Since at most one response per task
can be confirmed, this is the winning response.
Returns:
| Type | Description |
|---|---|
Response | None
|
A confirmed |
Response | None
|
been confirmed yet. |
get_winning_provider
¶
Return the address of the provider whose response was confirmed.
Returns:
| Type | Description |
|---|---|
str | None
|
Provider address if the task has been finalized, otherwise |
str | None
|
|
is_already_submitted
¶
Return whether a given response hash has already been submitted.
Used by providers to deduplicate response content — the contract tracks submitted hashes to prevent double-submission of the same payload from the same provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hash_bytes
|
bytes
|
32-byte hash of the response payload. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if a response with this hash has already been recorded. |
cancel
¶
cancel(*, signer: Signer | None = None) -> Receipt
Cancel the task by calling Controller.cancelTask.
Only works while the task is still in NEW state — once any
provider has called attempt, cancel reverts with
TaskAlreadyFinalizedError (or similar). Must be called by
the task's client.
On success, the escrowed payment is released back to the client
and the task transitions to CANCELED.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotTaskOwnerError
|
If the signer isn't the task's client. |
TaskAlreadyFinalizedError
|
If the task is past |
snapshot
¶
snapshot() -> TaskSnapshot
Return a frozen capture of every non-paginated field.
Issues one RPC per view call (sequential, not parallel) and
bundles the results into a TaskSnapshot dataclass. Omits
paginated fields (get_attempters, get_responses) and
IPFS-fetching fields (get_metadata) — call those explicitly.
Returns:
| Type | Description |
|---|---|
TaskSnapshot
|
|
TaskSnapshot
|
payment, expiry_time, delivery_method, attempt_count, and |
TaskSnapshot
|
winning_provider. |
Response¶
ogpu.protocol.response.Response
¶
Live, stateless proxy to an on-chain Response contract.
Responses are deployed by Nexus.submitResponse whenever a
provider produces output for a task. The Response contract carries
the provider's signature, the payment they claimed, and a data
field holding a URL (usually IPFS) to the actual payload.
Lifecycle: SUBMITTED → CONFIRMED. The transition happens
when the client calls confirm_response (MANUAL_CONFIRMATION
delivery) or automatically on the first submit
(FIRST_RESPONSE delivery).
Construction:
Response(address)— lazy, no RPC.Response.load(address)— eager, probesget_status().
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str
|
Checksummed contract address. |
chain |
Optional chain binding. |
Construct a lazy Response instance (no RPC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Response contract address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
load
classmethod
¶
load(address: str, chain: object = None) -> Response
Eager constructor — validate that the address is a Response contract.
Runs a get_status() probe and raises
ResponseNotFoundError on failure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Response contract address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
Returns:
| Type | Description |
|---|---|
Response
|
A |
Raises:
| Type | Description |
|---|---|
ResponseNotFoundError
|
If the probe fails. |
get_task
¶
get_task() -> Task
Navigate from this response back to its parent task.
Returns a fresh Task instance. Useful for chaining:
response.get_task().get_status().
Returns:
| Type | Description |
|---|---|
Task
|
A |
get_params
¶
get_params() -> ResponseParams
Fetch the full on-chain ResponseParams tuple.
Returns:
| Type | Description |
|---|---|
ResponseParams
|
|
get_data
¶
Return the raw data field (usually an IPFS URL) as a string.
Cheap — just reads the params tuple. For the actual content
behind the URL, use fetch_data().
Returns:
| Type | Description |
|---|---|
str
|
The data URL string. |
fetch_data
¶
Fetch the off-chain payload from the data URL and parse as JSON.
Performs one HTTP GET and returns the parsed dict. Only handles
JSON bodies — if a provider produced binary output (model
weights, images), use get_data() to get the URL and fetch
it with your own client.
Follows the A2 naming rule: get_data() is cheap/local
(reads a field), fetch_data() is network I/O.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Parsed JSON payload as a dict. |
Raises:
| Type | Description |
|---|---|
IPFSFetchError
|
Network error or invalid JSON. |
IPFSGatewayError
|
Gateway returned non-200. |
get_status
¶
get_status() -> ResponseStatus
Return the current status of the response.
Returns:
| Type | Description |
|---|---|
ResponseStatus
|
|
get_timestamp
¶
Return the Unix timestamp when the response was submitted.
Returns:
| Type | Description |
|---|---|
int
|
Unix timestamp. |
is_confirmed
¶
Return whether this response has been confirmed by the client.
Returns True if the response is the winning response for its
parent task. For FIRST_RESPONSE delivery this flips to True
immediately on submission; for MANUAL_CONFIRMATION it
requires a separate confirm_response call from the client.
Returns:
| Type | Description |
|---|---|
bool
|
True if confirmed. |
confirm
¶
confirm(*, signer: Signer | None = None) -> Receipt
Confirm this response by calling Controller.confirmResponse.
Must be called by the parent task's client. On success:
- This response transitions to
CONFIRMED. - The parent task transitions to
FINALIZED. - The escrowed payment is released from the vault to the response's provider.
Only meaningful for MANUAL_CONFIRMATION delivery — for
FIRST_RESPONSE, confirmation happens automatically on
submission.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotTaskOwnerError
|
Caller isn't the task's client. |
ResponseAlreadyConfirmedError
|
Already confirmed. |
snapshot
¶
snapshot() -> ResponseSnapshot
Return a frozen capture of every field.
Issues a few RPCs in sequence and bundles the results into a
ResponseSnapshot dataclass. Note that fetch_data() is
NOT included — the snapshot is chain-only, fetching IPFS is
still an explicit call.
Returns:
| Type | Description |
|---|---|
ResponseSnapshot
|
|
ResponseSnapshot
|
status, timestamp, confirmed. |
Provider¶
ogpu.protocol.provider.Provider
¶
Synthetic instance class wrapping provider-scoped operations.
Unlike Source / Task / Response, the Provider class is
NOT backed by a single contract ABI — there is no "Provider" contract
on-chain. Instead, Provider(address) is a convenience wrapper
that composes calls across three contracts:
- Terminal — identity, pairing, read-only base/live data lookups
- Vault — balance, lockup, unbonding, earnings, eligibility
- Nexus — source registrations and attempts
Every method delegates to a module-level protocol function, filling
in self.address as the provider argument where appropriate.
This gives you a cleaner API surface when your code holds a
"provider" concept (dashboards, provisioning scripts, scheduler
code) without needing to pass the address around repeatedly.
Provider-app responsibilities are not exposed here
Operations that produce live compute output or self-reported
provider state — submit_response, set_base_data,
set_live_data — are intentionally absent. Those must be
called by the docker source itself running real compute, not
by an SDK caller, otherwise providers could spoof responses
or capacity claims from arbitrary scripts.
Lazy by default — Provider(address) does no RPC. Use
Provider.load(address) if you want an eager existence check
(Terminal.isProvider must return True).
Example
from ogpu.protocol import Provider
p = Provider.load("0xPROVIDER")
print(p.get_master()) # from Terminal
print(p.get_lockup()) # from Vault
print(p.is_eligible()) # from Vault
for source in p.get_registered_sources(): # from Nexus
print(source.address)
snap = p.snapshot() # batch capture across all three contracts
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str
|
Checksummed provider address. |
chain |
Optional chain binding. |
Construct a lazy Provider instance (no RPC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Provider address. Checksummed automatically. |
required |
chain
|
object
|
Optional chain binding. |
None
|
load
classmethod
¶
load(address: str, chain: object = None) -> Provider
Eager constructor — validate that the address is a registered provider.
Runs Terminal.isProvider(address) and raises
ProviderNotFoundError if it returns False.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Provider address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
Returns:
| Type | Description |
|---|---|
Provider
|
A |
Raises:
| Type | Description |
|---|---|
ProviderNotFoundError
|
If the address is not a registered provider. |
get_master
¶
Return the master this provider is paired with.
Delegates to Terminal.masterOf(self.address). Returns the
zero address if the provider isn't paired.
get_base_data
¶
Return the long-lived metadata URL for this provider.
Delegates to Terminal.baseDataOf(self.address). Typically
an IPFS URL pointing at a JSON document describing the
provider's hardware and capabilities.
get_live_data
¶
Return the short-lived status URL for this provider.
Delegates to Terminal.liveDataOf(self.address). Typically
refreshed more frequently than base data — current load,
health, etc.
is_provider
¶
Return whether this address is registered as a provider.
Delegates to Terminal.isProvider(self.address).
get_default_agent_disabled
¶
Return whether the provider opted out of default agent delegation.
Delegates to Terminal.defaultAgentDisabled(self.address).
When True, the built-in scheduling agent (The Order) no
longer dispatches tasks to this provider automatically.
get_balance
¶
Return available (liquid) vault balance in wei.
Delegates to Vault.balanceOf(self.address).
get_lockup
¶
Return locked (staked) amount in wei.
Delegates to Vault.lockupOf(self.address). This is what
backs source registrations.
get_unbonding
¶
Return amount currently unbonding in wei.
Delegates to Vault.unbondingOf(self.address). Zero unless
the provider has called unbond and hasn't yet claim'd.
get_unbonding_timestamp
¶
Return the Unix timestamp when the current unbonding matures.
Delegates to Vault.unbondingTimestamp(self.address).
get_total_earnings
¶
Return cumulative earnings in wei.
Delegates to Vault.totalEarningsOf(self.address).
get_frozen_payment
¶
Return the amount escrowed against pending attempts in wei.
Delegates to Vault.frozenPayment(self.address).
get_sanction
¶
Return protocol sanction amount in wei.
Delegates to Vault.sanctionOf(self.address). Usually zero.
is_eligible
¶
Return whether the provider is eligible for vault operations.
Delegates to Vault.isEligible(self.address).
is_whitelisted
¶
Return whether the provider is on the vault whitelist.
Delegates to Vault.isWhitelisted(self.address).
announce_master
¶
announce_master(master: str, *, signer: Signer | None = None) -> Receipt
Pair this provider with a master by calling Terminal.announceMaster.
Must be called by the provider's own key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master
|
str
|
Master address to pair with. |
required |
signer
|
Signer | None
|
Provider signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
set_default_agent_disabled
¶
set_default_agent_disabled(value: bool, *, signer: Signer | None = None) -> Receipt
Opt this provider out of (or back into) default agent delegation.
Delegates to Terminal.setDefaultAgentDisabled. Must be
called by the provider's own key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
bool
|
True to disable, False to enable. |
required |
signer
|
Signer | None
|
Provider signer. Falls back to |
None
|
register_to
¶
register_to(source: str, env: int, *, signer: Signer | None = None) -> Receipt
Register this provider to a source.
Delegates to Nexus.register(source, self.address, env).
Can be called by the provider directly, the master, or an
authorized agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Source contract address to register to. |
required |
env
|
int
|
Preferred environment bitmask ( |
required |
signer
|
Signer | None
|
Provider/master/agent signer. Falls back to
|
None
|
unregister_from
¶
unregister_from(source: str, *, signer: Signer | None = None) -> Receipt
Unregister this provider from a source.
Delegates to Nexus.unregister(source, self.address).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Source contract address. |
required |
signer
|
Signer | None
|
Provider/master/agent signer. |
None
|
attempt
¶
attempt(task: str, suggested_payment: int, *, signer: Signer | None = None) -> Receipt
Submit an attempt on a task for this provider.
Delegates to Nexus.attempt(task, self.address, suggested_payment).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str
|
Task contract address. |
required |
suggested_payment
|
int
|
Advisory payment amount in wei. |
required |
signer
|
Signer | None
|
Provider/master/agent signer. |
None
|
stake
¶
stake(amount: int, *, signer: Signer) -> Receipt
Lock amount into this provider's vault lockup.
Convenience wrapper for vault.lock. signer must be
explicit — vault operations do not fall back to env vars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
int
|
Amount to lock in wei. |
required |
signer
|
Signer
|
Required hex key or |
required |
unstake
¶
unstake(amount: int, *, signer: Signer) -> Receipt
Start unbonding amount from this provider's lockup.
Convenience wrapper for vault.unbond.
cancel_unbonding
¶
cancel_unbonding(*, signer: Signer) -> Receipt
Abort any pending unbonding for this provider.
Convenience wrapper for vault.cancel_unbonding.
claim_earnings
¶
claim_earnings(*, signer: Signer) -> Receipt
Claim matured unbonded amounts into the liquid balance.
Convenience wrapper for vault.claim.
deposit_to_vault
¶
deposit_to_vault(amount: int, *, signer: Signer) -> Receipt
Deposit amount into this provider's vault balance.
Convenience wrapper for vault.deposit(self.address, amount).
The signer can be the provider themselves or anyone funding
the provider (e.g. the master).
withdraw_from_vault
¶
withdraw_from_vault(amount: int, *, signer: Signer) -> Receipt
Withdraw amount from this provider's liquid vault balance.
Convenience wrapper for vault.withdraw. signer must
hold the keys for self.address — vault withdraw uses
msg.sender.
snapshot
¶
snapshot() -> ProviderSnapshot
Return a frozen capture of Terminal + Vault state in one batch.
Issues one RPC per field (sequential) and bundles the results
into a ProviderSnapshot. Omits paginated Nexus fields
(get_registered_sources) — call those explicitly.
Returns:
| Type | Description |
|---|---|
ProviderSnapshot
|
|
Master¶
ogpu.protocol.master.Master
¶
Synthetic instance class wrapping master-scoped operations.
Like Provider, the Master class is NOT backed by a single
contract ABI — Master(address) composes calls across Terminal
and Vault into a cleaner per-master API surface. Lighter than
Provider because masters have a smaller operational surface:
- Terminal — pairing with a provider, setting agents, removing providers/containers
- Vault — balance, lockup, earnings, eligibility
Masters do not touch Nexus directly — provider-side scheduling
operations (register, attempt) are provider-role calls,
though masters can authorize an agent to drive them via
set_agent + ogpu.agent. Compute-output operations like
submit_response are not exposed in the SDK at all and must be
produced by the docker source running real compute.
Lazy by default; use Master.load(address) for eager existence
checking (Terminal.isMaster must return True).
Example
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str
|
Checksummed master address. |
chain |
Optional chain binding. |
Construct a lazy Master instance (no RPC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Master address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
load
classmethod
¶
load(address: str, chain: object = None) -> Master
Eager constructor — validate that the address is a registered master.
Runs Terminal.isMaster(address) and raises
MasterNotFoundError if it returns False.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Master address. |
required |
chain
|
object
|
Optional chain binding. |
None
|
Returns:
| Type | Description |
|---|---|
Master
|
A |
Raises:
| Type | Description |
|---|---|
MasterNotFoundError
|
If the address is not a registered master. |
get_provider
¶
Return the provider this master is paired with.
Delegates to Terminal.providerOf(self.address). Returns
the zero address if unpaired.
is_master
¶
Return whether this address is registered as a master.
Delegates to Terminal.isMaster(self.address).
get_frozen_payment
¶
Return the amount escrowed against pending task work in wei.
announce_provider
¶
announce_provider(provider: str, amount: int, *, signer: Signer | None = None) -> Receipt
Claim a provider by calling Terminal.announceProvider (payable).
First half of master/provider pairing. Sends amount as
msg.value — gets credited to the provider's vault lockup.
The pairing is completed when the provider subsequently calls
announceMaster.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address being claimed. |
required |
amount
|
int
|
Initial funding amount in wei. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
remove_provider
¶
remove_provider(provider: str, *, signer: Signer | None = None) -> Receipt
Break the pairing with a provider by calling Terminal.removeProvider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to remove. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
remove_container
¶
remove_container(provider: str, source: str, *, signer: Signer | None = None) -> Receipt
Signal a provider should stop running a source's container.
Delegates to Terminal.removeContainer. Doesn't actually
stop the docker container — emits an event the Provider App
watches and acts on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider whose container should stop. |
required |
source
|
str
|
Source whose container should stop. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
set_agent
¶
set_agent(agent: str, value: bool, *, signer: Signer | None = None) -> Receipt
Authorize (or revoke) an agent to sign on this master's behalf.
Delegates to Terminal.setAgent(agent, value). After
value=True, the agent's key can sign Nexus operations
(register, attempt, etc.) for providers managed by this master.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
str
|
Agent address. |
required |
value
|
bool
|
True to authorize, False to revoke. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
stake
¶
stake(amount: int, *, signer: Signer) -> Receipt
Lock amount into this master's vault lockup.
Convenience wrapper for vault.lock. signer must be
explicit — vault operations do not fall back to env vars.
unstake
¶
unstake(amount: int, *, signer: Signer) -> Receipt
Start unbonding amount from this master's lockup.
Convenience wrapper for vault.unbond.
cancel_unbonding
¶
cancel_unbonding(*, signer: Signer) -> Receipt
Abort any pending unbonding for this master.
Convenience wrapper for vault.cancel_unbonding.
claim_earnings
¶
claim_earnings(*, signer: Signer) -> Receipt
Claim matured unbonded amounts into the liquid balance.
Convenience wrapper for vault.claim.
deposit_to_vault
¶
deposit_to_vault(amount: int, *, signer: Signer) -> Receipt
Deposit amount into this master's vault balance.
Convenience wrapper for vault.deposit(self.address, amount).
withdraw_from_vault
¶
withdraw_from_vault(amount: int, *, signer: Signer) -> Receipt
Withdraw amount from this master's liquid vault balance.
Convenience wrapper for vault.withdraw. signer must
hold the keys for self.address.
snapshot
¶
snapshot() -> MasterSnapshot
Return a frozen capture of Terminal + Vault state in one batch.
Returns:
| Type | Description |
|---|---|
MasterSnapshot
|
|
MasterSnapshot
|
status, and all vault balance fields. |
Module-level functions¶
ogpu.protocol.nexus¶
Nexus contract — low-level wrappers.
The Nexus contract is the central registry for sources, tasks, and provider registrations. Every client-side publish operation, every provider-side task execution, and most status-changing flows run through Nexus.
This module is a thin 1:1 mirror of the NexusAbi function surface.
You rarely call these functions directly — the ogpu.client wrappers
(publish_source, update_source, inactivate_source), the
ogpu.agent wrappers (register_to, attempt), and the instance
classes (Source.set_params, Task.cancel) all delegate here.
publish_source
¶
publish_source(params: SourceParams, *, signer: Signer | None = None) -> Receipt
Call Nexus.publishSource(params) to deploy a new source.
This is the low-level entry point. client.publish_source is the
user-facing wrapper that builds the SourceParams from a
SourceInfo (including IPFS upload of metadata) and then wraps
the receipt in a Source instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
SourceParams
|
Fully-built |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Receipt
|
to pull the new source's contract address out of the receipt's |
Receipt
|
|
Raises:
| Type | Description |
|---|---|
MissingSignerError
|
If no signer is available. |
TxRevertError / other OGPUError
|
See |
update_source
¶
update_source(source_address: str, params: SourceParams, *, signer: Signer | None = None) -> Receipt
Call Nexus.updateSource(source, params) to change source parameters.
Goes through Nexus (rather than the source contract directly) so the
SourceUpdated event fires. Must be called by the source's owner.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_address
|
str
|
The source contract to update. |
required |
params
|
SourceParams
|
The new |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotSourceOwnerError
|
If the signer isn't the source's owner. |
MissingSignerError
|
If no signer is available. |
inactivate_source
¶
inactivate_source(source_address: str, *, signer: Signer | None = None) -> Receipt
Call Nexus.inactivateSource(source) to close a source to new tasks.
One-way transition — there is no "re-activate". Existing tasks under the source continue their natural lifecycle but no new tasks can be published against it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_address
|
str
|
The source contract to inactivate. |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotSourceOwnerError
|
If the signer isn't the source's owner. |
MissingSignerError
|
If no signer is available. |
register
¶
register(source: str, provider: str, env: int, *, signer: Signer | None = None) -> Receipt
Call Nexus.register(source, provider, preferredEnvironment).
Registers a provider to attempt tasks on a source. Can be called by:
- The provider itself (passing their own address as
provider) - The provider's master (who manages them)
- An agent authorized by the master via
Terminal.setAgent
The protocol's isAgentOf check in the contract authorizes
agent-based calls. The signer's role resolution defaults to
PROVIDER (reads PROVIDER_PRIVATE_KEY), but you can pass
any authorized key explicitly via signer=.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Source contract address to register to. |
required |
provider
|
str
|
Provider address being registered. Same as signer for self-registration; different for master/agent-driven flows. |
required |
env
|
int
|
Preferred environment bitmask from |
required |
signer
|
Signer | None
|
The signing key. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
InsufficientLockupError
|
Provider doesn't hold enough lockup
for this source's |
SourceInactiveError
|
Source is already inactivated. |
unregister
¶
unregister(source: str, provider: str, *, signer: Signer | None = None) -> Receipt
Call Nexus.unregister(source, provider).
Removes a provider from the source's registrant list. Follows the
same authorization rules as register — self, master, or
authorized agent can call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
Source contract address. |
required |
provider
|
str
|
Provider address being unregistered. |
required |
signer
|
Signer | None
|
The signing key. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
attempt
¶
attempt(task: str, provider: str, suggested_payment: int, *, signer: Signer | None = None) -> Receipt
Call Nexus.attempt(task, provider, suggestedPayment).
Records that a provider is attempting a task. The provider is committing to produce a response — the suggested payment field is an advisory number about what the provider expects to receive from the client's escrowed payment for the task.
Follows the same authorization rules as register. Sets the
task's status to ATTEMPTED on first call if it was NEW.
If the task has already expired, the transaction may mark it as
EXPIRED instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str
|
Task contract address. |
required |
provider
|
str
|
Provider address making the attempt. |
required |
suggested_payment
|
int
|
Advisory payment amount in wei. |
required |
signer
|
Signer | None
|
The signing key. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
TaskExpiredError
|
Task's |
TaskAlreadyFinalizedError
|
Task is already in terminal state. |
ogpu.protocol.controller¶
Controller contract — low-level wrappers.
The Controller contract handles client-side task lifecycle operations: publishing new tasks, confirming responses, and canceling tasks. Its role is distinct from Nexus — Controller mediates payment escrow and task finalization, while Nexus is the registry and attempt coordinator.
You rarely call these functions directly — the ogpu.client wrappers
(publish_task, confirm_response, cancel_task) build the
params, resolve signers, and hand the result back as instance classes
or typed receipts.
publish_task
¶
publish_task(params: TaskParams, *, signer: Signer | None = None) -> Receipt
Call Controller.publishTask(params) to publish a new task.
The Controller escrows the payment from the caller, deploys a new
Task contract, and emits TaskPublished from Nexus. The returned
receipt carries that event log — decode it with
extract_task_address to get the new task's address.
This is the low-level entry point. client.publish_task is the
user-facing wrapper that builds the TaskParams from a
TaskInfo (including IPFS upload of the config payload) and
wraps the receipt in a Task instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
TaskParams
|
Fully-built |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
SourceInactiveError
|
If the target source is inactive. |
InsufficientBalanceError
|
If the client doesn't have enough vault balance to cover the task's payment. |
MissingSignerError
|
If no signer is available. |
confirm_response
¶
confirm_response(response_address: str, *, signer: Signer | None = None) -> Receipt
Call Controller.confirmResponse(response) to finalize a task.
Must be called by the task's client (or their authorized agent).
Flips the response to CONFIRMED, the parent task to
FINALIZED, and triggers payment release from the vault to the
winning provider.
Only needed for sources using MANUAL_CONFIRMATION delivery —
sources with FIRST_RESPONSE delivery finalize automatically on
the first submitResponse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response_address
|
str
|
Response contract address to confirm. |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotTaskOwnerError
|
Caller isn't the task's client. |
ResponseAlreadyConfirmedError
|
Response is already confirmed. |
ResponseNotFoundError
|
No Response contract at that address. |
cancel_task
¶
cancel_task(task_address: str, *, signer: Signer | None = None) -> Receipt
Call Controller.cancelTask(task) to cancel a task before any attempts.
Only works while the task is in NEW state — once any provider
has called attempt, cancel reverts with
TaskAlreadyFinalizedError (or similar). Must be called by the
task's client.
Successfully canceling a task releases the escrowed payment back
to the client and transitions the task to CANCELED.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_address
|
str
|
Task contract to cancel. |
required |
signer
|
Signer | None
|
Client signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
NotTaskOwnerError
|
Caller isn't the task's client. |
TaskAlreadyFinalizedError
|
Task is already past |
ogpu.protocol.terminal¶
Terminal contract — low-level wrappers.
The Terminal contract handles identity and delegation: master/provider pairing, agent authorization, and provider metadata (base and live data). It's the contract that answers "who is who?" on-chain.
This module mirrors the Terminal ABI 1:1. Higher-level wrappers live in
ogpu.client.set_agent (client-side agent setup), Provider /
Master instance classes (role-scoped operations), and ogpu.agent
(scheduler-role delegation).
set_agent
¶
set_agent(agent: str, value: bool, *, signer: Signer | None = None) -> Receipt
Call Terminal.setAgent(agent, value) to authorize or revoke an agent.
Only clients and masters can set agents. Providers cannot — the
Terminal.AgentSet event is only triggered by client or master
signers (see PRD N1 for the protocol rationale).
Once authorized (value=True), the agent's own key can sign
Nexus operations on behalf of the principal — the contract checks
isAgentOf(principal, msg.sender) to authorize calls. Revoke by
calling again with value=False, or use the revoke_agent
one-liner.
The default env-var fallback is CLIENT_PRIVATE_KEY — pass
signer= with a master key to set an agent for a master instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
str
|
Address to authorize/revoke as an agent. |
required |
value
|
bool
|
True to authorize, False to revoke. |
required |
signer
|
Signer | None
|
Client or master signer. Defaults to
|
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
InvalidSignerError
|
If |
MissingSignerError
|
If no signer is available. |
revoke_agent
¶
revoke_agent(agent: str, *, signer: Signer | None = None) -> Receipt
Revoke an agent's authorization.
Shorthand for set_agent(agent, False, signer=...). Follows the
same role/authorization rules — only the principal that authorized
the agent can revoke.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
str
|
Address to revoke. |
required |
signer
|
Signer | None
|
Client or master signer. Defaults to
|
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
announce_master
¶
announce_master(master_address: str, *, signer: Signer | None = None) -> Receipt
Call Terminal.announceMaster(master). Provider-role caller.
Second half of the master/provider pairing handshake. After the
master has called announceProvider to claim a provider, the
provider calls announceMaster to confirm the link from their
side. Both calls must succeed for masterOf(provider) to resolve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master_address
|
str
|
Master address the provider is pairing with. |
required |
signer
|
Signer | None
|
Provider signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
announce_provider
¶
announce_provider(provider: str, amount: int, *, signer: Signer | None = None) -> Receipt
Call Terminal.announceProvider(provider, amount). Master-role caller, payable.
First half of the master/provider pairing handshake. The master claims a provider and sends an initial funding amount in the same transaction — the amount gets credited to the provider's vault lockup so they become immediately eligible to register to sources.
Pairing is completed when the provider subsequently calls
announceMaster(master).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address being announced. |
required |
amount
|
int
|
Initial lockup amount in wei. Sent as |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
remove_provider
¶
remove_provider(provider: str, *, signer: Signer | None = None) -> Receipt
Call Terminal.removeProvider(provider). Master-role caller.
Breaks the pairing between a master and a provider. After the call,
masterOf(provider) no longer resolves and the provider is no
longer considered managed by that master.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to remove. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
remove_container
¶
remove_container(provider: str, source: str, *, signer: Signer | None = None) -> Receipt
Call Terminal.removeContainer(provider, source). Master-role caller.
Signals that a provider should stop running the source's container.
Used by the Provider App as a management signal — the container
itself is not uninstalled by this call; the Provider App reads the
RemoveContainer event and tears down the docker instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider whose container should stop. |
required |
source
|
str
|
Source whose container should stop. |
required |
signer
|
Signer | None
|
Master signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
set_default_agent_disabled
¶
set_default_agent_disabled(value: bool, *, signer: Signer | None = None) -> Receipt
Call Terminal.setDefaultAgentDisabled(value). Provider-role caller.
Opts a provider out of (or back into) default agent delegation. When disabled, the default scheduling agent (The Order) no longer dispatches tasks to this provider automatically — the provider becomes invisible to the built-in scheduler and has to be dispatched manually.
Like the base/live data setters, this uses msg.sender to
identify the provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
bool
|
True to disable the default agent, False to re-enable it. |
required |
signer
|
Signer | None
|
Provider signer. Falls back to |
None
|
Returns:
| Type | Description |
|---|---|
Receipt
|
|
get_master_of
¶
Return the master paired with a provider.
Returns the zero address if the provider is not currently paired with any master.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to look up. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The master's checksummed address, or the zero address if unpaired. |
get_provider_of
¶
Return the provider paired with a master.
The inverse lookup of get_master_of. Returns the zero address
if the master has not paired with any provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master
|
str
|
Master address to look up. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The provider's checksummed address, or the zero address if unpaired. |
get_base_data_of
¶
Return the current base data URL for a provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to look up. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The base data URL as stored on-chain, or an empty string if |
str
|
never set. |
get_live_data_of
¶
Return the current live data URL for a provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider address to look up. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The live data URL as stored on-chain, or an empty string if |
str
|
never set. |
is_master
¶
Return whether an address is registered as a master.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Address to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the address has been announced as a master by at least |
bool
|
one provider. |
is_provider
¶
Return whether an address is registered as a provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Address to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the address has been announced as a provider by at |
bool
|
least one master. |
is_agent_of
¶
Return whether agent is authorized to sign on behalf of account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account
|
str
|
The principal (client or master address). |
required |
agent
|
str
|
The candidate agent address. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if |
is_default_agent_disabled
¶
Return whether the provider opted out of default agent delegation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Provider address to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the provider has disabled the default scheduling agent. |
ogpu.protocol.vault¶
Vault contract — low-level wrappers.
The Vault contract holds all staked tokens: provider lockups that back source registration, client deposits that escrow task payment, and master funds that back their managed providers. Every role in the protocol eventually interacts with the vault to deposit, lock, unbond, or claim.
All write functions require signer= as an explicit keyword argument.
There is no env-var fallback — this is intentional (per decision
C1-vault in the PRD). Vault operations are role-agnostic (any account
can hold a balance), and falling back to a role-specific env var
invites accidents when multiple roles share a process. Always pass
signer= explicitly.
deposit
¶
deposit(account: str, amount: int, *, signer: Signer) -> Receipt
Call Vault.deposit(account) to credit amount to account.
The Solidity function is payable — account is the beneficiary
address being credited, amount is sent as msg.value. The
signer pays gas and funds the deposit from their own balance;
account receives the credit.
Typically signer and account are the same (you deposit for
yourself) but they don't have to be — a master can deposit on
behalf of a managed provider, and Provider.deposit_to_vault
uses this pattern to pre-fill account=self.address.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account
|
str
|
The address being credited (beneficiary). |
required |
amount
|
int
|
Amount to deposit in wei. Must match what the signer
is willing to send as |
required |
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
MissingSignerError
|
If no signer is passed (vault calls do not fall back to env vars). |
withdraw
¶
withdraw(amount: int, *, signer: Signer) -> Receipt
Call Vault.withdraw(amount) to pull funds out of the signer's balance.
Only works on the unlocked portion of the signer's vault balance —
locked or unbonding funds cannot be withdrawn until they return
to the liquid balance via claim.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
int
|
Amount to withdraw in wei. |
required |
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
InsufficientBalanceError
|
If the signer's unlocked balance is
less than |
lock
¶
lock(amount: int, *, signer: Signer) -> Receipt
Call Vault.lock(amount) to stake amount from the liquid balance.
Moves funds from the signer's liquid (available) balance into the
locked (staked) portion. Locked tokens are what make a provider
eligible to register to sources — Vault.minLockupPerSource is
checked on every Nexus.register call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
int
|
Amount to lock in wei. |
required |
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
InsufficientBalanceError
|
If the signer's liquid balance is
less than |
unbond
¶
unbond(amount: int, *, signer: Signer) -> Receipt
Call Vault.unbond(amount) to start unbonding amount of locked funds.
Begins the unbonding cooldown. Tokens move from the locked balance
into the unbonding bucket and stay there for Vault.UNBONDING_PERIOD
seconds. After the period elapses, claim moves them to the
liquid balance where they can be withdrawn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
int
|
Amount to begin unbonding, in wei. |
required |
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
InsufficientLockupError
|
If the signer's locked balance is less
than |
cancel_unbonding
¶
cancel_unbonding(*, signer: Signer) -> Receipt
Call Vault.cancelUnbonding() to abort a pending unbonding.
Moves any in-flight unbonding amount back to the locked balance. Useful when you change your mind before the cooldown elapses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
claim
¶
claim(*, signer: Signer) -> Receipt
Call Vault.claim() to move matured unbonding back to the liquid balance.
Only works after the unbonding period has fully elapsed (check
get_unbonding_timestamp vs. current time). After a successful
claim, the matured amount is available for withdraw.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer
|
Required. Hex key or |
required |
Returns:
| Type | Description |
|---|---|
Receipt
|
|
Raises:
| Type | Description |
|---|---|
UnbondingPeriodNotElapsedError
|
If the cooldown hasn't finished. |
get_balance_of
¶
Return the available (liquid) balance for an address, in wei.
The portion of the vault deposit that isn't locked, unbonding, or escrowed in a frozen payment. This is what can be withdrawn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Available balance in wei. |
get_lockup_of
¶
Return the locked (staked) amount for an address, in wei.
The portion backing source registrations. Can be moved to unbonding
via unbond.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Locked amount in wei. |
get_unbonding_of
¶
Return the amount currently unbonding for an address, in wei.
Tokens in the cooldown window between unbond and claim.
Zero once claim has been called for all matured unbondings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Unbonding amount in wei. |
get_unbonding_timestamp
¶
Return the unix timestamp when the current unbonding matures.
After this time, claim will succeed. Zero if no unbonding is
in progress.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Unix timestamp. |
get_total_earnings_of
¶
Return cumulative earnings for an address, in wei.
Monotonically-increasing counter of everything earned through completed tasks, regardless of whether it's still in the vault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Cumulative earnings in wei. |
get_frozen_payment
¶
Return the amount escrowed against pending task work, in wei.
Funds earmarked for pending attempts that haven't been confirmed or refunded yet. Not available for withdraw.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Frozen payment in wei. |
get_sanction_of
¶
Return the sanction amount for an address, in wei.
Protocol-level sanctions applied for misbehavior. Usually zero; non-zero values indicate the account has been penalized.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to query. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Sanction amount in wei. |
is_eligible
¶
Return whether an account is eligible for vault operations.
Accounts that fail this check cannot participate in protocol flows (registration, attempts, etc.). Usually a combination of lockup thresholds, whitelist status, and sanction state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if eligible. |
is_whitelisted
¶
Return whether an account is on the vault whitelist.
Used for protocol-level access control — whitelisted accounts may get preferential eligibility or sanction handling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Account to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if whitelisted. |
get_min_lockup_per_source
¶
Return Vault.MIN_LOCKUP_PER_SOURCE in wei.
The minimum lockup a provider must hold in the vault to register
to any source. Sources can enforce a higher minimum via their own
minAvailableLockup field, but this is the protocol-wide floor.
Returns:
| Type | Description |
|---|---|
int
|
Minimum lockup amount in wei. |
get_unbonding_period
¶
Return Vault.UNBONDING_PERIOD in seconds.
The cooldown window between unbond and claim. After
calling unbond, you must wait at least this many seconds
before you can claim.
Returns:
| Type | Description |
|---|---|
int
|
Unbonding period in seconds. |
Shared infrastructure¶
ogpu.protocol.TxExecutor
¶
TxExecutor(contract: Contract, function_name: str, args: tuple[Any, ...] = (), *, signer: LocalAccount, value: int = 0, context: str | None = None, max_retries: int = 3)
Single-shot transaction sender with retry, nonce, and revert decoding.
Every write operation in the SDK — publish_source, publish_task,
confirm_response, set_agent, vault.lock, etc. — constructs
a TxExecutor and calls .execute(). The executor handles:
- Nonce resolution via
NonceManager(with automatic retry on nonce collisions) - Transaction building via
contract.functions.X.build_transaction - Signing with the provided
LocalAccount - Broadcasting via
eth.send_raw_transaction - Confirmation via
wait_for_transaction_receipt - Retry on
nonce too low/replacement transaction underpricederrors, up tomax_retriesattempts - Revert decoding —
ContractLogicErroris passed throughdecode_revertand re-raised as a typedOGPUErrorsubclass - Receipt wrapping — returns a frozen
Receiptdataclass instead of the raw web3AttributeDict
You usually don't construct this class directly — use the module-level
functions (nexus.publish_source, controller.cancel_task, etc.)
or instance methods (task.cancel(), source.inactivate()) and
let them handle it.
Attributes:
| Name | Type | Description |
|---|---|---|
contract |
The |
|
function_name |
Name of the contract function to invoke. |
|
args |
Positional arguments to pass to the function. |
|
signer |
|
|
value |
ETH value (wei) to attach to the call. Only non-zero for
payable functions ( |
|
context |
Free-form string used in revert decoding for
disambiguating errors. Defaults to |
|
max_retries |
Maximum retry attempts on recoverable errors (nonce/underpriced). Defaults to 3. |
Example
execute
¶
execute() -> Receipt
Build, sign, broadcast, and wait for the transaction.
Runs the full retry/revert/receipt pipeline. On success returns
a Receipt with the tx hash, block number, gas used, and
decoded log list. On failure raises a typed OGPUError
subclass — never a raw ContractLogicError or web3 exception.
Returns:
| Type | Description |
|---|---|
Receipt
|
A |
Raises:
| Type | Description |
|---|---|
TxRevertError
|
Contract reverted with a reason not in
|
PermissionError
|
Contract reverted with a known permission
check ( |
StateError
|
Contract reverted in a state that doesn't allow
the operation ( |
VaultError
|
On-chain vault check failed
( |
NonceError
|
Nonce collision exhausted all retries. |
GasError
|
Underpriced transaction couldn't be recovered. |
ogpu.protocol.resolve_signer
¶
resolve_signer(signer: Signer | None, role: Role | None = None) -> LocalAccount
Normalize a signer argument to a LocalAccount.
The entry point every write operation in the SDK uses to turn a user-provided signer into a concrete account the transaction layer can sign with. Handles three cases:
- Already a
LocalAccount— returned unchanged. This is the path hardware wallets, KMS, and other external signer backends take: construct aLocalAccount-shaped object once, pass it in assigner=. - Hex string — parsed via
Account.from_key. Most common path. None— fall back to the role-specific env var. Ifroleis alsoNone(vault operations), raiseMissingSignerErrorimmediately.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signer
|
Signer | None
|
The user-provided signer, or |
required |
role
|
Role | None
|
Which role the operation is acting as — controls which
env var to read when |
None
|
Returns:
| Type | Description |
|---|---|
LocalAccount
|
A |
Raises:
| Type | Description |
|---|---|
MissingSignerError
|
If |
InvalidSignerError
|
If |
Example
import os
from eth_account import Account
from ogpu.protocol._signer import resolve_signer
from ogpu.types import Role
# Explicit hex string
acc = resolve_signer("0x" + "11" * 32, role=Role.CLIENT)
print(acc.address)
# '0x...'
# Pre-built LocalAccount (e.g. from a hardware wallet)
local = Account.from_key("0x" + "11" * 32)
resolve_signer(local, role=Role.CLIENT) is local
# True
# Env var fallback — reads CLIENT_PRIVATE_KEY
os.environ["CLIENT_PRIVATE_KEY"] = "0x" + "11" * 32
acc = resolve_signer(None, role=Role.CLIENT)
# Vault-style: no fallback allowed
resolve_signer(None, role=None) # raises MissingSignerError
ogpu.protocol.load_contract
¶
Load a web3.contract.Contract for an ABI + address.
Two modes:
- Singleton resolution (
address=None) — for the four protocol-level singletons (Nexus, Controller, Terminal, Vault), looks up the address fromChainConfig.CHAIN_CONTRACTSfor the current chain and wraps it with the matching ABI. - Explicit address — for instance-bound contracts (Source, Task, Response), pass the deployed contract address directly.
The ABI is loaded via ChainConfig.load_abi which caches the
parsed JSON per chain, so subsequent calls are cheap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
abi_name
|
str
|
ABI file basename without extension. Known singleton
ABIs: |
required |
address
|
str | None
|
Contract address. Omit for singleton ABIs. |
None
|
Returns:
| Type | Description |
|---|---|
Contract
|
A |
Contract
|
the requested ABI. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
FileNotFoundError
|
If the ABI file doesn't exist for the current chain. |