# Introduction

Arkeo is a decentralized, free-market network providing reliable and censorship-resistant access to blockchain data. Unlike traditional centralized data providers (e.g., Infura and Alchemy), Arkeo empowers users and data providers with trustless interactions, transparent pricing, and community-driven quality assurance. Arkeo aims to create a truly decentralized alternative for accessing blockchain data, enhancing web3 self-reliance and privacy.

## The Arkeo Solution

Arkeo's solution centers on three core concepts:

* Free-Market Data Providers: Anyone can operate as a data provider, offering blockchain data at prices determined by market competition, allowing for efficient price discovery.
* Trustless Payments: Users can securely pay providers using any IBC-enabled asset, with flexible micro-payments and options for subscription or usage-based contracts.
* Transparent On-Chain Reputation: Provider performance and reliability are publicly verifiable through on-chain data, facilitating informed choices based on provider reputation and quality.

## How Arkeo Works

Here's a concise breakdown of how Arkeo functions:

* Individuals operate full blockchain nodes and become data providers, setting their own pricing for data queries.
* Users establish contracts directly with data providers, depositing tokens on-chain. Contracts support both subscription and pay-as-you-go models.
* Each query is cryptographically verifiable and redeemable on-chain, ensuring trustless and transparent income for data providers.
* A portion (10%) of provider earnings contributes to the network reserve, which funds validator incentives through block rewards.
* Providers build transparent reputations through public on-chain metrics, including service quality, user retention, income stability, and provider longevity.

Arkeo ensures decentralized and dependable blockchain data access, positioning itself as the robust web3 alternative to centralized infrastructure providers.

Jump into [Start Here](/how-to-use-arkeo/start-here) to get a better understanding how Arkeo works and how you can be part of it.


# How To Use Arkeo


# Start Here

You already know what Arkeo is about, now let's dive deeper. Whether you're here to **share your data**, **consume APIs**, **secure the network**, or **build something brand new**, this is where you'll discover your path and begin your journey.

***

## Who Are You?

### Find your starting point below:

| I want to…                                     |                                                                                    |
| ---------------------------------------------- | ---------------------------------------------------------------------------------- |
| Earn by sharing data, APIs, or services        | [Become a Provider](/arkeo-for-data-providers/provider)                            |
| Access on-demand data, bandwidth, or APIs      | [Become a Subscriber](/arkeo-for-data-subscribers/setup)                           |
| Secure the Arkeo network and earn rewards      | [Become a Validator](/arkeo-for-validators/validators)                             |
| Index and server the Indexer API               | [Become an Indexer](/arkeo-for-indexers/indexers)                                  |
| Build apps or integrate Arkeo into my projects | [Build on Arkeo](https://github.com/arkeonetwork/docs/blob/main/build/builders.md) |

***

## What Can You Do With Arkeo?

* **Sell** API access, blockchain data, or bandwidth—and get paid instantly and trustlessly.
* **Use** pay-as-you-go or subscription access for any service or data source.
* **Build** decentralized analytics, dApps, or data markets easily, without intermediaries.
* **Integrate** any chain, any data, any business model.

***

## Why Arkeo?

* **No lock-in:** Switch between providers any time.
* **Pay-as-you-go:** Only pay for what you use.
* **Composable:** Any data, any service, any blockchain.
* **Secure:** On-chain, trustless settlement with zero credit risk.

***

## How Does It All Work?

Arkeo combines **off-chain authorization** (fast, flexible agreements) with **on-chain settlement** (secure, final payments). Providers and subscribers sign usage off-chain, and payments are enforced and settled trustlessly on-chain, creating a fully transparent metering ecosystem.

Understanding the "Arkeo way" is essential, as this innovation genuinely matters. Explore in-depth details here:

* [The Arkeo Process](/how-to-use-arkeo/overview)
* [What Data Does Arkeo Support?](https://github.com/arkeonetwork/docs/blob/main/howto/supported.md)
* [Contracts Explained](/how-to-use-arkeo/contracts)
* [Settlement and Getting Paid](/how-to-use-arkeo/settlement-explained)
* [Key Security and Usage](/how-to-use-arkeo/security)

***

## Still Not Sure Where to Begin?

Arkeo has one of the best communities around. Come join, ask questions, and get help—we're all here for you! [Join Arkeo's Discord](https://discord.gg/BfEHpm6uFc)

We're constantly updating our [FAQ](/faqs/faqs), so be sure to check there as well.


# How Does This All Work

Arkeo provides a robust, trustless payment model known as **"off-chain authorization with on-chain settlement"**. This model is efficient, scalable, and secure, leveraging blockchain technology while maintaining the speed and low cost of off-chain authorization.

![arkeo\_docs\_overview\_2.png](/files/pe67RgpMeXrmdTEq6FKP)

## Understanding the Arkeo Transaction Model

In the Arkeo ecosystem, clients sign claims containing essential details such as usage information and a unique nonce (number used once) off-chain, authorizing resource usage without immediate blockchain settlement. Providers periodically submit these claims to the Arkeo blockchain through “claim-contract-income” transactions, effectively turning off-chain authorizations into on-chain settlements. This approach significantly enhances efficiency and scalability, and understanding nonce sequencing, ensuring robust Sentinel operations, and leveraging Cosmos SDK capabilities allows providers to deliver secure, reliable, and trustless metered billing services.

This approach is commonly referred to in the blockchain industry as:

* **Meta-transaction billing**
* **Voucher-based payment channels**
* **Off-chain signature with on-chain settlement**
* **Trustless metered billing**

## Technical Details

### Claims and Nonces:

A "claim" is a signed message from a client authorizing a specific amount of resource usage. Each claim includes a nonce, ensuring uniqueness and preventing replay attacks. Providers must carefully track the nonce numbers and associated client signatures, as mismatches between client nonces and on-chain sequence numbers can result in claim rejections.

### Sentinel and Event Handling:

The Arkeo Sentinel application is a key component that manages off-chain authorization and on-chain settlement. Sentinel subscribes to blockchain events via WebSocket, typically utilizing Tendermint/CometBFT RPC, which is enabled by the Cosmos SDK. Sentinel listens specifically for events related to contract state changes and claim settlements.

* It's important to note:
  * **If Sentinel is interrupted or paused, it may miss critical blockchain events.**
  * **A missed event can result in a discrepancy between the internal state (ClaimStore) and the actual blockchain state.**
* Sentinel mitigates these risks by:
  * **Reindexing events upon restart or on-demand.**
  * **Periodically synchronizing with a fully synced Arkeo node.**

## How Cosmos SDK Enables This Model

The Arkeo transaction process is built on the Cosmos SDK, which inherently supports flexible transaction and state management systems. Cosmos SDK provides built-in support for:

* **Handling custom messages and transactions, such as the Arkeo-specific claim-contract-income transactions.**
* **Event-driven architecture, allowing Sentinel to effectively subscribe and react to on-chain activities via Tendermint's WebSocket event system.**
* **Security and nonce management, providing tools to ensure transaction uniqueness and replay protection.**

## Best Practices for Providers

For smooth operations within the Arkeo system, providers should:

* **Continuously monitor the client's latest nonce and signatures.**
* **Ensure Sentinel is always operational and connected to a synced Arkeo node.**
* **Immediately restart Sentinel if desynchronization is suspected.**
* **Implement periodic full-state refreshes or event replay mechanisms, particularly when reliability is paramount.**

## An Analogy:

### Here’s a simple analogy illustrating how Arkeo elegantly solves a timeless problem.

> **Tommy’s Neighborhood Lemonade Stand**
>
> Tommy opened a lemonade stand hoping for happy customers and quick profits—but things quickly went downhill. Customers complained about slow service, neighbors sometimes “forgot” to pay, and Tommy occasionally poured smaller cups by accident, creating mistrust. Soon, everyone was unhappy, and Tommy wasn’t making money.
>
> **Enter "Arkie"**
>
> Just when Tommy was ready to quit, he met Arkie, a friendly robot helper who changed everything. Arkie was precise, impartial, and efficient, exactly what Tommy needed.
>
> **Arkie’s Smart Lemonade System**
>
> * Neighborhood kids who wanted lemonade made an initial deposit with Arkie, creating mutual trust. Arkie holds the funds.
> * Kids could then freely pour lemonade whenever they wanted without stopping to pay each time. Arkie accurately counted every cup poured, never interrupting service.
> * At the end of each day, Arkie transparently calculated exactly how much lemonade each kid drank, automatically deducting the correct amount from their deposit. Everyone trusted Arkie’s fairness completely.
> * Any leftover funds were returned by Arkie to each kid, though naturally, they reinvested it right back into the next day's lemonade.
>
> **A Happy Ending**
>
> Suddenly, customers were happy again! Quick, fair service meant everyone got exactly what they paid for. Tommy began making consistent profits, eliminating complaints about mistrust or missed payments. Thanks to Arkie, Tommy’s lemonade stand thrived.
>
> **Why It Worked?**
>
> * **Fairness:** Precise tracking ensured honesty.
> * **Efficiency:** Fast, frictionless transactions kept customers happy.
> * **Cost Savings:** Kids paid only for what they drank—no waste, no frustration.
> * **Trust Restored:** Clear records eliminated doubts or disputes.


# What Data Do We Support?

Every Provider we onboard is unique, this means we are always growing the data offering we support. As each type of supported data is routed within the Arkeo blockchain, we have to upgrade and add services periodically.

Here is how you can view what's currently supported:

```
arkeod query arkeo all-services
```

```
http://localhost:1317/arkeo/services
```

## Supported Data Feedback

Need us to support some data, or a different type of data? Just let us know.

Join our Data-Providers channel on Discord: [Arkeo Discord, Data-Providers](https://discord.com/channels/1050100146626642052/1359893459854688439)


# Contracts Explained

Contracts in the Arkeo system represent agreements between service providers and their clients. These contracts define the terms of service, including payment terms, service duration, authorization methods, and rate limitations. They provide a structured and secure way to govern interactions, payments, and accountability between clients and providers.

Contracts play a critical role in Arkeo's decentralized transaction system by enabling off-chain authorization (client signatures and usage tracking) combined with on-chain settlement (payments processed through blockchain transactions). By structuring interactions this way, Arkeo ensures efficiency, transparency, and security while minimizing blockchain overhead.

## Contract Types Overview

### Arkeo supports two primary types of contracts:

* **Subscription (Fixed Duration)**: Suitable for fixed-term services, offering predictable billing and simple management.
* **Pay-As-You-Go (PAYG)**: Suitable for services charged per usage, offering flexibility and precise control over costs and resource use.

### Comparison of Contract Features

| Feature                    | Subscription (Less Strict) | Pay-As-You-Go (More Strict) |
| -------------------------- | -------------------------- | --------------------------- |
| Fixed Contract Duration    | ✅                          | ✅                           |
| Client Signatures Required | ❌                          | ✅                           |
| Rate Limiting              | ✅                          | ⚠️ (Optional)               |
| Prepaid Deposits           | ✅                          | ✅                           |
| Whitelist Management       | ✅                          | ⚠️ (Optional)               |
| Settlement Grace Period    | ✅                          | ✅                           |
| Deposit Reimbursement      | ❌                          | ✅                           |
| Strictness                 | ⚠️ (More Open)             | ⚠️ (More Strict)            |

## When to Use Each Contract Type

### Subscription (Fixed Duration)

Use this contract type when:

* Strict signatures is not desired.
* Whitelist authentication is acceptable.
* Service requirements and usage are predictable and stable.
* You prefer simple management with less frequent on-chain interactions.
* There is no need to track individual usage per transaction.

### Pay-As-You-Go (PAYG)

Use this contract type when:

* Services are highly variable or usage-based.
* Precise metering and billing per transaction are necessary.
* Enhanced control and accountability through client signatures are required.
* Better decentralization and security.


# Trustless Settlement

In Arkeo, settlement is a crucial phase where providers are paid for the claims they've accumulated. Providers collect client-signed claims (containing nonces and usage data) off-chain and periodically submit these claims to the Arkeo blockchain. This submission initiates the decentralized reconciliation and payment process.

## Importance of the Settlement Duration

The settlement duration is the specific time window (measured in blocks) allocated to providers for submitting claims after the contract has expired. It is critical because:

* **It ensures timely payments and maintains accurate accounting on the blockchain.**
* **It encourages providers to regularly reconcile and submit their claims, enhancing overall system efficiency and reliability.**

## How Providers Get Paid

Providers receive payments by submitting collected claims within the settlement duration to the Arkeo blockchain. Upon successful submission:

* **The blockchain verifies the claims, checking nonces, signatures, and contract terms.**
* **The decentralized settlement script on the blockchain reconciles these claims.**
* **Once verified, the claimed amount of tokens is automatically transferred from the locked contract deposit directly to the provider's account.**

## Decentralized Reconciliation and Settlement

The settlement script on the blockchain is invoked automatically when providers submit their claims. The process involves:

* **Validating nonce sequences and verifying client signatures.**
* **Ensuring submitted claims match previously agreed contract terms, including rates and allowed durations.**
* **Executing token transfers to settle payments transparently and securely.**

This decentralized mechanism eliminates the need for third-party intermediaries and ensures trustless transactions, making it a robust solution for metered billing.

## Consequences of Missing the Settlement Duration

If a provider fails to submit their claims within the allocated settlement window:

* **Claims become invalid and cannot be submitted afterward.**
* **Tokens reserved in the contract for these unsettled claims remain locked until the contract expires, after which any unclaimed tokens revert to the client's account.**
* **Providers lose potential earnings, underscoring the importance of timely and accurate settlement submissions.**

Providers are advised to implement reliable Sentinel services and maintain timely claim submissions to avoid missed settlements and associated revenue loss.


# Key Security

## Overview: Arkeo Key Management

Arkeo requires secure handling of cryptographic keys to sign nonce claims for off-chain authorization. Keys can be generated using the built-in arkeod command-line tool:

> arkeod keys add --keyring-backend test

**Using the keyring-backend of test avoids password prompts, enabling automated processes to operate continuously. However, this convenience demands that you implement strong server security controls.**

**This method of using the test backend for the key management can be referred to as a "Hot Wallet."**

## Using the signhere Utility for Signing Nonces

Arkeo’s signing tool, signhere, provides a simple and secure method for signing nonce claims off-chain. Typically, signhere is invoked within automation scripts as follows:

> signhere -u Client-Key -m Message

## Recommended Security Practices:

* **Limit server and filesystem access to only trusted, authorized entities.**
* **Use dedicated, securely hosted servers with strong firewall rules and limited SSH access for any automated signing scripts.**
* **Regularly audit your scripts and key access logs to detect any unusual activities quickly.**

## Advanced Key Options:

For users or organizations with higher security needs, consider more robust key management solutions, which offer additional layers of protection while allowing automated signing:

* **External Hardware Security Modules (HSM)**
  * Securely stores private keys off-server.
  * Allows automated, secure signatures via authenticated sessions.
* **Cloud-based Key Management Service (KMS)**
  * Managed solutions like AWS KMS, Azure Key Vault.
  * Integrates with automated signing scripts through API calls.
* **Dedicated Local Key Daemon**
  * Runs independently and securely holds keys in memory.
  * Provides automated signing without repeated password prompts.

For optimal automated operation and performance, Arkeo currently recommends the straightforward use of keyring-backend=test, protected by robust server security measures, or more advanced options listed above if additional security layers are desired.


# Arkeo for Validators


# Arkeo for Validators

Validators play a critical role in securing and maintaining the Arkeo blockchain. This concise guide outlines the essential steps to become and manage a validator.

## Prerequisites

* A secure, dedicated server with reliable uptime.
* Installed and synced arkeod full node.
* An Arkeo account funded with the required minimum staking tokens.

## Step-by-Step Setup

### Install Arkeo Node

Follow official guidelines to install and sync a full Arkeo node:

```
git clone https://github.com/arkeonetwork/arkeo.git
cd arkeo
make install
```

### Install Cosmovisor

**Build Cosmovisor**

```bash
go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@v1.0.0
```

**Place Cosmovisor in /usr/local/bin**

```
sudo cp $(which cosmovisor) /usr/local/bin/
```

### Create or Import Validator Key

```
arkeod keys add <validator-key-name> --keyring-backend file
```

### Prepare Cosmovisor Directory Structure

Assuming your Arkeo home is \~/.arkeo (default):

```
mkdir -p ~/.arkeo/cosmovisor/genesis/bin
mkdir -p ~/.arkeo/cosmovisor/upgrades
```

Copy the current arkeod binary to the genesis bin:

```
cp ~/go/bin/arkeod ~/cosmovisor/genesis/bin/
```

### Update Service to Use Cosmovisor

Create a systemd service for Cosmovisor:

```
# /etc/systemd/system/arkeod.service

[Unit]
Description=Arkeo Node (Cosmovisor)
After=network-online.target

[Service]
User=<ARKEO_USER>
ExecStart=/usr/local/bin/cosmovisor run start
Restart=always
RestartSec=10
LimitNOFILE=4096
Environment="DAEMON_NAME=arkeod"
Environment="DAEMON_HOME=/home/<ARKEO_USER>/.arkeo"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=false"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"

[Install]
WantedBy=multi-user.target
```

### Fund Validator Account

Ensure your validator account is funded sufficiently for staking and fees.

## Validator Creation

Create your validator on-chain:

```
arkeod tx staking create-validator \
--amount 1000000uarkeo \
--pubkey $(arkeod tendermint show-validator) \
--moniker "YourValidatorName" \
--chain-id arkeo-main-v1 \
--commission-rate "0.10" \
--commission-max-rate "0.20" \
--commission-max-change-rate "0.01" \
--min-self-delegation "1" \
--from <validator-key-name> \
--keyring-backend file \
--fees 200uarkeo \
-y
```

Adjust values as needed.

## Validator Management Commands

* Validator status:

```
arkeod query staking validator <validator-address>
```

* Delegate more tokens:

```
arkeod tx staking delegate <validator-address> 500000uarkeo --from <validator-key-name> --fees 200uarkeo -y
```

* Withdraw validator rewards:

```
arkeod tx distribution withdraw-rewards <validator-address> --from <validator-key-name> --fees 200uarkeo -y
```

## Cosmovisor Upgrade Flow

For chain upgrades, place the new arkeod binary under:

```
~/.arkeo/cosmovisor/upgrades/<UpgradeName>/bin/arkeod
```

Cosmovisor will auto-switch at the block height specified by the chain upgrade proposal.

## Best Practices

* Regularly monitor validator health and logs.
* Maintain sufficient funds to cover transaction fees and maintain stake.
* Keep your validator node updated and secured.


# Arkeo for Data-Providers


# Providers Intro

An **Arkeo Data Provider** is someone who helps keep critical blockchain and other valuable data accessible by sharing their infrastructure with the Arkeo network. By running nodes, APIs, or data endpoints and registering them in the Arkeo Open Data Marketplace, providers help developers and businesses reliably access data—and earn automatic, on-chain rewards for their efforts.

Simply put, providers are essential to keeping the Arkeo marketplace healthy, decentralized, and vibrant.

## Provider Overviews

### Provider & Subscriber Overview

In the Arkeo ecosystem, there are two main roles: **Providers** and **Subscribers**.

**Providers** set up and maintain their own infrastructure—such as Arkeo nodes, Sentinel proxies, data indexers, and APIs—making sure their endpoints are always available and responsive.

**Subscribers** are applications, developers, or businesses that need reliable access to blockchain data. They connect to provider services using clear, on-chain subscription contracts.

As a provider, you'll need to:

* Run a reliable Arkeo Node.
* Set up a Sentinel Proxy to handle subscriber requests securely.
* Offer an Indexer and API to organize blockchain data for easy querying.
* Automate billing and settlement scripts to smoothly receive payments.

Here's how everything fits together visually:

![providers\_overview\_1.png](/files/AcPrbu7A6ueWpVqdMXQb)

### Arkeo Open Data Marketplace

The Arkeo Open Data Marketplace connects providers and subscribers in a transparent, decentralized environment. Think of it as an open hub where subscribers easily find providers who offer the data they need, and providers are fairly rewarded for their reliability and quality.

Here's how it works:

* Providers register their data endpoints on-chain.
* Subscribers browse the marketplace to find providers that meet their needs.
* Smart contracts handle payments and enforce agreements automatically.

This setup encourages healthy competition and redundancy—meaning subscribers always have reliable options, and providers benefit directly from their high-quality service.

Here's the big-picture view:

![providers\_marketplace\_1.png](/files/1dh9cCW5dxVtaCbepxE6)

Providers Showing Open Marketplace Diagram

## What is Expected of You?

As an Arkeo Data Provider, you're expected to:

* **Stay Reliable:** Aim for high uptime and make sure subscribers can consistently access your endpoints.
* **Maintain Accurate Data:** Ensure your data stays current and accurate by regularly syncing your node and indexer.
* **Engage Actively:** Keep your endpoints visible and available in the marketplace, adapting as needed based on subscriber feedback.
* **Automate Payments:** Run your payment scripts and settlement tools so you're compensated automatically and effortlessly.

While perfection isn't expected, striving for reliability ensures subscribers trust your services, and trust is key to success in an open market.

## Provider Feedback

As a provider, you truly are at the heart of the Arkeo system, and your voice matters!

Join our community on Discord:

* Share your thoughts and suggestions.
* Help newcomers who might be facing challenges you've already conquered.
* Request features that you think could make Arkeo even better.

Your input helps shape the future of decentralized data, and we deeply appreciate your involvement.

<https://discord.com/channels/1050100146626642052/1359893459854688439>

## Let's Get Setup

Ready to become an Arkeo Data Provider? Great!

Your next step is setting up your infrastructure and joining the Arkeo Open Data Marketplace.

[Go to setup](/arkeo-for-data-subscribers/setup)

Join our Data-Providers channel on Discord: [Arkeo Discord, Data-Providers](https://discord.com/channels/1050100146626642052/1359893459854688439)


# Setting Up a Provider

This guide walks you through setting up your Arkeo Provider—from bonding your service on-chain, to configuring metadata, running your backend (sentinel), and automating settlement. You do not need to be a validator or run a full node to be a provider, though running your own node is strongly recommended for reliability.

## Before You Begin

### What You Need

* **Access to a synced Arkeo Node**
  * Host your own. (Recommended)
  * Connect with someone who has their ports open.
* **Arkeo Accounts:**
  * **Hot Wallet** (automated settlement key created with keyring-backend test).
  * (Optional) Secure cold storage account for larger funds.
* **Arkeo CLI Tools** installed (from GitHub).
* **Server** or reliable machine for running your backend (sentinel).
* **Recommended:** A full node for complete control over blockchain events and reliable settlements.

## Install Arkeo Tools

```
git clone https://github.com/arkeonetwork/arkeo.git  
cd arkeo  
make install  
make tools
```

This installs the arkeod CLI and related tools.

> **Best Practice:**\
> Although no full chain sync is required for basic operations, running your own node is highly recommended. Doing so ensures full control over blockchain events critical for timely settlements, avoiding reliance on third-party RPC services.

## Syncing or Accessing an Arkeo Node

For basic testing and setup, I think it's fine to use my provider, as the ports are open.

Some command line examples:

```
arkeod status --node tcp://provider1.innovationtheory.com:26657

ARKEOD_NODE="tcp://provider1.innovationtheory.com:26657" arkeod query arkeo all-services
```

Or the api reference

```
http://provider1.innovationtheory.com:1317/arkeo/services
```

> **Best Practice:**\
> If you want to do anything at a production level, you will want to have a synced arkeo Daemon running connected live to the Arkeo blockchain.

Follow the setup instructions:

* [Running a Node](https://github.com/arkeonetwork/arkeo?tab=readme-ov-file)
* [Validator Instructions](/arkeo-for-validators/validators)

Then you can use the most recent snapshot as a shortcut to syncing.

```
wget http://seed.innovationtheory.com:8080/arkeo_snapshot.tar.gz
```

Either way, make sure you have access to a synced Arkeo node before moving forward.

## Create a Hot Wallet (Automated Key)

Providers automate claim settlements using a dedicated "hot wallet":

```
arkeod keys add <provider-hot-wallet> --keyring-backend test
```

* Fund this wallet only with minimal amounts required for bonding and fees.

> Security Notice:
>
> * The test backend stores your keys unencrypted; use it only for automated scripts.
> * Never use this wallet for significant funds.

## Arkeo Supported Services

Use either of these services for a comprehensive reference mapping between service names and their numeric identifiers, as used within Arkeo.

```
arkeod query arkeo all-services
```

```
http://localhost:1317/arkeo/services
```

## Bond Your Provider Service On-Chain

Bonding stakes collateral and registers your service.

> No Validator privileges are required to be a Provider.
>
> Each time you run the BOND script, you will add in more tokens- so be aware that the bond will keep increasing.
>
> Just add a negative bond amount to UNBOND tokens, and UNBOND all tokens to remove your provider.
>
> The Bond is implemented so that providers have skin in the game and can be docked for bad behavior or performance. This functionality will be worked into the system soon.

Usage:

```
./provider_bond_4.sh arkeo-mainnet-fullnode
```

```
#!/bin/bash

if [ -z "$1" ]; then
  echo "Usage: $0 <SERVICE>"
  exit 1
fi
SERVICE="$1"

USER="Arkeo-Main-Validator-1"
BOND=100000000
KEYRING_BACKEND="test"
FEES="200uarkeo"

# Get raw public key
RAWPUBKEY=$(arkeod keys show "$USER" -p --keyring-backend="$KEYRING_BACKEND" | jq -r .key)

# Convert to Bech32 pubkey
PUBKEY=$(arkeod debug pubkey-raw $RAWPUBKEY | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

#echo "Using USER: $USER"
#echo "RAW PUBKEY: $RAWPUBKEY"
#echo "PUBKEY: $PUBKEY"
#echo "SERVICE: $SERVICE"
#echo "KEYRING_BACKEND: $KEYRING_BACKEND"
#echo "FEES: $FEES"
#echo "BOND: $BOND"

echo "Bonding provider service '$SERVICE'..."

# Bond the provider
arkeod tx arkeo bond-provider \
  --from="$USER" --fees="$FEES" --keyring-backend="$KEYRING_BACKEND" -b sync -y \
  "$PUBKEY" "$SERVICE" -- "$BOND"

if [ $? -ne 0 ]; then
  echo "Error: Provider bonding transaction failed."
  exit 1
else
  echo "Provider bonding transaction submitted successfully."
fi
```

## Configure Provider Metadata

Make your service discoverable and configure contract terms:

> The Nonce is cosmetic, and not required to be incremented like in Contracts.

Usage:

```
./provider_mod_4.sh arkeo-mainnet-fullnode 1 1 200uarkeo 200uarkeo
```

```
#!/bin/bash

# Usage check for required arguments
if [ "$#" -lt 5 ]; then
  echo "Usage: $0 <SERVICE> <METADATA_NONCE> <STATUS> <SUBSCRIPTION_RATES> <PAY_AS_YOU_GO_RATES>"
  exit 1
fi
SERVICE="$1"
METADATA_NONCE="$2"
STATUS="$3"
SUBSCRIPTION_RATES="$4"
PAY_AS_YOU_GO_RATES="$5"

KEY="Arkeo-Main-Validator-1"
SENTINEL_URI="http://127.0.0.1:3636/metadata.json"
MIN_CONTRACT_DUR=5
MAX_CONTRACT_DUR=432000
SETTLEMENT_DUR=100
KEYRING_BACKEND="test"
FEES="200uarkeo"

# Get raw public key
RAWPUBKEY=$(arkeod keys show "$KEY" -p --keyring-backend="$KEYRING_BACKEND" | jq -r .key)

# Convert to Bech32 pubkey
PUBKEY=$(arkeod debug pubkey-raw $RAWPUBKEY | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

echo "Modifying provider for service '$SERVICE'..."

# Mod the provider
arkeod tx arkeo mod-provider \
"$PUBKEY" \
"$SERVICE" \
"$SENTINEL_URI" \
"$METADATA_NONCE" \
"$STATUS" \
"$MIN_CONTRACT_DUR" \
"$MAX_CONTRACT_DUR" \
"$SUBSCRIPTION_RATES" \
"$PAY_AS_YOU_GO_RATES" \
"$SETTLEMENT_DUR" \
--from="$KEY" \
--fees="$FEES" \
--keyring-backend="$KEYRING_BACKEND" \
-y

if [ $? -ne 0 ]; then
  echo "Error: Provider modification transaction failed."
  exit 1
else
  echo "Provider modification transaction submitted successfully."
fi
```

## Provider Bond + Mod Looping Add/Update Script

This is a fast onboarding script to setup multiple providers at once, quickly.

```
#!/bin/bash

# Paths to your scripts (edit if needed)
BOND_SCRIPT="./provider_bond_4.sh"
MOD_SCRIPT="./provider_mod_4.sh"
SERVICES_API_URL="http://localhost:1317/arkeo/services"

# SERVICE_TYPES contains lines of: SERVICE METADATA_NONCE STATUS SUBSCRIPTION_RATES PAY_AS_YOU_GO_RATES
# Example:
#   "akash-mainnet-fullnode 1 1 200uarkeo 200uarkeo"
# Where:
#   SERVICE            = the service type string
#   METADATA_NONCE     = integer metadata nonce for this service
#   STATUS             = 1 (ONLINE) or 0 (OFFLINE)
#   SUBSCRIPTION_RATES = e.g., 200uarkeo
#   PAY_AS_YOU_GO_RATES= e.g., 200uarkeo

SERVICE_TYPES=(
  "btc-mainnet-fullnode 1 1 200uarkeo 200uarkeo"
)

for SERVICE_ENTRY in "${SERVICE_TYPES[@]}"; do
  set -- $SERVICE_ENTRY
  SERVICE="$1"
  METADATA_NONCE="$2"
  STATUS="$3"
  SUBSCRIPTION_RATES="$4"
  PAY_AS_YOU_GO_RATES="$5"

  echo ""

  BOND_OUTPUT=$($BOND_SCRIPT "$SERVICE")
  echo "$BOND_OUTPUT"
  echo ""
  BOND_TXHASH=$(echo "$BOND_OUTPUT" | grep "txhash:" | awk '{print $2}')
  if [ -n "$BOND_TXHASH" ]; then
    sleep 6
    echo "Querying bond transaction $BOND_TXHASH ..."
    arkeod query tx $BOND_TXHASH
  else
    echo "No transaction hash found for bond."
  fi
  if [ $? -ne 0 ]; then
    echo "Bonding failed for $SERVICE. Skipping modification."
    continue
  fi

  echo ""

  MOD_OUTPUT=$($MOD_SCRIPT "$SERVICE" $METADATA_NONCE $STATUS "$SUBSCRIPTION_RATES" "$PAY_AS_YOU_GO_RATES")
  echo "$MOD_OUTPUT"
  echo ""
  MOD_TXHASH=$(echo "$MOD_OUTPUT" | grep "txhash:" | awk '{print $2}')
  if [ -n "$MOD_TXHASH" ]; then
    sleep 6
    echo "Querying mod transaction $MOD_TXHASH ..."
    arkeod query tx $MOD_TXHASH
  else
    echo "No transaction hash found for mod."
  fi
  if [ $? -ne 0 ]; then
    echo "Modification failed for $SERVICE."
  fi

done

SERVICES_JSON=$(curl -s $SERVICES_API_URL)

# Now output YAML config block for all service types
echo ""
echo "services:"
for SERVICE_ENTRY in "${SERVICE_TYPES[@]}"; do
  set -- $SERVICE_ENTRY
  SERVICE="$1"
  CHAIN_TYPE=$(echo "$SERVICE" | cut -d'-' -f1)
  SERVICE_ID=$(echo "$SERVICES_JSON" | jq ".services[] | select(.name==\"$SERVICE\") | .service_id")
  echo "  - name: $SERVICE"
  echo "    id: $SERVICE_ID"
  echo "    type: $CHAIN_TYPE"
  echo "    rpc_url: http://127.0.0.1:26657"
  echo "    rpc_user:"
  echo "    rpc_pass:"
done
```

## Provider and Sentinel Configuration

Example sentinel\_config.yaml:

```
provider:
pubkey: "<your-bech32-pubkey>"
name: "My Arkeo Provider"

services:
- name: btc-mainnet-fullnode
  id: 10
  type: bitcoin
  rpc_url: http://localhost:8332
  rpc_user: "<rpc-username>"
  rpc_pass: "<rpc-password>"

api:
listen_addr: "0.0.0.0:3636"
```

## Run Sentinel

Create and enable sentinel.service with systemd:

```
[Unit]
Description=Arkeo Sentinel (Provider)
After=network-online.target

[Service]
User=<your-os-user>
WorkingDirectory=/home/<your-os-user>
ExecStart=/home/<your-os-user>/go/bin/sentinel --config /home/<your-os-user>/sentinel_config.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
Environment="CLAIM_STORE_LOCATION=/home/<your-os-user>/.arkeo/claims"
Environment="CONTRACT_CONFIG_STORE_LOCATION=/home/<your-os-user>/.arkeo/contract_configs"
Environment="DESCRIPTION=Arkeo Core Multi-Provider: Core Provider of Blockchain Nodes and Indexers."
Environment="EVENT_STREAM_HOST=127.0.0.1:26657"
Environment="FREE_RATE_LIMIT=10"
Environment="LOCATION=USA, West Coast"
Environment="LOG_LEVEL=debug"
Environment="MONIKER=arkeo-core-multi-provider"
Environment="PORT=3636"
Environment="PROVIDER_CONFIG_STORE_LOCATION=/home/<your-os-user>/.arkeo/provider_configs"
Environment="PROVIDER_HUB_URI=http://127.0.0.1:1317"
Environment="PROVIDER_PUBKEY=<your-bech32-pubkey>"
Environment="SOURCE_CHAIN=arkeo-main-v1"
Environment="WEBSITE=https://arkeo.network"

[Install]
WantedBy=multi-user.target
```

Activate the service:

```
sudo systemctl daemon-reload
sudo systemctl enable --now sentinel
```

## Automate Settlements

Set up your settlement script to use the "hot wallet" (keyring-backend test) for automated signing:

* Do not store hot wallet mnemonics in plain text or public repositories.
* Regularly monitor hot wallet transactions and balances.

## Monitoring and Verification

Check provider status:

```
arkeod query arkeo show-provider <your-bech32-pubkey>
```

Metadata API:

```
curl http://localhost:3636/metadata.json
```

Logs:

```
journalctl -u sentinel -f
```

## Additional Recommendations

* **Run your own full node** for reliable and timely event processing.
* Limit reliance on third-party RPC providers to maintain control over settlements.
* Rotate and audit hot wallet keys regularly.


# Getting Paid

As an Arkeo provider, ensuring timely settlements of your earned income is crucial. This guide outlines how to settle your claims, explains when payments occur, and highlights important considerations to ensure you receive payments without interruption.

## When Providers Get Paid

* Providers get paid at the end of each contract period.
* Payments are consistent across both Subscription and Pay-As-You-Go (PAYG) contracts.
* Providers must explicitly submit claims periodically throughout the contract's settlement duration.

> Important: If you fail to settle your claim income before the contract's settlement duration expires, you will permanently lose those funds.

## How to Settle Your Claims

### What this function does:

* **Set variables:** Defines important values like your provider key, keyring backend, API endpoint, and blockchain fees.
* **Retrieve provider account:** Fetches your blockchain account address.
* **Get open claims:** Queries your provider API for claims that are ready for settlement.
* **Process claims:** For each open claim:
  * Extracts the contract ID, nonce, and signature.
  * Queries your blockchain account to determine the correct transaction sequence.
  * Submits the claim to the blockchain using arkeod tx arkeo claim-contract-income, specifying the necessary parameters.
* **Sleep interval:** Adds a short delay between transactions to ensure stability.

Replace the placeholder values (like your-provider-key) with your actual details.

```
#!/bin/bash
set -e

PROVIDER_KEY="your-provider-key"
KEYRING_BACKEND="test"
PROVIDER_API="http://127.0.0.1:3636"
CHAIN_ID="arkeo-main-v1"
FEES="200uarkeo"

PROVIDER_ACCOUNT=$(arkeod keys show "$PROVIDER_KEY" --bech acc --keyring-backend "$KEYRING_BACKEND" --address)

OPEN_CLAIMS=$(curl -sL "$PROVIDER_API/open-claims" | jq -c '.[] | select(.claimed == false)')

if [[ -z "$OPEN_CLAIMS" ]]; then
echo "No open claims to process."
exit 0
fi

echo "$OPEN_CLAIMS" | while read -r CLAIM; do
contract_id=$(echo "$CLAIM" | jq -r '.contract_id')
nonce=$(echo "$CLAIM" | jq -r '.nonce')
signature=$(echo "$CLAIM" | jq -r '.signature')

    RAW_ACCOUNT=$(arkeod query auth account "$PROVIDER_ACCOUNT" --output json)
    CURRENT_SEQ=$(echo "$RAW_ACCOUNT" | jq -r '.account.sequence // .account.value.sequence // .account.base_account.sequence // .account.base_account.value.sequence' 2>/dev/null)

    if [ -z "$CURRENT_SEQ" ]; then
      echo "ERROR: Failed to get current sequence."
      exit 1
    fi

    echo "Submitting claim for contract $contract_id, nonce $nonce."
    arkeod tx arkeo claim-contract-income "$contract_id" "$nonce" "$signature" nil \
      --from "$PROVIDER_KEY" \
      --keyring-backend "$KEYRING_BACKEND" \
      -b sync \
      --sequence "$CURRENT_SEQ" -y

    sleep 2
    echo "Claim submitted."
done
```

## Recommended Claim Submission Frequency

* Run this following script on a cron to periodically submit claims for Arkeo blockchain settlement.
* This script should be run regularly (e.g., hourly or daily), ensuring claims are always settled within your contract's defined settlement duration.
* Frequent submissions help reduce the risk of losing income due to missed settlements.

## Security and Operational Best Practices

* Use a dedicated hot wallet (keyring-backend test) specifically for automated scripts, funded minimally.
* Regularly monitor claim submissions and your provider account balance.
* Keep logs and review settlement script outputs periodically.

## Troubleshooting and Monitoring

Check recent claim statuses and account balances:

```
arkeod query bank balances <your-provider-account-address>
```

Review settlement logs regularly to detect and address issues promptly.


# Ongoing Management

This document outlines management tasks for maintaining your Arkeo provider services, including querying your provider details and understanding the service enum mappings used in Arkeo.

## Querying Provider Details

To view detailed information about your registered provider, filter by your provider public key (pub\_key) using the following command:

```
arkeod query arkeo list-providers --output json | jq '.provider[] | select(.pub_key=="<your-provider-pubkey>")'
```

## Listing Active Contracts by Provider

To list all active contracts associated with your provider public key (contracts where settlement height is 0), use the following command:

```
arkeod query arkeo list-contracts --output json | jq '.contract[] | select(.provider=="<your-provider-pubkey>" and .settlement_height=="0")'
```

## Best Practices

* Regularly query your provider details to ensure your service information is current and accurate.
* Periodically check your active contracts to manage settlements effectively.
* Understand the service mapping clearly when adding or updating your provider offerings.
* Regular monitoring and periodic verification ensure maximum reliability and client satisfaction.

## Arkeo Supported Services

Use either of these services for a comprehensive reference mapping between service names and their numeric identifiers, as used within Arkeo.

```
arkeod query arkeo all-services
```

```
http://localhost:1317/arkeo/services
```


# Arkeo for Data-Subscribers


# Subscribers Setup

Connecting securely and reliably to Arkeo provider services requires thoughtful initial setup. This guide covers key considerations, security practices, and the provider discovery process to ensure you get started correctly.

## Initial Considerations and Security

### Key Security

* Always safeguard your private keys; never share them publicly.
* For automation and script interactions, use a dedicated keyring backend (`test`). Refer to the [Security Documentation](/arkeo-for-data-subscribers/setup) for details on safe key management practices.
* Regularly back up your keys securely to prevent data loss.

## Selecting the Right Service

Determine clearly which service type you require and confirm its numeric identifier from the service mapping chart below. Correct service selection ensures compatibility and reliability.

### Provider Discovery

Use the following command to find reliable providers offering your chosen service type:

```
arkeod query arkeo list-providers --output json | \
jq '.provider[] | select(.status=="ONLINE" and .service==<service-number>)'
```

Replace with the numeric identifier corresponding to your chosen service.

### Provider Evaluation

Before choosing a provider, carefully check:

* Provider metadata (accessible via their advertised metadata\_uri).
* Contract terms such as rate, minimum duration, and settlement details.
* Provider reputation and reliability based on community feedback.

## Create a Hot Wallet (Automated Key)

Providers automate claim settlements using a dedicated "hot wallet":

```
arkeod keys add <provider-hot-wallet> --keyring-backend test
```

* Fund this wallet only with minimal amounts required for bonding and fees.

> Security Notice:
>
> * The test backend stores your keys unencrypted; use it only for automated scripts.
> * Never use this wallet for significant funds.

## Arkeo Supported Services

Use either of these services for a comprehensive reference mapping between service names and their numeric identifiers, as used within Arkeo.

```
arkeod query arkeo all-services
```

```
http://localhost:1317/arkeo/services
```

## More Information:

Once you’ve completed the initial subscriber setup, explore these additional documentation pages to fully prepare and manage your Arkeo contracts:

* [Subscription Contract Setup](/arkeo-for-data-subscribers/setup-subscription)
  * Step-by-step instructions to create, configure, test, and close predictable and consistent subscription contracts.
* [Pay-As-You-Go (PAYG) Contract Setup](/arkeo-for-data-subscribers/setup-payg)
  * Guide for flexible, usage-based contract creation and management, perfect for dynamic usage patterns.
* [Contract Management](/arkeo-for-data-subscribers/contract-management)
  * Detailed guidance and scripts to automate and ensure uninterrupted service through proactive contract handling.
* [Monitoring](/arkeo-for-data-subscribers/monitoring)
  * Best practices and quick commands to keep an eye on service health, active contracts, and your hot wallet balances.

Utilizing these resources ensures robust, secure, and continuous access to Arkeo provider services.


# Subscription Contract Setup

Subscription contracts on Arkeo provide clients with predictable, recurring access to provider services for a set period and rate. This model is ideal when you require continuous service without having to sign every usage event. As a subscriber, you pay upfront for a specified duration, during which you’re entitled to the provider’s resources within the agreed query-per-minute (QPM) and rate limits.

### Be mindful:

* **Subscription contracts are prepaid:** Your deposit covers the entire contract duration and rate; unused time or quota is not refundable if the contract is closed early.
* **Rate limits apply:** Exceeding the allowed QPM may result in throttling or denied service for the remainder of the interval.
* **Contract duration is fixed:** Extensions or changes require opening a new contract.
* **Closure triggers settlement:** Closing a contract early will immediately settle usage and may forfeit any remaining value.

The following sections walk you through opening, configuring, monitoring, testing, and closing a subscription contract on Arkeo.

## Opening a Subscription Contract

Before you can use a provider’s resources on Arkeo, you need to open a subscription contract. This script prepares all required contract parameters—including the provider’s public key, the chosen service, deposit, contract duration, rate, and authorization options—and submits a transaction to open the contract on-chain. Running this script sets up your access and guarantees your service level for the defined duration, provided you stay within the contract’s rate and query-per-minute limits.

```
#!/bin/bash

# Configuration: Set these values appropriately
PROVIDER_API="127.0.0.1:26657"                   # RPC endpoint for submitting tx
PROVIDER_PUBKEY="<provider-bech32-pubkey>"       # Provider's registered pubkey
SERVICE="<service-name>"                         # Service string as advertised by provider
CONTRACT_TYPE=0                                  # 0 = Subscription, 1 = Pay-As-You-Go
CONTRACT_DEPOSIT=172800000                       # Deposit (tokens); for subscriptions: rate * duration
CONTRACT_DURATION=86400                          # Duration (in blocks)
CONTRACT_RATE="200uarkeo"                        # Must match provider's published rate
CONTRACT_SETTLEMENT=1000                         # Settlement window (blocks)
CONTRACT_QPM=10                                  # Queries per minute (QPM)
CONTRACT_AUTH=1                                  # 0 = STRICT, 1 = OPEN
CONTRACT_DELEGATE=""                             # (Optional) Delegate pubkey
CLIENT_KEY="<your-client-key>"                   # Your local key name in arkeod keyring
KEYRING_BACKEND="test"                           # Or \"os\" / \"file\" for better security
FEES="200uarkeo"                                 # Transaction fee

# --- Get client pubkey in bech32 format ---
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$KEYRING_BACKEND" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

echo "Provider pubkey: $PROVIDER_PUBKEY"
echo "Client pubkey:   $CLIENT_PUBKEY"

# --- Submit transaction to open the contract ---
arkeod tx arkeo open-contract \
"$PROVIDER_PUBKEY" \
"$SERVICE" \
"$CLIENT_PUBKEY" \
"$CONTRACT_TYPE" \
"$CONTRACT_DEPOSIT" \
"$CONTRACT_DURATION" \
"$CONTRACT_RATE" \
"$CONTRACT_QPM" \
"$CONTRACT_SETTLEMENT" \
"$CONTRACT_AUTH" \
"$CONTRACT_DELEGATE" \
--from="$CLIENT_KEY" \
--fees="$FEES" \
--keyring-backend="$KEYRING_BACKEND" \
--node tcp://$PROVIDER_API \
-y
```

Note:

* Replace all placeholder values (inside <...>) with real details for your use case.
* Always check the provider’s advertised service name and rates before creating a contract.
* Make sure your keyring contains the correct client key and has enough balance for the deposit and fees.

## Configuring a Subscription Contract

After you have opened a subscription contract, you may want to fetch its details or update access configurations, such as IP whitelists or rate limits, using the provider’s Sentinel API. The script below securely signs API requests with your client key, retrieves contract information, and then updates the contract configuration. This is useful for enforcing access controls and customizing allowed usage from your end.

```
#!/bin/bash

# Configuration
PROVIDER_API="http://127.0.0.1:3636"
CONTRACT_ID=1
USER_KEY="your-client-key"
KEYRING_BACKEND="test"
CLIENT_KEY="your-client-key"
CLIENT_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --bech acc --keyring-backend="$KEYRING_BACKEND" --address)

# --- Sign and GET contract info ---
NONCE_GET=$(date +%s)
MSG_GET="$CONTRACT_ID:$NONCE_GET:"
SIG_GET=$(signhere -u "$USER_KEY" -m "$MSG_GET" | tail -n 1)
ARKAUTH_GET="$CONTRACT_ID:$NONCE_GET:$SIG_GET"
API_URL_GET="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_GET"

# Fetch contract details
curl -s "$API_URL_GET" | jq .

# --- Wait to ensure a unique POST nonce ---
sleep 1

# --- Sign POST request to update config ---
NONCE_POST=$(date +%s)
MSG_POST="$CONTRACT_ID:$NONCE_POST:"
SIG_POST=$(signhere -u "$USER_KEY" -m "$MSG_POST" | tail -n 1)
ARKAUTH_POST="$CONTRACT_ID:$NONCE_POST:$SIG_POST"
API_URL_POST="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_POST"

# Prepare whitelist and config JSON (edit as needed)
read -r -d '' WHITELIST_JSON <<EOF
{
  "white_listed_ip_addresses": [
    "127.0.0.1",
    "192.168.0.1"
  ],
  "per_user_rate_limit": 1000,
  "cors": {
    "allow_origins": ["*"],
    "allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "allow_headers": ["*"]
  }
}
EOF

# --- POST updated contract configuration ---
curl -X POST -H "Content-Type: application/json" -d "$WHITELIST_JSON" "$API_URL_POST"
echo
```

Notes:

* Replace placeholder values (like , , ) with your actual details.
* The first half of the script securely fetches contract info; the second half (optional) shows how to update settings if needed.
* Never commit your private keys or sensitive environment variables to source control.
* Only authorized users (contract owner or delegate) can view or change the contract’s config.

## View Subscription Contract

To effectively manage your subscription contract, you may need to view its current status, usage, and configuration as stored by the provider. This script securely fetches up-to-date information about your contract, using a signed request to authenticate your access. Running this ensures you can monitor your claims, see allowed limits, and troubleshoot or audit your subscription as needed.

```
#!/bin/bash

# Configuration (replace values with your actual details)
PROVIDER_API="http://127.0.0.1:3636"       # Provider's Sentinel API endpoint
CONTRACT_ID=1                              # Your contract ID
USER_KEY="your-client-key"                 # Your local key name
KEYRING_BACKEND="test"                     # Keyring backend (use 'file' or 'os' for production)

# Fetch your public address
CLIENT_PUBKEY=$(arkeod keys show "$USER_KEY" --bech acc --keyring-backend="$KEYRING_BACKEND" --address)
echo "Client Pubkey: $CLIENT_PUBKEY"

# Display claims endpoint
CLAIMS_API="$PROVIDER_API/claims?contract_id=$CONTRACT_ID&client=$CLIENT_PUBKEY"
echo "Claims API: $CLAIMS_API"

# Prepare signed nonce for authenticated GET request
NONCE_GET=$(date +%s)
MSG_GET="$CONTRACT_ID:$NONCE_GET:"
SIG_GET=$(signhere -u "$USER_KEY" -m "$MSG_GET" | tail -n 1)
ARKAUTH_GET="$CONTRACT_ID:$NONCE_GET:$SIG_GET"
API_URL_GET="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_GET"

echo "GET Auth: $ARKAUTH_GET"
echo "GET URL: $API_URL_GET"

# Retrieve contract info from the provider's API
curl -s "$API_URL_GET" | jq .
```

Note:

* Replace your-client-key-name and CONTRACT\_ID with your actual values.
* Only use keyring-backend test for local/testing environments; use a secure backend in production.

## Test Subscription Contract

Before running this script, ensure your subscription contract is active and the provider’s API endpoint is accessible.

This script is designed to simulate usage of your subscription contract by sending repeated requests to the provider’s API endpoint. It helps you verify whether the contract’s rate limits (queries per minute) are enforced and lets you observe the provider’s responses to typical usage patterns. This is useful for troubleshooting, auditing, and making sure you do not get unexpectedly throttled during actual use.

```
#!/bin/bash

# Usage:
#   ./test_subscription.sh [RATE_LIMIT] [INTERVAL] [TOTAL_REQUESTS]
#   RATE_LIMIT:     max requests per minute (default: 10)
#   INTERVAL:       seconds between requests (default: calculated to slightly exceed limit)
#   TOTAL_REQUESTS: number of requests to make (default: 30)

CONTRACT_ID=1
ENDPOINT="http://127.0.0.1:3636/btc-mainnet-fullnode?arkauth=$CONTRACT_ID"
DATA='{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}'
HEADERS="Content-Type: text/plain"

RATE_LIMIT="${1:-10}"
TOTAL_REQUESTS="${3:-30}"

# Calculate interval: if not specified, use 10% slower than max QPM to avoid 429 errors
if [[ -n "$2" ]]; then
    INTERVAL="$2"
else
    INTERVAL=$(echo "scale=2; 60/$RATE_LIMIT * 1.1" | bc)
fi

echo "Load Test (Subscription): Requests=$TOTAL_REQUESTS, QPM=$RATE_LIMIT, Interval=${INTERVAL}s"
echo "Contract: $CONTRACT_ID"
echo "Endpoint: $ENDPOINT"
echo "Data: $DATA"
echo

success=0
rate_limited=0
other=0

start_time=$(date +%s)

for i in $(seq 1 $TOTAL_REQUESTS); do
    loop_start=$(date +%s.%N)
    printf "Request #%d... " "$i"

    response=$(curl -s -w "\n%{http_code}" -X POST --data-binary "$DATA" -H "$HEADERS" "$ENDPOINT")
    http_code=$(echo "$response" | tail -n1)
    http_body=$(echo "$response" | sed '$d')

    if [ "$http_code" == "200" ]; then
        echo "✅ 200 OK"
        ((success++))
    elif [ "$http_code" == "403" ] || [ "$http_code" == "429" ]; then
        echo "🚫 Rate Limited ($http_code)"
        ((rate_limited++))
    else
        echo "❓ $http_code"
        ((other++))
    fi

    loop_end=$(date +%s.%N)
    elapsed=$(echo "$loop_end - $loop_start" | bc)

    sleep_time=$(echo "$INTERVAL - $elapsed" | bc)
    if (( $(echo "$sleep_time > 0" | bc -l) )); then
        sleep $sleep_time
    fi
done

end_time=$(date +%s)
duration=$((end_time - start_time))
if [ "$duration" -gt 0 ]; then
    qpm=$((success * 60 / duration))
else
    qpm=0
fi

echo
echo "Total Requests:    $TOTAL_REQUESTS"
echo "Duration:          $duration seconds"
echo "Successful (200):  $success"
echo "Rate Limited:      $rate_limited"
echo "Other Errors:      $other"
echo "Approx. QPM:       $qpm"
```

* Adjust CONTRACT\_ID and ENDPOINT to match your actual provider and contract.
* The script prints a summary at the end to help you understand your contract’s rate-limiting behavior.

## Close Subscription Contract

Closing a subscription contract is the process of formally ending your agreement with the provider on the Arkeo blockchain. This is important when you no longer need the service or want to finalize and settle usage up to the current point. Closing the contract will stop further access, trigger settlement (so the provider can get paid), and, in some cases, release any refundable deposit. Always ensure you’re ready to stop the service, as this action is final for the contract period.

```
#!/bin/bash

# Set variables for the provider API endpoint, contract ID, client key, and keyring backend.
PROVIDER_API="127.0.0.1:26657"
CONTRACT_ID=<your-contract-id>
CLIENT_KEY="<your-client-key-name>"
KEYRING_BACKEND="test"
FEES="200uarkeo"

# Fetch your client Bech32 public key for contract closure.
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$KEYRING_BACKEND" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

echo "Client pubkey: $CLIENT_PUBKEY"

# Submit the transaction to close the subscription contract.
arkeod tx arkeo close-contract \
"$CONTRACT_ID" \
"$CLIENT_PUBKEY" \
--from="$CLIENT_KEY" \
--fees="$FEES" \
--keyring-backend="$KEYRING_BACKEND" \
--node tcp://$PROVIDER_API \
-y
```

Notes:

* Replace and with your actual contract ID and local key name.
* Ensure your keyring backend and node address match your setup (for production, do not use "test" for keyring backend).
* After closing, you can verify contract status on-chain using arkeod query arkeo show-contract .


# Pay-As-You-Go Contract Setup

Pay-As-You-Go (PAYG) contracts are designed for users who need flexible, usage-based access to provider services on Arkeo. Unlike subscriptions, PAYG contracts allow you to pay only for what you use—ideal for testing, unpredictable workloads, or low-frequency usage where committing to a fixed period isn’t efficient. With PAYG, each individual request or action is explicitly authorized with a digital signature, ensuring you remain in control of every transaction.

Be mindful:

* Each usage must be authorized: You (or your delegate) must sign every usage event, and only authorized claims can be settled and paid out.
* Settlement deadlines matter: If the provider does not settle claims within the contract’s settlement duration, those claims are lost and you won’t be charged for them—but the provider loses payment for those events.
* Deposit and rate limits: Running out of deposit or exceeding configured rate limits will pause your access until you top up or adjust contract terms.
* Nonces for security: Every usage claim must include a unique nonce to prevent replay attacks.

The sections below walk you through creating, using, monitoring, and closing PAYG contracts on Arkeo.

## Create Pay-As-You-Go (PAYG) Contract

To start using a provider’s service on a pay-as-you-go basis, you first need to open a PAYG contract on-chain. This script creates a contract specifying the provider, service, deposit, duration, rate, and any usage limits. Opening the contract is necessary before you can authorize and pay for individual usage events. Always check provider terms (rate, service string, etc.) before running this step to ensure your contract will be accepted.

```
#!/bin/bash

# Variables (update these as needed)
PROVIDER_PUBKEY="<provider-pubkey>"           # Provider's registered public key
PROVIDER_API="<provider-api-host>:26657"      # Provider's arkeod API endpoint
SERVICE="<service-name>"                      # Service string advertised by provider
CONTRACT_TYPE=1                               # 1 = Pay-As-You-Go
CONTRACT_DEPOSIT=<deposit-amount>             # Number of tokens to deposit
CONTRACT_DURATION=<duration-in-blocks>        # Contract duration
CONTRACT_RATE="<rate>"                        # Example: "200uarkeo"
CONTRACT_SETTLEMENT=<settlement-duration>     # Settlement window (blocks)
CONTRACT_QPM=<qpm>                            # Queries per minute limit
CONTRACT_AUTH=0                               # 0 = STRICT, 1 = OPEN
CONTRACT_DELEGATE=""                          # Delegate pubkey (optional)
CLIENT_KEY="<your-client-key>"                # Your client key name (local keyring)
KEYRING_BACKEND="test"                        # Use "file" or "os" for production
FEES="200uarkeo"                              # Transaction fee

# --- Get your client pubkey in Bech32 format ---
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$KEYRING_BACKEND" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

echo "Provider pubkey: $PROVIDER_PUBKEY"
echo "Client pubkey:   $CLIENT_PUBKEY"

# --- Open PAYG contract on-chain ---
arkeod tx arkeo open-contract \
  "$PROVIDER_PUBKEY" \
  "$SERVICE" \
  "$CLIENT_PUBKEY" \
  "$CONTRACT_TYPE" \
  "$CONTRACT_DEPOSIT" \
  "$CONTRACT_DURATION" \
  "$CONTRACT_RATE" \
  "$CONTRACT_QPM" \
  "$CONTRACT_SETTLEMENT" \
  "$CONTRACT_AUTH" \
  "$CONTRACT_DELEGATE" \
  --from="$CLIENT_KEY" \
  --fees="$FEES" \
  --keyring-backend="$KEYRING_BACKEND" \
  --node tcp://$PROVIDER_API \
  -y
```

Notes:

* Replace all variables in angle brackets (<...>) with your specific values.
* Make sure your contract terms match the provider’s advertised service and expected rate.
* Use a secure keyring backend (file or os) for production environments, not test.
* Check the result of the transaction to confirm the contract was created successfully.

## Config Pay-As-You-Go (PAYG) Contract

This script allows you to fetch information about your active PAYG contract and then update its configuration—such as whitelist IP addresses, rate limits, or CORS settings- via the provider’s API. For security, every management action must be authorized with a signed message (using your contract and a unique nonce), ensuring that only the contract holder or delegate can make changes.

```
#!/bin/bash

# Set provider API endpoint and contract details
PROVIDER_API="http://127.0.0.1:3636"
CONTRACT_ID=<your-contract-id>
USER_KEY="<your-key-name>"
KEYRING_BACKEND="test"
CLIENT_KEY="<your-key-name>"
CLIENT_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --bech acc --keyring-backend="$KEYRING_BACKEND" --address)

# Sign GET contract info
NONCE_GET=$(date +%s)
MSG_GET="$CONTRACT_ID:$NONCE_GET:"
SIG_GET=$(signhere -u "$USER_KEY" -m "$MSG_GET" | tail -n 1)
ARKAUTH_GET="$CONTRACT_ID:$NONCE_GET:$SIG_GET"
API_URL_GET="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_GET"

echo "GET Auth: $ARKAUTH_GET"
echo "GET URL: $API_URL_GET"

# Get contract info from the provider
curl -s "$API_URL_GET" | jq .

# Wait briefly to ensure a unique nonce for the next request
sleep 1

# Sign POST request (update config)
NONCE_POST=$(date +%s)
MSG_POST="$CONTRACT_ID:$NONCE_POST:"
SIG_POST=$(signhere -u "$USER_KEY" -m "$MSG_POST" | tail -n 1)
ARKAUTH_POST="$CONTRACT_ID:$NONCE_POST:$SIG_POST"
API_URL_POST="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_POST"

echo "POST URL: $API_URL_POST"

# Prepare the whitelist update JSON (edit as needed)
read -r -d '' WHITELIST_JSON <<EOF
{
"white_listed_ip_addresses": [],
"per_user_rate_limit": 1000,
"cors": {
"allow_origins": ["*"],
"allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allow_headers": ["*"]
}
}
EOF

# Update contract configuration on the provider
curl -X POST -H "Content-Type: application/json" -d "$WHITELIST_JSON" "$API_URL_POST"
echo
```

Notes:

* Replace and with your actual contract ID and local key name.
* Only the contract holder or delegate may update contract configuration.
* Adjust the whitelist or CORS settings as appropriate for your use case.

## View Pay-As-You-Go (PAYG) Contract

To effectively manage your PAYG contract, you should regularly review its current status—such as remaining deposit, rate limits, active claims, and other details. This script securely retrieves contract information from the provider’s API using a signed request. Signing the request with your private key not only authenticates your identity but also ensures the privacy and security of your contract data.

```
#!/bin/bash

# Configuration: Set your provider API, contract ID, key, and keyring backend.
PROVIDER_API="http://127.0.0.1:3636"
CONTRACT_ID=<your-contract-id>
CLIENT_KEY="<your-client-key-name>"
KEYRING_BACKEND="test"

# Fetch your client address (Bech32 format).
CLIENT_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --bech acc --keyring-backend="$KEYRING_BACKEND" --address)
echo "Client Pubkey: $CLIENT_PUBKEY"

# Prepare a unique nonce and message for the GET request.
NONCE_GET=$(date +%s)
MSG_GET="$CONTRACT_ID:$NONCE_GET:"

# Sign the GET message with your client key.
SIG_GET=$(signhere -u "$CLIENT_KEY" -m "$MSG_GET" | tail -n 1)

# Construct the authenticated API URL.
ARKAUTH_GET="$CONTRACT_ID:$NONCE_GET:$SIG_GET"
API_URL_GET="$PROVIDER_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_GET"

echo "GET Auth: $ARKAUTH_GET"
echo "GET URL: $API_URL_GET"

# Request contract info from the provider's API and pretty-print it.
curl -s "$API_URL_GET" | jq .
```

Notes:

* Replace and with your actual contract ID and client key name.
* Never share your key or signature outputs.
* If running in production, ensure KEYRING\_BACKEND is set securely.

## Test Pay-As-You-Go (PAYG) Contract

This script simulates multiple authorized requests against a PAYG contract, making sure each request is correctly signed and counted. Its main purpose is to help subscribers validate rate limits, nonce sequencing, and provider responses under different loads. You’ll use this for integration tests or to ensure that your client and provider are enforcing rate limits and claim settlements as expected.

```
#!/bin/bash

# Usage:
#   ./payg_load_test.sh [RATE_LIMIT] [INTERVAL] [TOTAL_REQUESTS]
#   - RATE_LIMIT:     Max requests per minute (default: 10)
#   - INTERVAL:       Seconds between requests (default: just above the QPM interval)
#   - TOTAL_REQUESTS: Number of requests to make (default: 30)

# --- CONFIGURATION ---
CONTRACT_ID=<your-contract-id>
CHAIN_ID="arkeo-main-v1"
CLIENT_KEY="<your-client-key-name>"
KEYRING_BACKEND="test"
PROVIDER_API="http://127.0.0.1:3636"
SERVICE="<service-name>"
DATA='{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}'
HEADERS="Content-Type: text/plain"

# Get client Bech32 pubkey
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$KEYRING_BACKEND" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

RATE_LIMIT="${1:-10}"
TOTAL_REQUESTS="${3:-30}"

# Calculate request interval (default: 10% slower than max QPM)
if [[ -n "$2" ]]; then
    INTERVAL="$2"
else
    INTERVAL=$(echo "scale=2; 60/$RATE_LIMIT * 1.1" | bc)
fi

echo "Load Test (PAYG): Requests=$TOTAL_REQUESTS, QPM=$RATE_LIMIT, Interval=${INTERVAL}s"
echo "Contract: $CONTRACT_ID"
echo "Client: $CLIENT_KEY"
echo "Endpoint: $PROVIDER_API/$SERVICE"
echo "Data: $DATA"
echo

success=0
rate_limited=0
other=0

start_time=$(date +%s)

# Get starting nonce for the contract
CLAIMS_API="$PROVIDER_API/claims?contract_id=$CONTRACT_ID&client=$CLIENT_PUBKEY"
HIGHEST_NONCE=$(curl -s "$CLAIMS_API" | jq .highestNonce)
if [ -z "$HIGHEST_NONCE" ] || [ "$HIGHEST_NONCE" == "null" ]; then
  HIGHEST_NONCE=0
fi
NEXT_NONCE=$((HIGHEST_NONCE + 1))

for i in $(seq 1 $TOTAL_REQUESTS); do
    loop_start=$(date +%s.%N)
    printf "Request #%d... " "$i"

    # --- SIGN THE MESSAGE FOR THIS NONCE ---
    MSG="$CONTRACT_ID:$NEXT_NONCE:"
    SIG=$(signhere -u "$CLIENT_KEY" -m "$MSG" | tail -n 1)
    ARKAUTH="$CONTRACT_ID:$CLIENT_PUBKEY:$NEXT_NONCE:$SIG"
    ENDPOINT="$PROVIDER_API/$SERVICE?arkauth=$ARKAUTH"

    # --- Make the request ---
    response=$(curl -s -w "\n%{http_code}" -X POST --data-binary "$DATA" -H "$HEADERS" "$ENDPOINT")
    http_code=$(echo "$response" | tail -n1)
    http_body=$(echo "$response" | sed '$d')

    if [ "$http_code" == "200" ]; then
        echo "✅ 200 OK"
        ((success++))
    elif [ "$http_code" == "403" ] || [ "$http_code" == "429" ]; then
        echo "🚫 Rate Limited ($http_code)"
        ((rate_limited++))
    else
        echo "❓ $http_code"
        ((other++))
    fi

    NEXT_NONCE=$((NEXT_NONCE + 1))  # Increment for the next request

    # Maintain correct interval timing
    loop_end=$(date +%s.%N)
    elapsed=$(echo "$loop_end - $loop_start" | bc)
    sleep_time=$(echo "$INTERVAL - $elapsed" | bc)
    if (( $(echo "$sleep_time > 0" | bc -l) )); then
        sleep $sleep_time
    fi
done

end_time=$(date +%s)
duration=$((end_time - start_time))
if [ "$duration" -gt 0 ]; then
    qpm=$((success * 60 / duration))
else
    qpm=0
fi

echo
echo "Total Requests:    $TOTAL_REQUESTS"
echo "Duration:          $duration seconds"
echo "Successful (200):  $success"
echo "Rate Limited:      $rate_limited"
echo "Other Errors:      $other"
echo "Approx. QPM:       $qpm"
```

Notes:

* Replace , , and with your actual details.
* Ensure you have the appropriate permissions, deposit, and contract status before testing.
* This script will help you confirm rate limiting and signature-based PAYG access is working as intended.

## Close Pay-As-You-Go (PAYG) Contract

Closing a PAYG contract formally ends your usage agreement with a provider on the Arkeo network. This is needed when you no longer wish to authorize further usage or want to trigger final settlement of outstanding claims. Once a PAYG contract is closed, you cannot authorize new usage, and the provider can settle any remaining claims for payment. Always close your contract when finished to ensure all activity is finalized and the contract is removed from your active list.

```
#!/bin/bash

# Define your API endpoint, contract ID, client key, and keyring backend.
PROVIDER_API="127.0.0.1:26657"
CONTRACT_ID=<your-contract-id>
CLIENT_KEY="<your-client-key-name>"
KEYRING_BACKEND="test"
FEES="200uarkeo"

# Retrieve your client Bech32 public key for contract closure.
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$KEYRING_BACKEND" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

echo "Client pubkey: $CLIENT_PUBKEY"

# Submit the transaction to close the PAYG contract.
arkeod tx arkeo close-contract \
  "$CONTRACT_ID" \
  "$CLIENT_PUBKEY" \
  --from="$CLIENT_KEY" \
  --fees="$FEES" \
  --keyring-backend="$KEYRING_BACKEND" \
  --node tcp://$PROVIDER_API \
  -y
```

Notes:

* Replace and with your actual contract ID and local key name.
* Set KEYRING\_BACKEND and PROVIDER\_API as appropriate for your environment.
* After closing, verify contract status with arkeod query arkeo show-contract .


# Managing Contracts

Subscribers have flexibility in managing their contracts to ensure continuous uptime. The examples provided here illustrate a strategy using a single provider with multiple Pay-As-You-Go (PAYG) contracts, where the most recent active contract is always utilized. Subscribers may also apply similar logic to subscription contracts by automating contract renewal or implementing failover mechanisms upon expiry. The autocaller scripts demonstrated here are intelligent tools designed to reliably select the latest active contract for your chosen provider and service, ensuring consistent application availability.

## Contract Management: PAYG Auto-Topper Script

This auto-topper script ensures continuous uptime for your Pay-As-You-Go (PAYG) contracts by automatically monitoring their usage and duration, and proactively creating new overlapping contracts when active contracts reach a specified threshold. This automated approach ensures that your service access remains uninterrupted.

```
#!/bin/bash

#
# CONFIGURATION:
# These are the configuration values used for each service to maintain the 100% uptime capabilities of the script.
#
# SERVICE_NAME:             Human-readable name of the blockchain or API service (e.g., "btc-mainnet-fullnode").
# SERVICE_NUMBER:           Value for the service name, pulled from the enum here: https://raw.githubusercontent.com/arkeonetwork/arkeo/refs/heads/master/common/service.go
# SERVICE_ARKEO_API:        API endpoint for the local Arkeo node (used for creating/querying contracts, e.g., http://127.0.0.1:26657).
# SERVICE_ARKEO_FEE:        Default fee to use when creating or updating contracts via Arkeo transactions (e.g., "200uarkeo").
# PROVIDER_PUBKEY:          Bech32 public key of the provider (the service operator who receives contract income).
# PROVIDER_SENTINEL_API:    API endpoint for the provider's Sentinel proxy (where client requests are sent for metering/billing).
# CLIENT_KEY:               Local key name in your keyring for the client wallet (the party opening/contracts).
# CLIENT_KEYRING:           Keyring backend for the client key ("test", "file", "os", etc.).
# CONTRACT_TYPE:            Type of contract: 0 = subscription (fixed time), 1 = pay-as-you-go (usage-based).
# CONTRACT_AUTH:            Authorization model: 0 = STRICT (per-request client signatures), 1 = OPEN (no signatures required).
# CONTRACT_DEPOSIT:         Total amount of tokens (in smallest denom) to lock in the contract (e.g., "100000000" for 1 ARKEO).
# CONTRACT_DURATION:        Duration of contract in blocks (for subscriptions), or can be short for PAYG.
# CONTRACT_RATE:            Cost per request (matches provider's advertised rate, in smallest denom).
# CONTRACT_QPM:             Maximum queries per minute allowed under the contract (for rate limiting).
# CONTRACT_SETTLEMENT:      Number of blocks after contract expiry in which the provider can still submit claims.
# CONTRACT_DELEGATE:        (Optional) Bech32 pubkey of a delegate permitted to spend or claim from this contract.
#

CHAIN_ID="arkeo-main-v1"
CLIENT_KEY="Arkeo-Main-Validator-3"
CLIENT_KEYRING="test"
ARKEO_SERVICE_API="127.0.0.1:26657"
ARKEO_SERVICE_FEE="200uarkeo"
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$CLIENT_KEYRING" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")
CONTRACT_OVERLAP_THRESHOLD=20

SERVICES_LIST=(
'{
"SERVICE_NAME":             "btc-mainnet-fullnode",
"SERVICE_NUMBER":           10,
"PROVIDER_PUBKEY":          "arkeopub1addwnpepqfn52r6xng2wwfrgz2tm5yvscq42k3yu3ky9cg3kw5s6p0qg7tfx75uwq3z",
"PROVIDER_SENTINEL_API":    "http://127.0.0.1:3636",
"CONTRACT_TYPE":            1,
"CONTRACT_AUTH":            0,
"CONTRACT_DEPOSIT":         100000000,
"CONTRACT_DURATION":        100,
"CONTRACT_RATE":            "10000uarkeo",
"CONTRACT_QPM":             20,
"CONTRACT_SETTLEMENT":      100,
"CONTRACT_DELEGATE":        ""
}'
)

#
# OPEN ARKEO CONTRACT:
# This function is called when there are no contracts found and to create a second overlapping contract when the active contract reached 25%.
#

open_arkeo_contract() {

# Open the contract and capture the txhash
OPEN_CONTRACT_RESULT=$(arkeod tx arkeo open-contract \
"$PROVIDER_PUBKEY" \
"$SERVICE_NAME" \
"$CLIENT_PUBKEY" \
"$CONTRACT_TYPE" \
"$CONTRACT_DEPOSIT" \
"$CONTRACT_DURATION" \
"$CONTRACT_RATE" \
"$CONTRACT_QPM" \
"$CONTRACT_SETTLEMENT" \
"$CONTRACT_AUTH" \
"$CONTRACT_DELEGATE" \
--from="$CLIENT_KEY" \
--keyring-backend="$CLIENT_KEYRING" \
--fees="$ARKEO_SERVICE_FEE" \
--node tcp://$ARKEO_SERVICE_API \
-y --output json)

TXHASH=$(echo "$OPEN_CONTRACT_RESULT" | jq -r '.txhash // .TxHash // empty')
if [ -z "$TXHASH" ] || [ "$TXHASH" == "null" ]; then
echo "Failed to get txhash! Raw result:"
echo "$OPEN_CONTRACT_RESULT"
exit 1
fi
echo "TxHash: $TXHASH"

# Wait for transaction to be committed, retry if not present yet
TX_RESULT=""
for i in {1..10}; do
TX_RESULT=$(arkeod query tx "$TXHASH" --output json 2>/dev/null)
if echo "$TX_RESULT" | jq . > /dev/null 2>&1; then
break
fi
sleep 2
done

CONTRACT_ID=$(echo "$TX_RESULT" | jq -r '
.events[]?
| select(.type == "arkeo.arkeo.EventOpenContract")
| .attributes[]?
| select(.key == "contract_id")
| .value
' | tr -d '"')

if [ -z "$CONTRACT_ID" ]; then
echo "Could not extract contract id. Raw tx result:"
echo "$TX_RESULT" | jq
exit 1
fi

echo "Contract ID: $CONTRACT_ID"

# Sign POST request (update config)
NONCE_DATE=$(date +%s)
MSG_POST="$CONTRACT_ID:$NONCE_DATE:"
SIG_POST=$(signhere -u "$CLIENT_KEY" -m "$MSG_POST" | tail -n 1)
ARKAUTH_POST="$CONTRACT_ID:$NONCE_DATE:$SIG_POST"
API_URL_POST="$PROVIDER_SENTINEL_API/manage/contract/$CONTRACT_ID?arkcontract=$ARKAUTH_POST"

echo "POST URL: $API_URL_POST"

# Prepare the whitelist update JSON
read -r -d '' WHITELIST_JSON <<EOF
{
"white_listed_ip_addresses": [],
"per_user_rate_limit": 1000,
"cors": {
"allow_origins": ["*"],
"allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allow_headers": ["*"]
}
}
EOF

echo "Whitelist: $WHITELIST_JSON"
echo "API Url: $API_URL_POST"

# Config contract data
curl -X POST -H "Content-Type: application/json" -d "$WHITELIST_JSON" "$API_URL_POST"

}

#
# SERVICE LOOP:
# Main loop to iterate over each service and manage contracts accordingly
#

echo
echo "Arkeo Pay-As-You-Go Contract Topper"
echo "  $(date)"

for SERVICE in "${SERVICES_LIST[@]}"; do

#
# SERVICE VARIABLE MAPPING
# Map the configuration values to variables.
#

SERVICE_NAME=$(echo "$SERVICE" | jq -r '.service_name // .SERVICE_NAME // empty')
SERVICE_NUM=$(echo "$SERVICE" | jq -r '.service_number // .SERVICE_NUMBER // empty')
SERVICE_ARKEO_API=$(echo "$SERVICE" | jq -r '.service_arkeo_api // .SERVICE_ARKEO_API // empty')
SERVICE_ARKEO_FEE=$(echo "$SERVICE" | jq -r '.service_arkeo_fee // .SERVICE_ARKEO_FEE // empty')
PROVIDER_PUBKEY=$(echo "$SERVICE" | jq -r '.provider_pubkey // .PROVIDER_PUBKEY // empty')
PROVIDER_SENTINEL_API=$(echo "$SERVICE" | jq -r '.provider_sentinel_api // .PROVIDER_SENTINEL_API // empty')
CONTRACT_TYPE=$(echo "$SERVICE" | jq -r '.contract_type // .CONTRACT_TYPE // empty')
CONTRACT_AUTH=$(echo "$SERVICE" | jq -r '.contract_auth // .CONTRACT_AUTH // empty')
CONTRACT_DEPOSIT=$(echo "$SERVICE" | jq -r '.contract_deposit // .CONTRACT_DEPOSIT // empty')
CONTRACT_DURATION=$(echo "$SERVICE" | jq -r '.contract_duration // .CONTRACT_DURATION // empty')
CONTRACT_RATE=$(echo "$SERVICE" | jq -r '.contract_rate // .CONTRACT_RATE // empty')
CONTRACT_QPM=$(echo "$SERVICE" | jq -r '.contract_qpm // .CONTRACT_QPM // empty')
CONTRACT_SETTLEMENT=$(echo "$SERVICE" | jq -r '.contract_settlement // .CONTRACT_SETTLEMENT // empty')
CONTRACT_DELEGATE=$(echo "$SERVICE" | jq -r '.contract_delegate // .CONTRACT_DELEGATE // empty')

if [[ -z "$SERVICE_NAME" || -z "$SERVICE_NUM" || -z "$PROVIDER_PUBKEY" || -z "$CLIENT_PUBKEY" ]]; then
echo
echo "Service: $SERVICE_NAME:"
echo "    Service entry is missing required fields."
continue
fi

#
# LIST CONTRACTS
# This pulls a long list of contracts and filters them for the client and provider service.
#

CONTRACTS_JSON="$(arkeod query arkeo list-contracts --output json)"

CONTRACTS=$(echo "$CONTRACTS_JSON" | jq -c \
--arg sn "$SERVICE_NUM" \
--arg prov "$PROVIDER_PUBKEY" \
--arg cli "$CLIENT_PUBKEY" '
[.contract[]
| select(.type == "PAY_AS_YOU_GO")
| select(.service == ($sn | tonumber))
| select(.provider == $prov)
| select(.client == $cli)
| select(.settlement_height == "0")
| select(.deposit != "0")
] | sort_by(.id | tonumber)[]
')

#
# NO CONTRACTS IN SERVICE
# Let's create a contract for the service since it didn't find an active one.
#

if [[ -z "$CONTRACTS" ]]; then

    echo
    echo "Service: $SERVICE_NAME:"
    echo "  No active PAY_AS_YOU_GO contracts found."
    echo "  Attempting to open a new active contract."

    open_arkeo_contract

    continue
fi

#
# CONTRACTS LOOP:
# Process and display information for each active contract
#

PRINTED_SERVICE_HEADER=0

echo "$CONTRACTS" | while read -r CONTRACT; do

    #
    # SERVICE HEADER:
    # Print this header once.
    #

    if [[ "$PRINTED_SERVICE_HEADER" -eq 0 ]]; then
      echo
      echo "Service: $SERVICE_NAME"
      PRINTED_SERVICE_HEADER=1
    fi

    #
    # CONTRACT CALCULATIONS:
    # Various calculations to determine percentages of usage and duration.
    #

    #echo "$CONTRACT" | jq

    CONTRACT_ID=$(echo "$CONTRACT" | jq -r '.id')

    #echo "Contract ID: $CONTRACT_ID"

    DEPOSIT_VAL=$(echo "$CONTRACT" | jq -r '.deposit | tonumber')
    RATE_AMOUNT=$(echo "$CONTRACT" | jq -r '.rate.amount | tonumber')

    CLAIMS_API="$PROVIDER_SENTINEL_API/claims?contract_id=$CONTRACT_ID&client=$CLIENT_PUBKEY"
    NONCE=$(curl -s "$CLAIMS_API" | jq .highestNonce)
    if [ -z "$NONCE" ] || [ "$NONCE" == "null" ]; then
      NONCE=0
    fi

    if [[ -z "$CONTRACT_ID" || -z "$DEPOSIT_VAL" || -z "$NONCE" || -z "$RATE_AMOUNT" ]]; then
      continue
    fi

    #echo "Nonce: $NONCE"
    #echo "Rate Amount: $RATE_AMOUNT"

    USED_AMOUNT=$(($NONCE * $RATE_AMOUNT))
    REMAINDER=$(($DEPOSIT_VAL - $USED_AMOUNT))

    #echo "Deposit Val: $DEPOSIT_VAL"
    #echo "Used Amount: $USED_AMOUNT"
    #echo "Remainder: $REMAINDER"

    if [[ "$DEPOSIT_VAL" -eq 0 ]]; then
      PERCENT_LEFT=0
      PERCENT_USED=0
    else
      PERCENT_LEFT=$(awk "BEGIN {printf \"%.2f\", ($REMAINDER/$DEPOSIT_VAL)*100}")
      PERCENT_USED=$(awk "BEGIN {printf \"%.2f\", 100 - ($REMAINDER/$DEPOSIT_VAL)*100}")
    fi

    CURRENT_HEIGHT=$(arkeod status | jq -r .sync_info.latest_block_height)
    CONTRACT_START=$(echo "$CONTRACT" | jq -r '.height | tonumber')
    CONTRACT_DURATION=$(echo "$CONTRACT" | jq -r '.duration | tonumber')
    CONTRACT_EXPIRE_HEIGHT=$((CONTRACT_START + CONTRACT_DURATION))
    BLOCKS_LEFT=$((CONTRACT_EXPIRE_HEIGHT - CURRENT_HEIGHT))

    if (( CONTRACT_DURATION > 0 )); then
      PERCENT_TIL_EXPIRE=$(awk "BEGIN {printf \"%.2f\", ($BLOCKS_LEFT/$CONTRACT_DURATION)*100}")
      (( $(awk "BEGIN {print ($PERCENT_TIL_EXPIRE < 0)}") )) && PERCENT_TIL_EXPIRE=0
    else
      PERCENT_TIL_EXPIRE=0
    fi

    DURATION_USED=$(awk "BEGIN {printf \"%.2f\", 100 - $PERCENT_TIL_EXPIRE}")


    if (( BLOCKS_LEFT <= 0 )); then

      #
      # CONTRACT SETTLEMENT PHASE
      # The contract has expired, but is still in a settlement phase. The overlap contract should be used for calls.
      #

      echo "  Contract #$CONTRACT_ID, Deposit: ${DEPOSIT_VAL}uarkeo, Expires at Block: $CONTRACT_EXPIRE_HEIGHT"
      echo "    $PERCENT_LEFT% Deposit Remaining"

      # Calculate settlement percentage left
      CONTRACT_START_HEIGHT=$(echo "$CONTRACT" | jq -r '.height | tonumber')
      CONTRACT_DURATION=$(echo "$CONTRACT" | jq -r '.duration | tonumber')
      SETTLEMENT_DURATION=$(echo "$CONTRACT" | jq -r '.settlement_duration | tonumber')
      SETTLEMENT_BLOCKS_LEFT=$(( (CONTRACT_START_HEIGHT + CONTRACT_DURATION + SETTLEMENT_DURATION) - CURRENT_HEIGHT ))
      PERCENT_TIL_SETTLEMENT=$(awk "BEGIN {printf \"%.2f\", ($SETTLEMENT_BLOCKS_LEFT/$SETTLEMENT_DURATION)*100}")
      echo "    $PERCENT_TIL_SETTLEMENT% Settlement Remaining"
    else

      #
      # CONTRACT ACTIVE PHASE
      # Active contract used for calls.
      #

      echo "  Contract #$CONTRACT_ID: Deposit: ${DEPOSIT_VAL}uarkeo, Expires at Block: $CONTRACT_EXPIRE_HEIGHT"
      echo "    $PERCENT_LEFT% Deposit Remaining"
      echo "    $PERCENT_TIL_EXPIRE% Duration Remaining"
    fi

    #
    # CONTRACT OVERLAP CREATION
    # When the active contract reaches a duration threshold, this triggers the creation of an overlapping contract to take over when the active one expires.
    #

    PERCENT_TIL_EXPIRE_INT=${PERCENT_TIL_EXPIRE%.*}
    CONTRACT_COUNT=$(echo "$CONTRACTS" | wc -l)

    if (( PERCENT_TIL_EXPIRE_INT <= CONTRACT_OVERLAP_THRESHOLD )) && (( CONTRACT_COUNT == 1 )); then

      echo
      echo "  Contract ():"
      echo "    Active Contract is getting low."
      echo "    Attempting to open a new contract to use next..."

      open_arkeo_contract

    fi

done

done

echo
```

Notes:

* Ensure the script is run periodically to verify continued connectivity and proper authorization.
* Check logs and outputs regularly to monitor successful execution and identify potential issues early.
* Maintain accurate and up-to-date configurations to reflect your service usage and provider agreements.

## Contract Management: PAYG Auto-Fetch Test Script

This script identifies the currently active Pay-As-You-Go (PAYG) contract and performs a signed test call to verify connectivity and authorization. It retrieves the latest active contract, computes the next available nonce for claim tracking, generates a cryptographic signature, and makes an authenticated request to the provider's API. This ensures the PAYG contract is functional and ready for use, validating proper setup and ongoing access.

```
#!/bin/bash

# CONFIGURATION:

# CHAIN_ID                  The chain id for Arkeo, as this is needed for signing.
# CLIENT_KEY:               Local key name in your keyring for the client wallet (the party opening/contracts).
# CLIENT_KEYRING:           Keyring backend for the client key ("test", "file", "os", etc.).
# PROVIDER_SERVICE_NAME:    Human-readable name of the blockchain or API service (e.g., "btc-mainnet-fullnode").
# PROVIDER_SERVICE_NUMBER:  Value for the service name, pulled from the enum here: https://raw.githubusercontent.com/arkeonetwork/arkeo/refs/heads/master/common/service.go
# PROVIDER_PUBKEY:          Bech32 public key of the provider (the service operator who receives contract income).
# PROVIDER_SENTINEL_API:    API endpoint for the provider's Sentinel proxy (where client requests are sent for metering/billing).
# PROVIDER_CONTRACT_TYPE:   Type of contract: 0 = subscription (fixed time), 1 = pay-as-you-go (usage-based).

CHAIN_ID="arkeo-main-v1"

CLIENT_KEY="Arkeo-Main-Validator-3"
CLIENT_KEYRING="test"
CLIENT_RAW_PUBKEY=$(arkeod keys show "$CLIENT_KEY" --output json --keyring-backend="$CLIENT_KEYRING" | jq -r .pubkey | jq -r .key)
CLIENT_PUBKEY=$(arkeod debug pubkey-raw "$CLIENT_RAW_PUBKEY" -t secp256k1 | grep 'Bech32 Acc:' | sed "s|Bech32 Acc: ||g")

PROVIDER_SERVICE_NAME="btc-mainnet-fullnode"
PROVIDER_SERVICE_NUMBER=10
PROVIDER_PUBKEY="arkeopub1addwnpepqfn52r6xng2wwfrgz2tm5yvscq42k3yu3ky9cg3kw5s6p0qg7tfx75uwq3z"
PROVIDER_SENTINEL_API="http://127.0.0.1:3636"
PROVIDER_CONTRACT_TYPE=1

# Retrieve the oldest usable contract info (in case there is an overlapping contract).
case "$PROVIDER_CONTRACT_TYPE" in
  0) CONTRACT_TYPE_STRING="SUBSCRIPTION" ;;
  1) CONTRACT_TYPE_STRING="PAY_AS_YOU_GO" ;;
  *) echo "Unknown contract type: $PROVIDER_CONTRACT_TYPE" && exit 1 ;;
esac

CURRENT_HEIGHT=$(arkeod status | jq -r .sync_info.latest_block_height)
# echo "Current Height: $CURRENT_HEIGHT"

CONTRACTS_JSON="$(arkeod query arkeo list-contracts --output json)"
CONTRACT_JSON=$(echo "$CONTRACTS_JSON" | jq -c \
  --arg sn "$PROVIDER_SERVICE_NUMBER" \
  --arg prov "$PROVIDER_PUBKEY" \
  --arg cli "$CLIENT_PUBKEY" \
  --arg type "$CONTRACT_TYPE_STRING" \
  --argjson current_height "$CURRENT_HEIGHT" '
    [.contract[]
      | select(.type == $type)
      | select(.service == ($sn | tonumber))
      | select(.provider == $prov)
      | select(.client == $cli)
      | select(.settlement_height == "0")
      | select(.deposit != "0")
      | select((.height | tonumber) + (.duration | tonumber) > $current_height)
    ] | sort_by(.id | tonumber)[0]'
)

echo
echo "Selected Contract:"
# echo "$CONTRACT_JSON" | jq

if [ -z "$CONTRACT_JSON" ] || [ "$CONTRACT_JSON" == "null" ]; then
  echo "No active PAYG contract found."
  echo
  exit 1
else
  CONTRACT_ID=$(echo "$CONTRACT_JSON" | jq -r '.id')
  echo "  Contract ID: $CONTRACT_ID"
fi

CONTRACT_ID=$(echo "$CONTRACT_JSON" | jq -r '.id')

# GET HIGHEST NONCE USED (Essential for claims, and lowest costs.)
CLAIMS_API="$PROVIDER_SENTINEL_API/claims?contract_id=$CONTRACT_ID&client=$CLIENT_PUBKEY"
HIGHEST_NONCE=$(curl -s "$CLAIMS_API" | jq .highestNonce)
if [ -z "$HIGHEST_NONCE" ] || [ "$HIGHEST_NONCE" == "null" ]; then
  HIGHEST_NONCE=0
fi
NEXT_NONCE=$((HIGHEST_NONCE + 1))

# SIGN THE MESSAGE (Essential for strict/PAYG Contracts)
CHAIN_ID="arkeo-main-v1"
MSG="$CONTRACT_ID:$NEXT_NONCE:$CHAIN_ID"
SIG=$(signhere -u "$CLIENT_KEY" -m "$MSG" | tail -n 1)

# MAKE THE SIGNED REQUEST
ARKAUTH="$CONTRACT_ID:$NEXT_NONCE:$SIG"
echo "  Nonce: $NEXT_NONCE"
echo "  Signature: $SIG"

RESULT=$(curl -s --data-binary "{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"getblockcount\", \"params\": []}" \
  -H 'content-type: text/plain;' \
  "$PROVIDER_SENTINEL_API/$PROVIDER_SERVICE_NAME?arkauth=$ARKAUTH")

echo "  Result:"
echo "$RESULT" | jq

echo
```

Notes:

* Verify your configuration variables carefully before running this script.
* Regularly test your PAYG contracts to ensure they're valid and operational.
* Maintain sufficient funds and monitor nonce increments closely to avoid disruption in service.


# Monitoring

Effective monitoring is essential for maintaining reliable service access and ensuring your subscriber contracts operate smoothly. Utilizing the auto-topper script for continuous contract monitoring has proven highly effective, providing proactive management and automated renewal to ensure uninterrupted service.

## Account Balance Monitoring

It's crucial to monitor your hot wallet's account balance regularly to ensure you maintain sufficient funds for automated transactions and fees. You can quickly check your account balance using the following command:

```
arkeod query bank balances <your-provider-account-address>
```

Replace with your specific Arkeo account address.

Regular balance checks help prevent disruptions due to insufficient funds and ensure your auto-topper script and other contract management processes run smoothly.


# Arkeo for Indexers


# Arkeo for Indexers

The **Arkeo Indexer** is a powerful two-part system that makes it easy to work with on-chain data from the Arkeo blockchain. It consists of two key applications:

### The Indexer

A refactored and modernized version of Unchained, the Indexer connects directly to the Arkeo blockchain and parses on-chain data, storing it in a local PostgreSQL SQL database for fast, reliable queries. It keeps your database synced with the chain in near real-time, handling all the heavy lifting of extracting and organizing blockchain activity.

### The API

The API is a lightweight web service that sits on top of your SQL database. It exposes all the indexed blockchain data via easy-to-use REST endpoints, making it simple for dApps, explorers, dashboards, and other services to access up-to-date Arkeo data without worrying about parsing the chain themselves.

#### With the Indexer and API together, you can:

* Run your own private copy of all relevant Arkeo data.
* Serve fast, flexible, and custom queries to your users or apps.
* Stay in sync with the chain, with full control over data, uptime, and privacy.

## Indexer Setup

### Service Overview

The service used to launch the indexer contains any needed environmental variables and points at the config file.

```
[Unit]
Description=Arkeo Indexer Service
After=network-online.target

[Service]
User=user
WorkingDirectory=/home/user
ExecStart=/home/user/go/bin/indexer --config /home/user/arkeo_providers/indexer_config_1.yaml
Environment="LOG_LEVEL=info"
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
```

### Config File

This contains the core values needed for the running of the indexer.

```
arkeo_api: "http://localhost:1317"
tendermint_api: "http://localhost:26657"
tendermint_ws: "http://localhost:26657"
chain_id: "arkeo-main-v1"
bech32_pref_acc_addr: "arkeo"
bech32_pref_acc_pub: "arkeopub"
db:
  host: "localhost"                         # Use your database host or IP here
  port: 5432                                # Standard PostgreSQL port
  user: "arkeo_user"                        # Your database user
  pass: "REPLACE_WITH_SECRET_PASSWORD"      # <--- Set this securely!
  name: "arkeo"                             # Database name
  pool_max_conns: 20
  pool_min_conns: 1
  ssl_mode: "disable"                       # Set to "require" for production if possible
  connection_timeout: 30
```

### SQL Setup

You want to install Postgres SQL for the indexer.

With that installed, there is a setup for formatting the tables and adjusting access.

Make sure you did this command on your root arkeo directory from the command line:

```
make tools
```

This creates the TERN tool that is used to create the sql tables.

Do these commands on the server hosting the Postgres server.

> Note that if you DROP DATABASE arkeo below, you will lose all your existing arkeo index data- but you probably know that.

```
psql -h 127.0.0.1 -U postgres -c "DROP DATABASE arkeo;"
psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE arkeo;"
```

Update the tern config in the arkeo directory.

```
/Users/user/Projects/arkeo/directory/tern/tern.conf
```

```
[database]
host = "localhost"                          # Use your database host or IP here
port = 5432                                 # Standard PostgreSQL port
database = "arkeo"                          # Database name
user = "postgres"                           # Database user
password = "REPLACE_WITH_SECURE_PASSWORD"   # <--- Never commit real passwords!
version_table = "public.schema_version"
sslmode = "disable"                         # Use 'require' in production if possible

[data]
# Any fields in the data section are available in migration templates
# prefix = "foo"                            # Example custom field (uncomment as needed)
```

Use TERN to update the sql data structure.

> Note, that you don't want to leave your sensitive Postgres admin data in this directory- so remember to delete this info once you setup your database.

Tern is a bit confusing to install as Arkeo uses this version: <https://github.com/jackc/tern>

```
go install github.com/jackc/tern/v2@latest
```

```
tern migrate -c /Users/user/Projects/arkeo/directory/tern/tern.conf -m /Users/user/Projects/arkeo/directory/tern
```

A long script of sql will run by as it updates your Postgres tables.

Now that there is a structure, you need to lower permissions for a user you want to use for the Indexer.

```
psql -h 100.28.199.0 -U postgres -d arkeo

CREATE USER arkeo_user WITH PASSWORD 'REPLACE_WITH_A_STRONG_PASSWORD';
```

No let's apply the user to the tables that TERN made.

```
psql -h 100.28.199.0 -U postgres -d arkeo

DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'public') LOOP
EXECUTE 'ALTER TABLE public.' || quote_ident(r.tablename) || ' OWNER TO arkeo_user;';
END LOOP;
END $$;

DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = 'public') LOOP
EXECUTE 'ALTER SEQUENCE public.' || quote_ident(r.sequence_name) || ' OWNER TO arkeo_user;';
END LOOP;
END $$;

DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT table_name FROM information_schema.views WHERE table_schema = 'public') LOOP
EXECUTE 'ALTER VIEW public.' || quote_ident(r.table_name) || ' OWNER TO arkeo_user;';
END LOOP;
END $$;

ALTER SCHEMA public OWNER TO arkeo_user;
ALTER DATABASE arkeo OWNER TO arkeo_user;

\dt+

\q
```

### Testing

Now run your Indexer.

```
cd ~/go/bin  

./indexer --config /Users/user/arkeo_providers/indexer_config_1.yaml
```

And as that works, you will see blocks flying by and data in the Postgres sql. If it looks good, then launch the background service.

## API Setup

### Service Overview

The service used to launch the api that exposes the indexer sql data on port 7777.

```
[Unit]
Description=Arkeo API Service
After=network-online.target

[Service]
User=user
WorkingDirectory=/home/user
ExecStart=/home/user/go/bin/api --config /home/user/arkeo_providers/api_config_1.yaml
Environment="LOG_LEVEL=info"
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
```

### Config File

This contains the core values needed for the running of the api.

```
db:
  host: "localhost"                     # Database host (update as needed)
  port: 5432                            # PostgreSQL port
  user: "arkeo_user"                    # Database user
  pass: "REPLACE_WITH_SECURE_PASSWORD"  # <-- Use a strong password!
  name: "arkeo"                         # Database name
  pool_max_conns: 5
  pool_min_conns: 1
  ssl_mode: "disable"                   # Use "require" for production if possible
  connection_timeout: 10
```

```
cd ~/go/bin  

./api --config /Users/user/arkeo_providers/api_config_1.yaml
```

### API Calls

Here are some calls for the Indexer API:

#### Health

```
http://127.0.0.1:7777/health
```

#### Stats

```
http://127.0.0.1:7777/stats
http://127.0.0.1:7777/stats/arkeo-mainnet-fullnode
```

#### Provider Search

```
http://127.0.0.1:7777/provider/search?service=arkeo-mainnet-fullnode&sort=contract_count
```

#### Provider

```
http://127.0.0.1:7777/provider/arkeopub1addwnpepqfn52r6xng2wwfrgz2tm5yvscq42k3yu3ky9cg3kw5s6p0qg7tfx75uwq3z?service=arkeo-mainnet-fullnode
```

#### Subscriber

```
http://127.0.0.1:7777/subscriber/arkeopub1addwnpepqtr4y6gahwhl3jxfahdnuf00s6fqw8he8rtssf8rf5gx2fwsc8ww7u93hf3?service=arkeo-mainnet-fullnode
```

## Provider Feedback

As a provider, you can tell us what more is needed with the index and api.

Join our community on Discord:

* Share your thoughts and suggestions.
* Help newcomers who might be facing challenges you've already conquered.
* Request features that you think could make Arkeo even better.

Your input helps shape the future of decentralized data, and we deeply appreciate your involvement.

Join our Data-Providers channel on Discord: [Arkeo Discord, Data-Providers](https://discord.com/channels/1050100146626642052/1359893459854688439)


# Architecture


# The Arkeo Token

## Introduction

The **Arkeo Token (ARKEO)** is the native cryptocurrency of the Arkeo Network, playing a vital role in the ecosystem by serving as:

* A means of payment between subscribers (clients) and data providers.
* Bonds posted by providers to demonstrate commitment and credibility.
* A staking asset used by validators and delegators to secure the network through Proof-of-Stake consensus.
* A governance token enabling holders to participate in voting and decision-making processes for network upgrades and changes.
* **Conversion:**
  * **1 ARKEO = 100,000,000 uARKEO**

## Maximum Supply

* **Total Supply:** 121,000,000 ARKEO

This fixed supply helps maintain predictable economics, transparency, and long-term sustainability.

## Airdrop

Detailed information about the airdrop process is available in the [Airdrop Documentation](/architecture/airdrop).

## Reserve

The **Reserve** is a Cosmos module managing the **non-circulating ARKEO supply**. It operates based on predefined network rules, independently from DAO governance or direct voting. Tokens from the reserve are systematically released to validators and delegators as rewards according to a controlled emission schedule.

### Emission Formula

Token emissions per block are determined by the following formula, designed to ensure predictable inflation and sustainable network incentives:

```
e = 6         # Emission curve
y = 6,311,520 # Blocks per year
r = Reserve Depth

block emission = r / e / y
```

This formula determines the number of tokens emitted per block, based on the reserve depth (`r`) and the emission curve (`e`).

## Staking and Rewards

ARKEO tokens can be staked with validators to secure the network and earn rewards. Validators operate nodes that validate transactions, produce new blocks, and maintain network security. Delegators contribute by delegating their ARKEO tokens to validators, sharing in the earned rewards proportional to their stake.

Staking ARKEO tokens helps maintain network security and decentralization, rewarding participants who actively support network integrity. For step-by-step instructions, refer to the Validator Documentation.

## Governance Participation

ARKEO token holders actively shape the network’s future by participating in governance. Token holders can vote on important proposals such as:

* Network upgrades and changes.
* Adjustments to economic parameters and emission schedules.
* Introduction of new features and integrations.

Engaging in governance empowers the community, enhances decentralization, and ensures decisions reflect the interests of network participants. Active governance fosters a robust, responsive, and community-driven ecosystem.


# Airdrop

## Airdrop Closed

The initial Arkeo airdrop period has officially ended. All previously allocated but unclaimed tokens have been returned to the Arkeo network reserve. We thank everyone for their participation and support.

## Original Airdrop Distribution (for reference)

The initial airdrop of ARKEO tokens was distributed among a broad variety of communities to encourage diverse participation in the Arkeo network.

## Original Claiming Process (now closed)

Users were required to take multiple actions to receive their full airdrop allocation:

* 1/3 was sent upon initial claim.
* 1/3 was sent after delegating Arkeo tokens to a validator.
* 1/3 was sent after participating in governance.

Ethereum users claimed their tokens by transferring from their designated Ethereum address to their Arkeo address via a signed message.

Eligible Arkeo native addresses were provided a small amount of ARKEO at genesis to cover the gas fees necessary to claim their tokens.

To incentivize timely claims, the claimable airdrop amount reduced over time:

* Full amount claimable for the first month (`DurationUntilDecay`).
* Linear decay in the claimable amount from the 1st to the 2nd month (`DurationOfDecay`).
* After two months, unclaimed tokens reverted to the reserve.

## THORChain Users

THORChain's unique BIP-44 coin type (931) required an additional step to transfer allocated tokens from a THORChain-derived address to an Arkeo address. This transfer could only be performed once per claim.

## Continuing Participation

Even though the airdrop has concluded, you can continue to engage with the Arkeo network by:

* Delegating ARKEO tokens to validators.
* Participating in governance proposals.
* Becoming a data provider or subscriber.

We appreciate your continued interest and involvement in the Arkeo community!


# Testnet

We are delighted to invite you to take part in an exciting journey as we embark on Phase 3 of our Testnet. This crucial stage is a testament to our relentless pursuit of developing a robust, efficient, and user-centric protocol, and we couldn't have done it without community members like you.

This document is your comprehensive guide to the exciting world of the Arkeo public testnet, where your valuable contributions can make a significant impact. Let's get started!

## 🎯 Purpose and Goals of the Testnet The Testnet serves as a vibrant

platform to test the fundamental functionality of our core protocol. This includes validating network operations, data providers, and dapps that utilize the data. However, note that we're saving the airdrop for a separate testnet, specifically created to test that code.

## ⏳ Testnet Duration Our Testnet is designed to operate for at least one

month, but the joy of discovery may extend this period. Keep in mind, we might reset and launch a new network if our dedicated team deems it necessary for optimization purposes.

## 🤔 Need Support or Have Questions? Our supportive community is always

ready to help! If you have questions, concerns, creative ideas, or bug reports, please join our [Discord server](https://discord.gg/wBcdVM53). For more focused discussions, #validator-testing and #data-testing are your go-to channels.

## 🤝 Expected Conduct We kindly ask all testers to contribute in good faith,

keeping the best interests of the network and the project at heart. If you stumble upon a bug or discover an exploit during your exploration, please alert our developers via Discord.

## 🎩 Testing Roles There are three primary roles you can take for a spin in

our beta:

1. **Validator:** Help the network commit new blocks to the Arkeo blockchain by running a testnet validator.
2. **Data Provider:** Run full nodes of various blockchains, allowing others to contract your infrastructure and pay for access (or offer it for free).
3. **Dapps:** If you're developing applications that require connections to blockchain daemons, we'd love your input on this role.

Whatever your role, you should find what you need to get started in our documentation: <https://docs.arkeo.network> - but if you can’t find what you are looking for please reach out in discord and let us know how we can help.

## 💰 Acquiring Testnet Tokens To jump into testing, you'll need testnet

tokens. At present, we support a command-line tool, not wallets. Learn how to install this CLI tool and create a wallet on our [GitHub repository](https://github.com/arkeonetwork/arkeo). Once you've got your "tarkeo" address, request tokens through this [Discord Channel](https://discord.gg/wBcdVM53).

## 💻 Testnet Address

To access a testnet server, they can be reached at

```
seed31.innovationtheory.com
```

The arkeo api is available on port `1317`

```
curl seed31.innovationtheory.com:1317/arkeo/providers | jq
```

For the RPC port, try port `26657`

```
curl -s seed31.innovationtheory.com:26657/status | jq
```

You can also find the genesis file here

```
curl -s http://seed31.innovationtheory.com:26657/genesis | jq
```

## 🎉 Let's Make Magic Happen! By participating in the Arkeo Network Phase 3

Testnet, you're not just testing a protocol—you're part of a passionate community that is shaping the future of blockchain technology. Your contributions are helping us build a more robust, efficient, and user-centric platform. For this, we are immensely grateful. Let the testing begin!


# Directory

The Directory Service is an off-chain API designed to simplify discovery and selection of data providers. Users and clients can utilize the directory to quickly find suitable providers based on criteria such as service type, pricing, reputation metrics, and availability. By streamlining the discovery process, the directory enhances user experience and promotes healthy competition among providers.

Arkeo ensures decentralized and dependable blockchain data access, positioning itself as the robust web3 alternative to centralized infrastructure providers.


# FAQs


# Frequently Asked Questions

Here are some commonly asked questions. We will update these as more requests come in.

### What is Arkeo?

Arkeo is a decentralized ecosystem enabling trustless, pay-as-you-go transactions. It combines off-chain authorization (client-signed claims) with on-chain settlement, providing efficient, transparent, and secure payment processing.

### How does Arkeo handle payments?

Arkeo uses off-chain authorization with on-chain settlement. Clients authorize usage off-chain through signatures, which providers periodically submit to the blockchain for secure and decentralized payment reconciliation.

### What contract types does Arkeo support?

Arkeo supports two contract types:

* **Subscription Contracts:** Fixed-term, predictable billing.
* **Pay-As-You-Go (PAYG) Contracts:** Usage-based billing requiring client signatures per usage event.

### How does Arkeo ensure security in key management?

Arkeo provides secure key management options, from simple test setups for automation (password-free signing) to advanced integrations like hardware security modules (HSMs) or external key management services (KMS).

### What happens if a provider doesn’t settle within the specified settlement duration?

If a provider fails to submit claims for settlement within the defined settlement duration, those claims expire and the provider forfeits payment for the related usage events.

### How are client signatures verified by providers?

Providers verify client signatures using the Arkeo blockchain’s cryptographic functionality. Every claim includes a unique nonce and client signature, ensuring authenticity and preventing replay attacks.

### Can a contract be delegated for third-party management?

Yes, Arkeo contracts support optional delegation. Providers or subscribers can assign a delegate by specifying the delegate’s public key when creating a contract, allowing trusted third parties to manage or settle claims.

### How do rate limits work within Arkeo contracts?

Arkeo contracts can optionally define a maximum queries-per-minute (QPM) parameter to enforce rate limits. This protects providers from excessive requests, especially valuable for PAYG contracts.

### What tools does Arkeo offer to simplify nonce signing?

Arkeo provides the `signhere` command-line tool for signing nonces and usage data quickly and securely. It enables automated signing processes without manual intervention or password entry when using appropriate key management practices.

### What happens if the Sentinel process misses blockchain events?

If Sentinel becomes desynchronized or misses blockchain events (due to downtime or connection issues), it can be re-synced by restarting or reindexing events. Regular Sentinel maintenance is recommended to ensure claims are accurately tracked and settled.

### Do I have to be a validator or run my own full node to be a provider?

No. Any funded Arkeo account can bond and run a provider service. For convenience, you only need the CLI binaries, but using an external node may impact your reliability and settlement guarantees.


# Official URLs


