createos-deploy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDeploy 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 securelyOnly 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 viemFlow
流程
- (no payment) — gateway checks credits AND active projects
POST /agent/deploy- 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 to deploy using existing credits (this will reduce runtime of the other active projects)
X-Use-Existing-Credits: true
- No credits → returns 402 with ,
pay_to,amount_token,payment_chainsupported_chains
- — check token balance on each supported chain
GET /agent/balance/:address?chain=... - If no chain has enough balance, stop and tell the user:
"Your walletdoesn't have enough funds to deploy. Please add {amount_usd} {token} on {chain} to address
0x...."0x...Show all supported chains so the user can pick one to fund. - Send ERC20 transfer to using viem → get
pay_totxHashwithPOST /agent/deploy→ verifies payment, topups credits, deploysX-Payment-Tx: txHash - → poll until ready
GET /agent/deploy/:projectId/:deploymentId/status
- (无需支付)——网关检查额度和活跃项目
POST /agent/deploy- 有额度、无活跃项目 → 直接部署,返回200。跳至步骤5。
- 有额度、有活跃项目 → 返回402并附带警告。Agent需选择:
- 支付以延长总运行时长(推荐),或
- 添加请求头后重试,使用现有额度部署(这会减少其他活跃项目的运行时长)
X-Use-Existing-Credits: true
- 无额度 → 返回402,包含、
pay_to、amount_token、payment_chain等信息supported_chains
- —— 检查每个支持链上的代币余额
GET /agent/balance/:address?chain=... - 如果没有任何链的余额足够,停止操作并告知用户:
"你的钱包余额不足,无法部署。请在**{chain}链上向地址
0x...添加{amount_usd} {token}**。"0x...展示所有支持链,供用户选择充值的链。 - 使用viem向地址发送ERC20转账 → 获取
pay_to携带txHash调用X-Payment-Tx: txHash→ 验证支付、充值额度、完成部署POST /agent/deploy - → 轮询直至部署完成
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=arbitrumjson
{
"address": "0x...",
"chain": "arbitrum",
"balances": [
{ "token": "usdc", "symbol": "USDC", "balance": "18.000000", "decimals": 6 }
]
}List supported chains:
GET /agent/chainsjson
{
"chains": [
{ "chain": "arbitrum", "chain_id": 42161, "tokens": ["usdc", "usdt"] },
{ "chain": "base", "chain_id": 8453, "tokens": ["usdc", "usdt"] }
]
}查询余额 —— 某链上的所有代币:
GET /agent/balance/0xYourWallet?chain=arbitrumjson
{
"address": "0x...",
"chain": "arbitrum",
"balances": [
{ "token": "usdc", "symbol": "USDC", "balance": "18.000000", "decimals": 6 }
]
}列出支持链:
GET /agent/chainsjson
{
"chains": [
{ "chain": "arbitrum", "chain_id": 42161, "tokens": ["usdc", "usdt"] },
{ "chain": "base", "chain_id": 8453, "tokens": ["usdc", "usdt"] }
]
}Auth Headers (all requests)
认证请求头(所有请求)
Sign with your private key.
{wallet}:{timestamp}:{nonce}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-uuidList Your Projects (auth required)
列出你的项目(需认证)
GET /agent/projectsReturns 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"
}
]
}urlnullactivebuildingdeployingpendingqueuedpromotingdeletingfailedGET /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"
}
]
}若项目暂无成功部署记录,将为。状态值包括:、、、、、、、。
urlnullactivebuildingdeployingpendingqueuedpromotingdeletingfailedDelete 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: if the wallet is not the deployer.
403DELETE /agent/projects/{projectId}从NodeOps永久删除项目。仅最初部署该项目的钱包有权删除。
json
{ "projectId": "uuid", "status": "deleted" }错误:若钱包不是部署者,返回。
403Step 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 (no credits):
402json
{
"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 (has credits but active projects exist):
402json
{
"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..." }] }
}无额度时返回:
402json
{
"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": [...]
}有额度但存在活跃项目时返回:
402json
{
"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: usdcResponse :
200json
{ "projectId": "uuid", "deploymentId": "uuid", "status": "deploying" }使用相同的请求体,添加支付请求头:
POST /agent/deploy
X-Payment-Tx: 0xTransactionHash
X-Payment-Chain: arbitrum
X-Payment-Token: usdc返回:
200json
{ "projectId": "uuid", "deploymentId": "uuid", "status": "deploying" }Step 4: Poll
步骤4:轮询
GET /agent/deploy/{projectId}/{deploymentId}/status- — keep polling every 5s
{ "status": "deploying" } - — done
{ "status": "ready", "endpoint": "https://..." } - — stop
{ "status": "failed", "reason": "..." }
GET /agent/deploy/{projectId}/{deploymentId}/status- —— 每5秒轮询一次
{ "status": "deploying" } - —— 部署完成
{ "status": "ready", "endpoint": "https://..." } - —— 停止轮询
{ "status": "failed", "reason": "..." }
Upload Types
上传类型
Files:
Zip:
{ "type": "files", "files": [{ "path": "...", "content": "base64" }] }{ "type": "zip", "data": "base64-zip", "filename": "code.zip" }Important: When uploading files, exclude build artifacts and dependencies:
- ,
node_modules/,dist/,build/.next/ - ,
.env, keys, secrets.env.* - ,
.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
错误码
| Code | Meaning |
|---|---|
| 400 | Invalid body |
| 401 | Bad signature / expired / nonce reused |
| 402 | Payment required or verification failed |
| 403 | Wrong wallet on status endpoint |
| 409 | Tx hash already used |
| 429 | Rate 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 —— 完整可用示例