Supplier staking config

This document describes the configuration file used by the Supplier actor to submit a stake transaction, which is a prerequisite for it to provide RPC services on Pocket Network.

Copy-pasta example

You can find a fully featured example configuration at https://github.com/pokt-network/poktroll/tree/main/localnet/pocketd/config/supplier1_stake_config.yaml.

Gov Param References & Values

  • Supplier module governance params can be found here: https://dev.poktroll.com/protocol/governance/gov_params

  • Supplier module Beta parameter values: https://github.com/pokt-network/poktroll/blob/main/tools/scripts/params/bulk_params_beta/supplier_params.json

  • Supplier module Main parameter values: https://github.com/pokt-network/poktroll/blob/main/tools/scripts/params/bulk_params_main/supplier_params.json

Usage

The stake-supplier transaction submission command accepts a --config flag that points to a yaml configuration file that defines their staking configuration. This includes, but is not limited to, things like stake_amount, provided services, their respective advertised endpoints, etc.

The following is an example command of how to stake a supplier in a LocalNet environment.

pocketd tx supplier stake-supplier \
  --home=./pocket \
  --config ./stake_config.yaml \
  --keyring-backend test \
  --from supplier1 \
  --network=<network> #e.g. local, alpha, beta, main

Staking types

The Supplier staking command supports Custodial and Non-Custodial staking.

Custodial Staking

The owner of the Supplier is the same as the operator. This means the account that receives the rewards is the same as the one that signs the RelayResponses and submits claims and proofs.

Custodial staking is the simplest to set up and manage, as there is no need to manage multiple accounts. It is suitable for Suppliers that do not have concerns about using the private key of the staking or the rewarded account to operate the RelayMiner or update the Supplier's stake and services.

Non-Custodial Staking

The owner of the Supplier is different from the operator. This means the account that receives the rewards is different from the one signing the RelayResponses and submitting claims and proofs.

Non-custodial staking is suitable for Suppliers that want to separate the RelayMiner staking operations from the account that has custody over the staked funds, and in turn, the rewards being earned.

When staking a Supplier, the signing account specified with the --from flag (which may differ from the Supplier's owner or operator) will have its upokt balance deducted to stake the Supplier.

When unstaking a Supplier, the staked upokt will be returned to the owner_address account.

Configuration

owner_address

Scenario
Requirement

Always

Required

owner_address: <address>

The owner_address is the address of the account that owns the Supplier's staked funds, which will be transferred to this account's balance when the Supplier unstakes and finishes unbonding.

  • For custodial staking, the owner_address is the same as the operator_address.

  • For non-custodial staking, the owner_address MUST be different from the operator_address. This address receives the staked upokt when the Supplier is unstaked and finished unbonding.

  • The owner_address can only be changed with a stake message signed by the Supplier's owner account.

  • It is also used as the unique shareholder address for the Supplier if none of default_rev_share_percent or rev_share_percent is defined in the configuration file.

The owner_address does not identify a Supplier; multiple Suppliers can have the same owner_address.

operator_address

Scenario
Requirement

Always

Optional

operator_address: <address>

The operator_address is the address that identifies the Supplier. Its corresponding account is used for operational tasks such as signing RelayResponses, submitting Claims and Proofs as well as updating the Supplier's info (i.e. adding or removing services, increasing the stake amount, etc.)

  • The operator account can also be used to unstake the Supplier, which will cause the staked upokt to be sent to the owner_address after unbonding finishes.

  • If the operator_address is empty or not specified, the owner_address is used as the operator_address.

  • If the operator_address is the same as the owner_address, then the staking is custodial.

stake_amount

Scenario
Requirement

Initial Supplier Stake

Required

In/Decrease Supplier Stake

Required

Otherwise

Optional

stake_amount: <number>upokt

Defines the amount of upokt to stake for the Supplier account. This amount covers all the services defined in the services section.

default_rev_share_percent

Revenue Share Update Permissions (Operator-Only)

Revenue share addresses and percentages CAN ONLY be updated by the OPERATOR account.

In this example, both owner_address and operator_address are the same (custodial staking). This means the same account can update both stake amounts and revenue share configurations. For non-custodial staking, only the operator can modify revenue share settings.

Scenario
Requirement

Always

Optional

default_rev_share_percent:
  <shareholder_address_1>: <uint32>
  <shareholder_address_2>: <uint32>

default_rev_share_percent is an optional map that defines the default revenue share percentage for all the services that do not have their specific rev_share_percent entry defined.

This field is useful if the Supplier owner wants to set a default revenue share for all the service entries that do not provide one. This way, the operator does not have to repeat the same values for each service in the services section.

  • This map cannot be empty but can be omitted, in which case the default revenue share falls back to 100% of the rewards allocated to the Supplier's owner_address.

default_rev_share_percent configuration details

  • The shareholder_addresses MUST be valid Pocket addresses.

  • The revenue share values MUST be strictly positive floats with a maximum value of 100 and a total sum of 100 across all the shareholder_addresses.

  • If default_rev_share_percent is defined, then the owner_address of the Supplier MUST be explicitly defined in the map if they are to receive a share on the services that fall back to the default.

services

Scenario
Requirement

Initial Supplier Stake

Optional

Update Supplier Service Config(s)

Required

services:
  - service_id: <string>
    endpoints:
      - publicly_exposed_url: <protocol>://<hostname>:<port>
        rpc_type: <string>
    rev_share_percent:
      <shareholder_address>: <float>

services define the list of services that the Supplier wants to provide. It takes the form of a list of service objects. Each service object consists of a service_id and a list of endpoints that the Supplier will advertise on Pocket Network.

service_id

Scenario
Requirement

Always (per service)

Required

service_id is a string that uniquely identifies the service that the Supplier is providing. It MUST be 8 characters or less and composed of alphanumeric characters, underscores, and dashes only.

For example, it must match the regex ^[a-zA-Z0-9_-]{1,8}$, and spaces are disallowed.

endpoints

Scenario
Requirement

Always (per service)

Required

endpoints is a list of endpoint objects that the Supplier will advertise to the Pocket Network. Each endpoint object consists of a publicly_exposed_url and a rpc_type.

publicly_exposed_url

Scenario
Requirement

Always (per service)

Required

The publicly_exposed_url defines the endpoint for sending RelayRequests from the Pocket Network's Gateways and Applications. This endpoint is provided by the Supplier when staking, and is meant to point to (or route requests to) the Supplier's RelayMiner which in turn forwards these requests to the service node.

  • Example: When a Supplier stakes with a config file that contains https://ethereum-relayminer1.relayminers.com:443 as a publicly_exposed_url, this endpoint will be discoverable on the Pocket Network by Gateways and Applications, which can send it Ethereum RelayRequests to be processed by the Supplier's RelayMiner.

rpc_type

Scenario
Requirement

Always (per service)

Required

rpc_type is a string that defines the type of RPC service that the Supplier is providing.

Since services may support multiple types of RPCs (e.g., Ethereum has both JSON-RPC and WebSocket), a Supplier needs to specify which one it provides.

This allows Gateways and Applications to know which ones are supported by a given Supplier and select the appropriate one to send RelayRequests to.

The same url can be used for different rpc_types and it is up to the Gateway or Application to build the RelayRequest with the desired rpc_type.

For example, a Supplier can provide JSON_RPC and GRPC rpc_types to be served from the same endpoint:

endpoints:
  - publicly_exposed_url: http://service-host
    rpc_type: JSON_RPC
  - publicly_exposed_url: http://service-host
    rpc_type: GRPC

The rpc_type MUST be one of the supported types found here: https://github.com/pokt-network/poktroll/tree/main/pkg/relayer/config/types.go#L8

rev_share_percent

rev_share_percent is an optional map that defines the service's specific revenue share percentage. It overrides the default_rev_share_percent if defined for the service.

  • This map cannot be empty but can be omitted, in which case it falls back to the default_rev_share_percent top-level configuration entry.

rev_share_percent configuration details

  • The shareholder_addresses MUST be valid Pocket addresses.

  • The revenue share values MUST be strictly positive floats with a maximum value of 100 and a total sum of 100 across all the shareholder_addresses.

  • If default_rev_share_percent is defined, then the owner_address of the Supplier MUST be explicitly defined in the map if they are to receive a share on the services that fall back to the default.

Staking Modes

Session Boundary Behavior

All service configuration changes take effect at next session start to ensure current sessions remain stable and deterministic.

The pocketd tx stake-supplier command supports different operational modes depending on what you provide in the configuration file and which account signs the transaction.

1

Stake-only updates

If the services section is empty, only the stake amount changes. Service configuration history remains unchanged.

Example:

owner_address: $SUPPLIER_ADDR
operator_address: $SUPPLIER_ADDR
stake_amount: 1000069upokt
2

Service Configuration Updates

If the services section is provided, new configs are scheduled to activate at next session start.

Existing configs are either:

  • Replaced (if inactive and for the same service)

  • Marked for deactivation (if active or for different services)

Example:

owner_address: $SUPPLIER_ADDR
operator_address: $SUPPLIER_ADDR
services:
  - service_id: "eth"
    endpoints:
      - publicly_exposed_url: http://$EXTERNAL_IP:8545 # must be public
        rpc_type: JSON_RPC
3

Stake & Service Config Updates

Both stake and services can be updated in a single transaction.

Staking Permission Rules

  • Owner: Can update stake amount only (services section must be empty)

  • Operator: Can update stake amount, service configs, or both

Configuration Use Case Matrix

Action
Signer
Service Configs Provided?
Stake Amount Provided?
Result / Behavior

Initial Stake

Owner

❌ No

✅ Yes

✅ Stake escrowed, no services configured

✅ Yes

✅ Yes

❌ ERROR – owner may not provide service configs

❌ No / ✅ Yes

❌ No

❌ ERROR – stake amount must be provided

Operator

❌ No

✅ Yes

✅ Stake escrowed, no services configured

✅ Yes

✅ Yes

✅ Stake escrowed, services configured

❌ No / ✅ Yes

❌ No

❌ ERROR – stake amount must be provided

Upstake/Downstake

Owner

❌ No

✅ Yes

✅ Stake (un)escrowed, no change to service configs

✅ Yes

❌ No / ✅ Yes

❌ ERROR – owner may not provide service configs

Operator

❌ No

✅ Yes

✅ Stake (un)escrowed, no change to service configs

✅ Yes

✅ Yes

✅ Stake (un)escrowed, services updated

✅ Yes

❌ No

✅ Service configs updated

(End of document)

Was this helpful?