Skills sohopay

Initiate payments on the SOHO Pay credit layer using EIP-712 signatures.

install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/amitbiswas1992/soho" ~/.claude/skills/openclaw-skills-sohopay && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/amitbiswas1992/soho" ~/.openclaw/skills/openclaw-skills-sohopay && rm -rf "$T"
manifest: skills/amitbiswas1992/soho/SKILL.md
source content

SOHO Pay - Credit Layer Payments

This skill allows the agent to initiate payments through the SOHO Pay

Creditor
smart contract using the
spendWithAuthorization
EIP-712 flow.

The agent signs the payment authorization off-chain using a pre-configured wallet, and then submits the transaction to the network on the user's behalf.

Core Command

The primary way to use this skill is with a natural language command that maps to:

pay <amount> to <merchant_address>

  • <amount>
    : The numerical amount to pay (e.g.,
    10
    ,
    0.5
    ).
  • <merchant_address>
    : The recipient EVM address (
    0x...
    ). Names are not supported and no random addresses are ever generated by this skill.

Workflow

Payments (credit spend)

When you issue a

pay
command, the skill performs the following actions:

  1. Parse Inputs: Extracts the amount and merchant address from the user's request.
  2. Validate Merchant Address: Confirms that the merchant is a valid EVM address; otherwise it aborts.
  3. Pre-Flight Checks (BorrowerManager):
    • Verifies the borrower is registered and active.
    • Checks if the credit limit is sufficient for the requested amount.
    • On demand, can auto-register the agent once via
      registerAgent
      .
  4. Generate Authorization: Creates an EIP-712 typed data message for the payment.
  5. Sign Off-Chain: Uses the configured
    PRIVATE_KEY
    wallet (from environment variables) to sign the authorization message.
  6. Execute On-Chain: Calls the
    spendWithAuthorization
    function on the
    Creditor
    contract, providing the signed message.
  7. Report Result: Returns the transaction hash to the user upon confirmation.

Status / Profile checks

The

status
helper reads the BorrowerManager profile + USDC wallet balance for the bot:

  • Calls the
    s_borrowerProfiles(address)
    public mapping getter to fetch:
    creditLimit, outstandingDebt, totalSpent, totalRepaid, spendingCount, repaymentCount, lastActivityTime, creditScore, isActive, isAgent, transactionIds
    .
  • Calls
    IERC20(USDC).balanceOf(bot)
    to fetch the USDC wallet balance for the same address.
  • Prints a human-readable summary so you can see, per network:
    • Whether the bot is registered / active
    • Credit limit and whether the profile is flagged as an agent
    • Outstanding debt and historical spend/repay totals
    • Last activity timestamp and credit score
    • USDC balance available in the wallet

This is what powers prompts like:

  • "check my bot status on testnet"
  • "check my bot outstanding debt on mainnet"

Repayments (reduce outstanding debt)

The

repay
helper uses USDC to pay down outstandingDebt tracked by BorrowerManager and Creditor:

  1. Pre-flight checks:
    • Verifies the borrower is registered and active.
    • Reads current credit limit and any existing outstandingDebt`.
  2. USDC balance & allowance:
    • Ensures the bot wallet has enough USDC balance for the requested repayment.
    • Checks
      IERC20(USDC).allowance(bot, Creditor)
      and, if too low, sends an
      approve(Creditor, amount)
      tx first.
  3. On-chain repay:
    • Calls
      Creditor.repay(amount, USDC)
      from the borrower wallet.
    • The Creditor contract:
      • Caps the repayment to
        min(amount, outstandingDebt)
        .
      • Applies payments to BNPL plans via
        applyPaymentToPlans
        .
      • Updates the borrower profile via
        updateOnRepayment
        (new score + limit).
      • Transfers USDC from the borrower to the Vault and calls
        vault.repayVaultDebt
        .
    • Emits a repayment event with the new score and limit.
  4. Status after repay:
    • After a successful repay, you can run
      status
      again to verify:
      • outstandingDebt
        has decreased (or is
        0
        ),
      • totalRepaid
        increased,
      • creditScore
        and
        creditLimit
        have been updated.

This is what backs prompts like:

  • "repay my bot debt on testnet"
  • "repay 5 USDC of my bot debt on mainnet"

Configuration

  • Environment Variable (runtime): The private key for the signing wallet must be provided via the
    PRIVATE_KEY
    environment variable.
  • Why the private key is needed: OpenClaw is designed to run as an autonomous agent. For it to initiate SOHO Pay transactions without human clicks, it must be able to sign EIP-712 authorizations itself.
  • Local-only usage (important):
    PRIVATE_KEY
    is used only locally on the machine running OpenClaw. The raw key is never sent to SOHO Pay, ClawHub, or any external service — only signed messages and transactions leave the machine.
    Anyone running this bot must understand that the key controls whatever funds are on the selected network.
  • Skill Metadata: The skill declares
    PRIVATE_KEY
    as a required, sensitive credential. You can use a single key for both Base mainnet and Base Sepolia, but be aware this may control real funds on mainnet.
  • Networks: The script supports both Base mainnet (default) and Base Sepolia (testnet). It enforces the expected
    chainId
    for the selected network and aborts if the RPC does not match.

Defaults

The following values are hardcoded into the script for consistency, and are used on both Base mainnet and Base Sepolia:

  • Creditor Contract:
    0xdb34d612dd9aa548f6c94af118f82a461a835e09
  • Borrower Manager:
    0xc6ecd37c42ee73714956b6a449b41bc1d46b07b0
  • Asset (USDC):
    0x43848d5a4efa0b1c72e1fd8ece1abf42e9d5e221
    (6 decimals)
  • Payment Plan ID:
    0

Setup, Installation & Dependencies

This skill is a small Node.js project under

skills/sohopay
.

  1. Set

    PRIVATE_KEY
    in the environment where OpenClaw runs:

    export PRIVATE_KEY=0xYOUR_KEY_HERE
    

    This address will be the SOHO Pay "agent" on Base mainnet / Base Sepolia.

  2. Install the skill and dependencies:

    clawhub install sohopay
    cd skills/sohopay
    npm install
    

    This installs the runtime dependencies declared in

    package.json
    (currently
    ethers
    and
    dotenv
    ).

  3. Register the agent once on the chosen network (before making payments):

    # Base mainnet (default)
    node scripts/register.js
    
    # Explicit mainnet
    node scripts/register.js mainnet
    
    # Base Sepolia testnet
    node scripts/register.js testnet
    

    This calls

    registerAgent(agent)
    on the
    BorrowerManager
    contract using the
    PRIVATE_KEY
    address.

  4. Make payments after registration using

    scripts/pay.js
    :

    # Base mainnet (default when no network arg is given)
    node scripts/pay.js 10 0xMerchantOnMainnet
    
    # Explicit mainnet
    node scripts/pay.js mainnet 10 0xMerchantOnMainnet
    
    # Base Sepolia testnet
    node scripts/pay.js testnet 10 0xMerchantOnTestnet
    

    This uses the SOHO Pay Creditor contract to spend on credit via

    spendWithAuthorization
    .

  5. Check status / profile and balances using

    scripts/status.js
    :

    # Base mainnet
    node scripts/status.js mainnet
    
    # Base Sepolia testnet
    node scripts/status.js testnet
    

    This reads the BorrowerManager profile and USDC wallet balance for the agent and prints a human-readable summary (credit limit, outstanding debt, totals, scores, and USDC balance).

  6. Repay outstanding debt using USDC with

    scripts/repay.js
    :

    # Base mainnet
    node scripts/repay.js mainnet 10
    
    # Base Sepolia testnet
    node scripts/repay.js testnet 10
    

    This uses USDC from the agent wallet to repay

    outstandingDebt
    via the Creditor contract, updating the borrower profile and vault debt, and emitting a repayment event.

Security Notes

  • PRIVATE_KEY
    is highly sensitive
    . Treat it exactly like the key to a normal wallet: anyone with this value can move all funds it controls.
  • Local signing only: The script signs transactions locally and never transmits the raw private key over the network. Only signatures and transactions are sent to RPC endpoints.
  • This skill never triggers itself; it is only executed when called by a user, cron job, or higher-level workflow. It is safe to wire into autonomous flows (e.g. “if price < 10, then pay …”) as long as you understand what those automations will do with your
    PRIVATE_KEY
    .
  • The merchant must be provided as an explicit
    merchant_address
    . If the address is wrong, funds on that network may be irrecoverably sent to the wrong account.
  • No random address generation is performed. The skill will refuse non-address merchant inputs.

Example Usage

Natural-language commands

These are the kinds of prompts you can send to your OpenClaw agent once the skill is installed and

PRIVATE_KEY
is configured.

  • Register bot (testnet)

    "register my bot to use sohopay on Base Sepolia testnet"

  • Register bot (mainnet)

    "register my bot to use sohopay on Base mainnet"

  • Pay a merchant (EIP‑712 spendWithAuthorization)

    "pay 10 USDC to 0x1234567890abcdef1234567890abcdef12345678 on testnet using sohopay"

  • Check bot status (credit limit, outstanding debt, totals, USDC balance)

    "check my bot status on testnet"

    "check my bot outstanding debt on mainnet"

  • Repay debt (calls

    Creditor.repay(amount, stablecoin)
    )
    "repay my bot debt on testnet"

    "repay 5 USDC of my bot debt on mainnet"

Script entrypoints (for reference)

  • Registration:

    node scripts/register.js [mainnet|testnet] [check]

    • node scripts/register.js testnet
      – register bot on Base Sepolia
    • node scripts/register.js mainnet check
      – status only, no tx
  • Payments (credit spend):

    • node scripts/pay.js [mainnet|testnet] <amount> <merchant_address>
  • Status (profile + outstanding debt + USDC balance):

    • node scripts/status.js mainnet
    • node scripts/status.js testnet
  • Repayments (reduce outstanding debt using USDC):

    • node scripts/repay.js [mainnet|testnet] <amount>

When mapped through OpenClaw, you should prefer natural-language prompts; the scripts above are provided for debugging and manual CLI use.