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:
INLINECODE2
- -
<amount>: The numerical amount to pay (e.g., 10, 0.5). - INLINECODE6 : 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.
- Validate Merchant Address: Confirms that the merchant is a valid EVM address; otherwise it aborts.
- 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.
- Sign Off-Chain: Uses the configured
PRIVATE_KEY wallet (from environment variables) to sign the authorization message. - Execute On-Chain: Calls the
spendWithAuthorization function on the Creditor contract, providing the signed message. - 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:
- - INLINECODE17
- INLINECODE18
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)**: **PRIVATEKEY
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 PRIVATEKEY
** in the environment where OpenClaw runs:
CODEBLOCK0
This address will be the SOHO Pay "agent" on Base mainnet / Base Sepolia.
2. **Install the skill and dependencies**:
CODEBLOCK1
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):
CODEBLOCK2
This calls registerAgent(agent)
on the BorrowerManager
contract using the PRIVATE
KEY address.
4. **Make payments after registration** using scripts/pay.js:
CODEBLOCK3
This uses the SOHO Pay Creditor contract to spend on credit via spendWithAuthorization.
5. **Check status / profile and balances** using scripts/status.js:
CODEBLOCK4
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:
CODEBLOCK5
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
- **PRIVATEKEY
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 merchantaddress
. 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] 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] `
When mapped through OpenClaw, you should prefer natural-language prompts; the scripts above are provided for debugging and manual CLI use.
SOHO Pay - 信用层支付
该技能允许代理通过SOHO Pay的Creditor智能合约,使用spendWithAuthorization EIP-712流程发起支付。
代理使用预配置的钱包在链下签署支付授权,然后代表用户将交易提交到网络。
核心命令
使用该技能的主要方式是通过自然语言命令,映射到:
pay <金额> to <商户地址>
- - <金额>:支付的数值(例如 10、0.5)。
- <商户地址>:接收方的EVM地址(0x...)。不支持名称,该技能不会生成任何随机地址。
工作流程
支付(信用消费)
当您发出pay命令时,技能执行以下操作:
- 1. 解析输入:从用户请求中提取金额和商户地址。
- 验证商户地址:确认商户是有效的EVM地址;否则中止。
- 预检检查(BorrowerManager):
- 验证借款人是否已
注册且
活跃。
- 检查
信用额度是否足够支付请求金额。
- 按需可通过registerAgent自动注册代理一次。
- 4. 生成授权:为支付创建EIP-712类型化数据消息。
- 链下签名:使用配置的PRIVATE_KEY钱包(来自环境变量)签署授权消息。
- 链上执行:调用Creditor合约上的spendWithAuthorization函数,提供已签名的消息。
- 报告结果:确认后向用户返回交易哈希。
状态/资料检查
status辅助函数读取机器人的BorrowerManager资料 + USDC钱包余额:
- - 调用s_borrowerProfiles(address)公共映射getter获取:
creditLimit, outstandingDebt, totalSpent, totalRepaid, spendingCount, repaymentCount, lastActivityTime, creditScore, isActive, isAgent, transactionIds。
- - 调用IERC20(USDC).balanceOf(bot)获取同一地址的USDC钱包余额。
- 打印人类可读的摘要,以便您查看每个网络:
- 机器人是否已注册/活跃
- 信用额度以及资料是否被标记为代理
-
未偿债务和历史消费/还款总额
- 最后活动时间戳和信用评分
- 钱包中可用的USDC余额
这支持以下提示:
- - check my bot status on testnet
- check my bot outstanding debt on mainnet
还款(减少未偿债务)
repay辅助函数使用USDC偿还BorrowerManager和Creditor跟踪的outstandingDebt:
- 1. 预检检查:
- 验证借款人是否已
注册且
活跃。
- 读取当前
信用额度和任何现有
outstandingDebt。
- 2. USDC余额和授权:
- 确保机器人钱包有足够的
USDC余额用于请求的还款。
- 检查IERC20(USDC).allowance(bot, Creditor),如果太低,首先发送approve(Creditor, amount)交易。
- 3. 链上还款:
- 从借款人钱包调用Creditor.repay(amount, USDC)。
- Creditor合约:
- 将还款上限设为min(amount, outstandingDebt)。
- 通过applyPaymentToPlans将付款应用于BNPL计划。
- 通过updateOnRepayment更新借款人资料(新评分+额度)。
- 将USDC从借款人转移到Vault并调用vault.repayVaultDebt。
- 发出包含新评分和额度的还款事件。
- 4. 还款后状态:
- 成功还款后,您可以再次运行status验证:
- outstandingDebt已减少(或为0),
- totalRepaid增加,
- creditScore和creditLimit已更新。
这支持以下提示:
- - repay my bot debt on testnet
- repay 5 USDC of my bot debt on mainnet
配置
- - 环境变量(运行时):签名钱包的私钥必须通过PRIVATEKEY环境变量提供。
- 为什么需要私钥:OpenClaw被设计为作为自主代理运行。为了让它无需人工点击即可发起SOHO Pay交易,它必须能够自行签署EIP-712授权。
- 仅本地使用(重要):PRIVATEKEY仅在运行OpenClaw的机器上本地使用。原始密钥从不发送给SOHO Pay、ClawHub或任何外部服务——只有已签名的消息和交易离开机器。任何运行此机器人的用户必须理解,该密钥控制所选网络上的任何资金。
- 技能元数据:该技能将PRIVATE_KEY声明为必需的敏感凭证。您可以为Base主网和Base Sepolia使用同一个密钥,但请注意这可能会控制主网上的真实资金。
- 网络:脚本支持Base主网(默认)和Base Sepolia(测试网)。它强制执行所选网络的预期chainId,如果RPC不匹配则中止。
默认值
以下值硬编码在脚本中以保持一致性,并在Base主网和Base Sepolia上使用:
- - Creditor合约:0xdb34d612dd9aa548f6c94af118f82a461a835e09
- Borrower Manager:0xc6ecd37c42ee73714956b6a449b41bc1d46b07b0
- 资产(USDC):0x43848d5a4efa0b1c72e1fd8ece1abf42e9d5e221(6位小数)
- 支付计划ID:0
设置、安装和依赖
该技能是skills/sohopay下的一个小型Node.js项目。
- 1. 在OpenClaw运行的环境中设置PRIVATE_KEY:
bash
export PRIVATE
KEY=0xYOURKEY_HERE
该地址将成为Base主网/Base Sepolia上的SOHO Pay代理。
- 2. 安装技能和依赖:
bash
clawhub install sohopay
cd skills/sohopay
npm install
这将安装package.json中声明的运行时依赖(当前为ethers和dotenv)。
- 3. 在所选网络上注册代理一次(在支付之前):
bash
# Base主网(默认)
node scripts/register.js
# 显式主网
node scripts/register.js mainnet
# Base Sepolia测试网
node scripts/register.js testnet
这将使用PRIVATE_KEY地址在BorrowerManager合约上调用registerAgent(agent)。
- 4. 注册后使用scripts/pay.js进行支付:
bash
# Base主网(未提供网络参数时的默认值)
node scripts/pay.js 10 0xMerchantOnMainnet
# 显式主网
node scripts/pay.js mainnet 10 0xMerchantOnMainnet
# Base Sepolia测试网
node scripts/pay.js testnet 10 0xMerchantOnTestnet
这将使用SOHO Pay Creditor合约通过spendWithAuthorization进行信用消费。
- 5. 使用scripts/status.js检查状态/资料和余额:
bash
# Base主网
node scripts/status.js mainnet
# Base Sepolia测试网
node scripts/status.js testnet
这将读取代理的BorrowerManager资料和USDC钱包余额,并打印人类可读的摘要(信用额度、未偿债务、总额、评分和USDC余额)。
- 6. 使用USDC通过scripts/repay.js偿还未偿债务:
bash
# Base主网
node scripts/repay.js mainnet 10
# Base Sepolia测试网
node scripts/repay.js testnet 10
这将使用代理钱包中的USDC通过Creditor合约偿还outstandingDebt,更新借款人资料和金库债务,并发出还款事件。
安全说明
- - PRIVATEKEY高度敏感。请像对待普通钱包密钥一样对待它:任何拥有此值的人都可以转移其控制的所有资金。
- 仅本地签名:脚本在本地签署交易,从不通过网络传输原始私钥。只有签名和交易被发送到RPC端点。
- 该技能从不自行触发;仅在用户、cron作业或更高级别工作流调用时执行。只要您理解这些自动化将如何使用您的PRIVATEKEY,将其接入自主流程(例如