{
  "schemaVersion": "1.0",
  "item": {
    "slug": "sohopay",
    "name": "SOHO Pay Credit Layer",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/nmsteve/sohopay",
    "canonicalUrl": "https://clawhub.ai/nmsteve/sohopay",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/sohopay",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=sohopay",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "_meta.json",
      "package-lock.json",
      "package.json",
      "scripts/pay.js",
      "scripts/register.js"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/sohopay"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/sohopay",
    "agentPageUrl": "https://openagent3.xyz/skills/sohopay/agent",
    "manifestUrl": "https://openagent3.xyz/skills/sohopay/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/sohopay/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "SOHO Pay - Credit Layer Payments",
        "body": "This skill allows the agent to initiate payments through the SOHO Pay Creditor smart contract using the spendWithAuthorization EIP-712 flow.\n\nThe 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."
      },
      {
        "title": "Core Command",
        "body": "The primary way to use this skill is with a natural language command that maps to:\n\npay <amount> to <merchant_address>\n\n<amount>: The numerical amount to pay (e.g., 10, 0.5).\n<merchant_address>: The recipient EVM address (0x...). Names are not supported and no random addresses are ever generated by this skill."
      },
      {
        "title": "Payments (credit spend)",
        "body": "When you issue a pay command, the skill performs the following actions:\n\nParse Inputs: Extracts the amount and merchant address from the user's request.\nValidate Merchant Address: Confirms that the merchant is a valid EVM address; otherwise it aborts.\nPre-Flight Checks (BorrowerManager):\n\nVerifies the borrower is registered and active.\nChecks if the credit limit is sufficient for the requested amount.\nOn demand, can auto-register the agent once via registerAgent.\n\n\nGenerate Authorization: Creates an EIP-712 typed data message for the payment.\nSign Off-Chain: Uses the configured PRIVATE_KEY wallet (from environment variables) to sign the authorization message.\nExecute On-Chain: Calls the spendWithAuthorization function on the Creditor contract, providing the signed message.\nReport Result: Returns the transaction hash to the user upon confirmation."
      },
      {
        "title": "Status / Profile checks",
        "body": "The status helper reads the BorrowerManager profile + USDC wallet balance for the bot:\n\nCalls the s_borrowerProfiles(address) public mapping getter to fetch:\ncreditLimit, outstandingDebt, totalSpent, totalRepaid, spendingCount, repaymentCount, lastActivityTime, creditScore, isActive, isAgent, transactionIds.\nCalls IERC20(USDC).balanceOf(bot) to fetch the USDC wallet balance for the same address.\nPrints a human-readable summary so you can see, per network:\n\nWhether the bot is registered / active\nCredit limit and whether the profile is flagged as an agent\nOutstanding debt and historical spend/repay totals\nLast activity timestamp and credit score\nUSDC balance available in the wallet\n\nThis is what powers prompts like:\n\n\"check my bot status on testnet\"\n\"check my bot outstanding debt on mainnet\""
      },
      {
        "title": "Repayments (reduce outstanding debt)",
        "body": "The repay helper uses USDC to pay down outstandingDebt tracked by BorrowerManager and Creditor:\n\nPre-flight checks:\n\nVerifies the borrower is registered and active.\nReads current credit limit and any existing outstandingDebt`.\n\n\nUSDC balance & allowance:\n\nEnsures the bot wallet has enough USDC balance for the requested repayment.\nChecks IERC20(USDC).allowance(bot, Creditor) and, if too low, sends an approve(Creditor, amount) tx first.\n\n\nOn-chain repay:\n\nCalls Creditor.repay(amount, USDC) from the borrower wallet.\nThe Creditor contract:\n\nCaps the repayment to min(amount, outstandingDebt).\nApplies payments to BNPL plans via applyPaymentToPlans.\nUpdates the borrower profile via updateOnRepayment (new score + limit).\nTransfers USDC from the borrower to the Vault and calls vault.repayVaultDebt.\n\n\nEmits a repayment event with the new score and limit.\n\n\nStatus after repay:\n\nAfter a successful repay, you can run status again to verify:\n\noutstandingDebt has decreased (or is 0),\ntotalRepaid increased,\ncreditScore and creditLimit have been updated.\n\nThis is what backs prompts like:\n\n\"repay my bot debt on testnet\"\n\"repay 5 USDC of my bot debt on mainnet\""
      },
      {
        "title": "Configuration",
        "body": "Environment Variable (runtime): The private key for the signing wallet must be provided via the PRIVATE_KEY environment variable.\nWhy 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.\nLocal-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.\nSkill 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.\nNetworks: 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."
      },
      {
        "title": "Defaults",
        "body": "The following values are hardcoded into the script for consistency, and are used on both Base mainnet and Base Sepolia:\n\nCreditor Contract: 0xdb34d612dd9aa548f6c94af118f82a461a835e09\nBorrower Manager: 0xc6ecd37c42ee73714956b6a449b41bc1d46b07b0\nAsset (USDC): 0x43848d5a4efa0b1c72e1fd8ece1abf42e9d5e221 (6 decimals)\nPayment Plan ID: 0"
      },
      {
        "title": "Setup, Installation & Dependencies",
        "body": "This skill is a small Node.js project under skills/sohopay.\n\nSet PRIVATE_KEY in the environment where OpenClaw runs:\nexport PRIVATE_KEY=0xYOUR_KEY_HERE\n\nThis address will be the SOHO Pay \"agent\" on Base mainnet / Base Sepolia.\n\n\nInstall the skill and dependencies:\nclawhub install sohopay\ncd skills/sohopay\nnpm install\n\nThis installs the runtime dependencies declared in package.json (currently ethers and dotenv).\n\n\nRegister the agent once on the chosen network (before making payments):\n# Base mainnet (default)\nnode scripts/register.js\n\n# Explicit mainnet\nnode scripts/register.js mainnet\n\n# Base Sepolia testnet\nnode scripts/register.js testnet\n\nThis calls registerAgent(agent) on the BorrowerManager contract using the PRIVATE_KEY address.\n\n\nMake payments after registration using scripts/pay.js:\n# Base mainnet (default when no network arg is given)\nnode scripts/pay.js 10 0xMerchantOnMainnet\n\n# Explicit mainnet\nnode scripts/pay.js mainnet 10 0xMerchantOnMainnet\n\n# Base Sepolia testnet\nnode scripts/pay.js testnet 10 0xMerchantOnTestnet\n\nThis uses the SOHO Pay Creditor contract to spend on credit via spendWithAuthorization.\n\n\nCheck status / profile and balances using scripts/status.js:\n# Base mainnet\nnode scripts/status.js mainnet\n\n# Base Sepolia testnet\nnode scripts/status.js testnet\n\nThis 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).\n\n\nRepay outstanding debt using USDC with scripts/repay.js:\n# Base mainnet\nnode scripts/repay.js mainnet 10\n\n# Base Sepolia testnet\nnode scripts/repay.js testnet 10\n\nThis 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."
      },
      {
        "title": "Security Notes",
        "body": "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.\nLocal 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.\nThis 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.\nThe 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.\nNo random address generation is performed. The skill will refuse non-address merchant inputs."
      },
      {
        "title": "Natural-language commands",
        "body": "These are the kinds of prompts you can send to your OpenClaw agent once the skill is installed and PRIVATE_KEY is configured.\n\nRegister bot (testnet)\n\"register my bot to use sohopay on Base Sepolia testnet\"\n\n\nRegister bot (mainnet)\n\"register my bot to use sohopay on Base mainnet\"\n\n\nPay a merchant (EIP‑712 spendWithAuthorization)\n\"pay 10 USDC to 0x1234567890abcdef1234567890abcdef12345678 on testnet using sohopay\"\n\n\nCheck bot status (credit limit, outstanding debt, totals, USDC balance)\n\"check my bot status on testnet\"\n\"check my bot outstanding debt on mainnet\"\n\n\nRepay debt (calls Creditor.repay(amount, stablecoin))\n\"repay my bot debt on testnet\"\n\"repay 5 USDC of my bot debt on mainnet\""
      },
      {
        "title": "Script entrypoints (for reference)",
        "body": "Registration: node scripts/register.js [mainnet|testnet] [check]\n\nnode scripts/register.js testnet – register bot on Base Sepolia\nnode scripts/register.js mainnet check – status only, no tx\n\n\n\nPayments (credit spend):\n\nnode scripts/pay.js [mainnet|testnet] <amount> <merchant_address>\n\n\n\nStatus (profile + outstanding debt + USDC balance):\n\nnode scripts/status.js mainnet\nnode scripts/status.js testnet\n\n\n\nRepayments (reduce outstanding debt using USDC):\n\nnode scripts/repay.js [mainnet|testnet] <amount>\n\nWhen mapped through OpenClaw, you should prefer natural-language prompts; the scripts above are provided for debugging and manual CLI use."
      }
    ],
    "body": "SOHO Pay - Credit Layer Payments\n\nThis skill allows the agent to initiate payments through the SOHO Pay Creditor smart contract using the spendWithAuthorization EIP-712 flow.\n\nThe 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.\n\nCore Command\n\nThe primary way to use this skill is with a natural language command that maps to:\n\npay <amount> to <merchant_address>\n\n<amount>: The numerical amount to pay (e.g., 10, 0.5).\n<merchant_address>: The recipient EVM address (0x...). Names are not supported and no random addresses are ever generated by this skill.\nWorkflow\nPayments (credit spend)\n\nWhen you issue a pay command, the skill performs the following actions:\n\nParse Inputs: Extracts the amount and merchant address from the user's request.\nValidate Merchant Address: Confirms that the merchant is a valid EVM address; otherwise it aborts.\nPre-Flight Checks (BorrowerManager):\nVerifies the borrower is registered and active.\nChecks if the credit limit is sufficient for the requested amount.\nOn demand, can auto-register the agent once via registerAgent.\nGenerate Authorization: Creates an EIP-712 typed data message for the payment.\nSign Off-Chain: Uses the configured PRIVATE_KEY wallet (from environment variables) to sign the authorization message.\nExecute On-Chain: Calls the spendWithAuthorization function on the Creditor contract, providing the signed message.\nReport Result: Returns the transaction hash to the user upon confirmation.\nStatus / Profile checks\n\nThe status helper reads the BorrowerManager profile + USDC wallet balance for the bot:\n\nCalls the s_borrowerProfiles(address) public mapping getter to fetch:\ncreditLimit, outstandingDebt, totalSpent, totalRepaid, spendingCount, repaymentCount, lastActivityTime, creditScore, isActive, isAgent, transactionIds.\nCalls IERC20(USDC).balanceOf(bot) to fetch the USDC wallet balance for the same address.\nPrints a human-readable summary so you can see, per network:\nWhether the bot is registered / active\nCredit limit and whether the profile is flagged as an agent\nOutstanding debt and historical spend/repay totals\nLast activity timestamp and credit score\nUSDC balance available in the wallet\n\nThis is what powers prompts like:\n\n\"check my bot status on testnet\"\n\"check my bot outstanding debt on mainnet\"\nRepayments (reduce outstanding debt)\n\nThe repay helper uses USDC to pay down outstandingDebt tracked by BorrowerManager and Creditor:\n\nPre-flight checks:\nVerifies the borrower is registered and active.\nReads current credit limit and any existing outstandingDebt`.\nUSDC balance & allowance:\nEnsures the bot wallet has enough USDC balance for the requested repayment.\nChecks IERC20(USDC).allowance(bot, Creditor) and, if too low, sends an approve(Creditor, amount) tx first.\nOn-chain repay:\nCalls Creditor.repay(amount, USDC) from the borrower wallet.\nThe Creditor contract:\nCaps the repayment to min(amount, outstandingDebt).\nApplies payments to BNPL plans via applyPaymentToPlans.\nUpdates the borrower profile via updateOnRepayment (new score + limit).\nTransfers USDC from the borrower to the Vault and calls vault.repayVaultDebt.\nEmits a repayment event with the new score and limit.\nStatus after repay:\nAfter a successful repay, you can run status again to verify:\noutstandingDebt has decreased (or is 0),\ntotalRepaid increased,\ncreditScore and creditLimit have been updated.\n\nThis is what backs prompts like:\n\n\"repay my bot debt on testnet\"\n\"repay 5 USDC of my bot debt on mainnet\"\nConfiguration\nEnvironment Variable (runtime): The private key for the signing wallet must be provided via the PRIVATE_KEY environment variable.\nWhy 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.\nLocal-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.\nSkill 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.\nNetworks: 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.\nDefaults\n\nThe following values are hardcoded into the script for consistency, and are used on both Base mainnet and Base Sepolia:\n\nCreditor Contract: 0xdb34d612dd9aa548f6c94af118f82a461a835e09\nBorrower Manager: 0xc6ecd37c42ee73714956b6a449b41bc1d46b07b0\nAsset (USDC): 0x43848d5a4efa0b1c72e1fd8ece1abf42e9d5e221 (6 decimals)\nPayment Plan ID: 0\nSetup, Installation & Dependencies\n\nThis skill is a small Node.js project under skills/sohopay.\n\nSet PRIVATE_KEY in the environment where OpenClaw runs:\n\nexport PRIVATE_KEY=0xYOUR_KEY_HERE\n\n\nThis address will be the SOHO Pay \"agent\" on Base mainnet / Base Sepolia.\n\nInstall the skill and dependencies:\n\nclawhub install sohopay\ncd skills/sohopay\nnpm install\n\n\nThis installs the runtime dependencies declared in package.json (currently ethers and dotenv).\n\nRegister the agent once on the chosen network (before making payments):\n\n# Base mainnet (default)\nnode scripts/register.js\n\n# Explicit mainnet\nnode scripts/register.js mainnet\n\n# Base Sepolia testnet\nnode scripts/register.js testnet\n\n\nThis calls registerAgent(agent) on the BorrowerManager contract using the PRIVATE_KEY address.\n\nMake payments after registration using scripts/pay.js:\n\n# Base mainnet (default when no network arg is given)\nnode scripts/pay.js 10 0xMerchantOnMainnet\n\n# Explicit mainnet\nnode scripts/pay.js mainnet 10 0xMerchantOnMainnet\n\n# Base Sepolia testnet\nnode scripts/pay.js testnet 10 0xMerchantOnTestnet\n\n\nThis uses the SOHO Pay Creditor contract to spend on credit via spendWithAuthorization.\n\nCheck status / profile and balances using scripts/status.js:\n\n# Base mainnet\nnode scripts/status.js mainnet\n\n# Base Sepolia testnet\nnode scripts/status.js testnet\n\n\nThis 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).\n\nRepay outstanding debt using USDC with scripts/repay.js:\n\n# Base mainnet\nnode scripts/repay.js mainnet 10\n\n# Base Sepolia testnet\nnode scripts/repay.js testnet 10\n\n\nThis 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.\n\nSecurity Notes\nPRIVATE_KEY is highly sensitive. Treat it exactly like the key to a normal wallet: anyone with this value can move all funds it controls.\nLocal 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.\nThis 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.\nThe 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.\nNo random address generation is performed. The skill will refuse non-address merchant inputs.\nExample Usage\nNatural-language commands\n\nThese are the kinds of prompts you can send to your OpenClaw agent once the skill is installed and PRIVATE_KEY is configured.\n\nRegister bot (testnet)\n\"register my bot to use sohopay on Base Sepolia testnet\"\n\nRegister bot (mainnet)\n\"register my bot to use sohopay on Base mainnet\"\n\nPay a merchant (EIP‑712 spendWithAuthorization)\n\"pay 10 USDC to 0x1234567890abcdef1234567890abcdef12345678 on testnet using sohopay\"\n\nCheck bot status (credit limit, outstanding debt, totals, USDC balance)\n\"check my bot status on testnet\"\n\"check my bot outstanding debt on mainnet\"\n\nRepay debt (calls Creditor.repay(amount, stablecoin))\n\"repay my bot debt on testnet\"\n\"repay 5 USDC of my bot debt on mainnet\"\n\nScript entrypoints (for reference)\n\nRegistration: node scripts/register.js [mainnet|testnet] [check]\n\nnode scripts/register.js testnet – register bot on Base Sepolia\nnode scripts/register.js mainnet check – status only, no tx\n\nPayments (credit spend):\n\nnode scripts/pay.js [mainnet|testnet] <amount> <merchant_address>\n\nStatus (profile + outstanding debt + USDC balance):\n\nnode scripts/status.js mainnet\nnode scripts/status.js testnet\n\nRepayments (reduce outstanding debt using USDC):\n\nnode scripts/repay.js [mainnet|testnet] <amount>\n\nWhen mapped through OpenClaw, you should prefer natural-language prompts; the scripts above are provided for debugging and manual CLI use."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/nmsteve/sohopay",
    "publisherUrl": "https://clawhub.ai/nmsteve/sohopay",
    "owner": "nmsteve",
    "version": "1.0.17",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/sohopay",
    "downloadUrl": "https://openagent3.xyz/downloads/sohopay",
    "agentUrl": "https://openagent3.xyz/skills/sohopay/agent",
    "manifestUrl": "https://openagent3.xyz/skills/sohopay/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/sohopay/agent.md"
  }
}