createos-deploy

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Deploy to CreateOS

部署到CreateOS

No auth session, no OAuth, no browser login required. This skill uses the HTTP 402 payment flow — the on-chain payment itself is the access control. Just call the API, pay with USDC/USDT, and deploy.
无需认证会话、无需OAuth、无需浏览器登录。 该技能使用HTTP 402支付流程——链上支付本身就是访问控制。只需调用API,使用USDC/USDT支付,即可完成部署。

Prerequisites

前置条件

You need an EVM wallet with gas (ETH) and USDC on a supported chain. Generate one if needed:
ts
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);
// Save privateKey securely
Only dependency:
npm install viem
你需要一个在支持链上拥有gas(ETH)和USDC的EVM钱包。如果需要,可生成一个:
ts
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);
// 安全保存privateKey
唯一依赖:
npm install viem

Flow

流程

  1. POST /agent/deploy
    (no payment) — gateway checks credits AND active projects
    • Has credits, no active projects → deploys directly, returns 200. Skip to step 5.
    • Has credits, has active projects → returns 402 with a warning. The agent must either:
      • Pay to extend total runtime (recommended), OR
      • Retry with header
        X-Use-Existing-Credits: true
        to deploy using existing credits (this will reduce runtime of the other active projects)
    • No credits → returns 402 with
      pay_to
      ,
      amount_token
      ,
      payment_chain
      ,
      supported_chains
  2. GET /agent/balance/:address?chain=...
    — check token balance on each supported chain
  3. If no chain has enough balance, stop and tell the user:
    "Your wallet
    0x...
    doesn't have enough funds to deploy. Please add {amount_usd} {token} on {chain} to address
    0x...
    ."
    Show all supported chains so the user can pick one to fund.
  4. Send ERC20 transfer to
    pay_to
    using viem → get
    txHash
    POST /agent/deploy
    with
    X-Payment-Tx: txHash
    → verifies payment, topups credits, deploys
  5. GET /agent/deploy/:projectId/:deploymentId/status
    → poll until ready
  1. POST /agent/deploy
    (无需支付)——网关检查额度和活跃项目
    • 有额度、无活跃项目 → 直接部署,返回200。跳至步骤5。
    • 有额度、有活跃项目 → 返回402并附带警告。Agent需选择:
      • 支付以延长总运行时长(推荐),或
      • 添加请求头
        X-Use-Existing-Credits: true
        后重试
        ,使用现有额度部署(这会减少其他活跃项目的运行时长)
    • 无额度 → 返回402,包含
      pay_to
      amount_token
      payment_chain
      supported_chains
      等信息
  2. GET /agent/balance/:address?chain=...
    —— 检查每个支持链上的代币余额
  3. 如果没有任何链的余额足够,停止操作并告知用户
    "你的钱包
    0x...
    余额不足,无法部署。请在**{chain}链上向地址
    0x...
    添加
    {amount_usd} {token}**。"
    展示所有支持链,供用户选择充值的链。
  4. 使用viem向
    pay_to
    地址发送ERC20转账 → 获取
    txHash
    携带
    X-Payment-Tx: txHash
    调用
    POST /agent/deploy
    → 验证支付、充值额度、完成部署
  5. GET /agent/deploy/:projectId/:deploymentId/status
    → 轮询直至部署完成

Credit Sharing & Active Projects

额度共享与活跃项目

NodeOps credits are pooled across all your active projects and consumed hourly. When you have multiple active deployments, they share the same credit balance.
  • If you have 0 active projects and credits: deploys for free, no impact.
  • If you have 1+ active projects and you deploy without paying, the new project will share the credit pool — reducing runtime of the other projects.
  • The gateway prevents this by default: if you have active projects, you must either pay (to add fresh credits) or explicitly opt in via
    X-Use-Existing-Credits: true
    .
Always tell the user when their deploy will affect other active projects, and recommend paying instead.
NodeOps额度在所有活跃项目间共享,按小时消耗。当你拥有多个活跃部署时,它们共用同一额度池。
  • 若你无活跃项目但有额度:免费部署,无影响。
  • 若你有1个及以上活跃项目且不支付就部署,新项目将共享额度池——会减少其他项目的运行时长
  • 网关默认阻止此操作:若你有活跃项目,必须选择支付(添加新额度)或通过
    X-Use-Existing-Credits: true
    显式选择使用现有额度。
务必告知用户,其部署操作是否会影响其他活跃项目,并推荐优先选择支付方式。

Utility Endpoints (no auth required)

实用端点(无需认证)

Check balance — all tokens on a chain:
GET /agent/balance/0xYourWallet?chain=arbitrum
json
{
  "address": "0x...",
  "chain": "arbitrum",
  "balances": [
    { "token": "usdc", "symbol": "USDC", "balance": "18.000000", "decimals": 6 }
  ]
}
List supported chains:
GET /agent/chains
json
{
  "chains": [
    { "chain": "arbitrum", "chain_id": 42161, "tokens": ["usdc", "usdt"] },
    { "chain": "base", "chain_id": 8453, "tokens": ["usdc", "usdt"] }
  ]
}
查询余额 —— 某链上的所有代币:
GET /agent/balance/0xYourWallet?chain=arbitrum
json
{
  "address": "0x...",
  "chain": "arbitrum",
  "balances": [
    { "token": "usdc", "symbol": "USDC", "balance": "18.000000", "decimals": 6 }
  ]
}
列出支持链:
GET /agent/chains
json
{
  "chains": [
    { "chain": "arbitrum", "chain_id": 42161, "tokens": ["usdc", "usdt"] },
    { "chain": "base", "chain_id": 8453, "tokens": ["usdc", "usdt"] }
  ]
}

Auth Headers (all requests)

认证请求头(所有请求)

Sign
{wallet}:{timestamp}:{nonce}
with your private key.
X-Wallet-Address: 0xYourWallet
X-Signature: 0xSignedMessage
X-Timestamp: 1711500000000
X-Nonce: unique-uuid
使用私钥签名
{wallet}:{timestamp}:{nonce}
X-Wallet-Address: 0xYourWallet
X-Signature: 0xSignedMessage
X-Timestamp: 1711500000000
X-Nonce: unique-uuid

List Your Projects (auth required)

列出你的项目(需认证)

GET /agent/projects
Returns all projects deployed by the wallet, with the live URL of the latest deployment for each.
json
{
  "wallet": "0x5B6C...",
  "count": 2,
  "projects": [
    {
      "id": "uuid",
      "name": "demo-1234567890",
      "displayName": "Demo App",
      "status": "active",
      "url": "https://demo-1234567890.nodeops.network",
      "createdAt": "2026-04-07T10:00:00.000Z"
    }
  ]
}
url
will be
null
if the project has no successful deployment yet. Status values:
active
,
building
,
deploying
,
pending
,
queued
,
promoting
,
deleting
,
failed
.
GET /agent/projects
返回钱包部署的所有项目,以及每个项目最新部署的在线URL。
json
{
  "wallet": "0x5B6C...",
  "count": 2,
  "projects": [
    {
      "id": "uuid",
      "name": "demo-1234567890",
      "displayName": "Demo App",
      "status": "active",
      "url": "https://demo-1234567890.nodeops.network",
      "createdAt": "2026-04-07T10:00:00.000Z"
    }
  ]
}
若项目暂无成功部署记录,
url
将为
null
。状态值包括:
active
building
deploying
pending
queued
promoting
deleting
failed

Delete a Project (auth required)

删除项目(需认证)

DELETE /agent/projects/{projectId}
Permanently deletes a project from NodeOps. Only the wallet that originally deployed the project can delete it.
json
{ "projectId": "uuid", "status": "deleted" }
Errors:
403
if the wallet is not the deployer.
DELETE /agent/projects/{projectId}
从NodeOps永久删除项目。仅最初部署该项目的钱包有权删除。
json
{ "projectId": "uuid", "status": "deleted" }
错误:若钱包不是部署者,返回
403

Step 1: Get Quote

步骤1:获取报价

POST /agent/deploy
Content-Type: application/json

{
  "uniqueName": "my-app",
  "displayName": "My App",
  "upload": { "type": "files", "files": [{ "path": "index.js", "content": "base64..." }] }
}
Response
402
(no credits):
json
{
  "error": "Payment required",
  "amount_usd": 0.5,
  "amount_token": "500000",
  "current_credit_balance_usd": 0,
  "active_projects": 0,
  "pay_to": "0x7EA5...",
  "payment_chain": "arbitrum",
  "token": "usdc",
  "decimals": 6,
  "supported_chains": [...]
}
Response
402
(has credits but active projects exist):
json
{
  "error": "Payment required",
  "warning": "You have 2 active project(s) sharing credits. Paying extends total runtime. To deploy using existing credits (will reduce other projects' runtime), retry with header X-Use-Existing-Credits: true",
  "amount_usd": 0.5,
  "current_credit_balance_usd": 1.20,
  "active_projects": 2,
  "pay_to": "0x7EA5...",
  ...
}
POST /agent/deploy
Content-Type: application/json

{
  "uniqueName": "my-app",
  "displayName": "My App",
  "upload": { "type": "files", "files": [{ "path": "index.js", "content": "base64..." }] }
}
无额度时返回
402
json
{
  "error": "Payment required",
  "amount_usd": 0.5,
  "amount_token": "500000",
  "current_credit_balance_usd": 0,
  "active_projects": 0,
  "pay_to": "0x7EA5...",
  "payment_chain": "arbitrum",
  "token": "usdc",
  "decimals": 6,
  "supported_chains": [...]
}
有额度但存在活跃项目时返回
402
json
{
  "error": "Payment required",
  "warning": "You have 2 active project(s) sharing credits. Paying extends total runtime. To deploy using existing credits (will reduce other projects' runtime), retry with header X-Use-Existing-Credits: true",
  "amount_usd": 0.5,
  "current_credit_balance_usd": 1.20,
  "active_projects": 2,
  "pay_to": "0x7EA5...",
  ...
}

Step 2: Pay

步骤2:支付

Send ERC20 transfer with viem:
ts
import { createWalletClient, createPublicClient, http } from "viem";
import { arbitrum } from "viem/chains";

const txHash = await walletClient.writeContract({
  address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on arbitrum
  abi: [
    {
      name: "transfer",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [
        { name: "to", type: "address" },
        { name: "value", type: "uint256" },
      ],
      outputs: [{ name: "", type: "bool" }],
    },
  ],
  functionName: "transfer",
  args: [quote.pay_to, BigInt(quote.amount_token)],
});
await publicClient.waitForTransactionReceipt({ hash: txHash });
使用viem发送ERC20转账:
ts
import { createWalletClient, createPublicClient, http } from "viem";
import { arbitrum } from "viem/chains";

const txHash = await walletClient.writeContract({
  address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on arbitrum
  abi: [
    {
      name: "transfer",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [
        { name: "to", type: "address" },
        { name: "value", type: "uint256" },
      ],
      outputs: [{ name: "", type: "bool" }],
    },
  ],
  functionName: "transfer",
  args: [quote.pay_to, BigInt(quote.amount_token)],
});
await publicClient.waitForTransactionReceipt({ hash: txHash });

Step 3: Deploy

步骤3:部署

Same request body, add payment header:
POST /agent/deploy
X-Payment-Tx: 0xTransactionHash
X-Payment-Chain: arbitrum
X-Payment-Token: usdc
Response
200
:
json
{ "projectId": "uuid", "deploymentId": "uuid", "status": "deploying" }
使用相同的请求体,添加支付请求头:
POST /agent/deploy
X-Payment-Tx: 0xTransactionHash
X-Payment-Chain: arbitrum
X-Payment-Token: usdc
返回
200
json
{ "projectId": "uuid", "deploymentId": "uuid", "status": "deploying" }

Step 4: Poll

步骤4:轮询

GET /agent/deploy/{projectId}/{deploymentId}/status
  • { "status": "deploying" }
    — keep polling every 5s
  • { "status": "ready", "endpoint": "https://..." }
    — done
  • { "status": "failed", "reason": "..." }
    — stop
GET /agent/deploy/{projectId}/{deploymentId}/status
  • { "status": "deploying" }
    —— 每5秒轮询一次
  • { "status": "ready", "endpoint": "https://..." }
    —— 部署完成
  • { "status": "failed", "reason": "..." }
    —— 停止轮询

Upload Types

上传类型

Files:
{ "type": "files", "files": [{ "path": "...", "content": "base64" }] }
Zip:
{ "type": "zip", "data": "base64-zip", "filename": "code.zip" }
Important: When uploading files, exclude build artifacts and dependencies:
  • node_modules/
    ,
    dist/
    ,
    build/
    ,
    .next/
  • .env
    ,
    .env.*
    , keys, secrets
  • .git/
    ,
    .DS_Store
  • __pycache__/
    ,
    venv/
    ,
    .venv/
Only upload source code and config files needed to build and run the project.
文件:
{ "type": "files", "files": [{ "path": "...", "content": "base64" }] }
压缩包:
{ "type": "zip", "data": "base64-zip", "filename": "code.zip" }
重要提示:上传文件时,排除构建产物和依赖项:
  • node_modules/
    ,
    dist/
    ,
    build/
    ,
    .next/
  • .env
    ,
    .env.*
    , 密钥、机密信息
  • .git/
    ,
    .DS_Store
  • __pycache__/
    ,
    venv/
    ,
    .venv/
仅上传构建和运行项目所需的源代码和配置文件。

Error Codes

错误码

CodeMeaning
400Invalid body
401Bad signature / expired / nonce reused
402Payment required or verification failed
403Wrong wallet on status endpoint
409Tx hash already used
429Rate limited (30/min)
代码含义
400请求体无效
401签名错误 / 已过期 / 随机数重复
402需要支付或支付验证失败
403状态端点使用的钱包不正确
409交易哈希已被使用
429请求受限(每分钟最多30次)

Reference

参考

  • api-reference.md — full endpoint specs
  • example.md — complete working example
  • api-reference.md —— 完整端点规格
  • example.md —— 完整可用示例