mcpField
C
collectorcrypt

collectorcrypt

github.com/starchild-ai-agent其他30259 次安装6 天前更新
代码仓库

关于 collectorcrypt

CollectorCrypt API 技能用于与 Solana 上的收藏卡 NFT 市场及周边服务交互,适合构建卡牌交易、盲包和实体卡兑换流程。它涵盖市场、Gacha、Vault、Swap 等服务,并通过钱包签名处理链上交易。

主要功能

  1. 01浏览并交易收藏卡 NFT
  2. 02创建并开启随机卡牌盲包
  3. 03在 NFT 与实体卡之间兑换
  4. 04通过托管机制进行点对点交换
  5. 05支持多种 Solana NFT 标准

适用场景

  1. 01浏览市场并购买或上架收藏卡
  2. 02集成盲包生成与开包流程
  3. 03将实体卡存入 Vault 铸造 NFT
  4. 04构建链上 NFT 或代币交换流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill collectorcrypt

安装后在 Claude Code 中输入/collectorcrypt确认已加载。

详细介绍

CollectorCrypt API

连接实体集换式卡牌与区块链 —— 在 Solana 上买卖和交易收藏卡牌 NFT,开启神秘扭蛋包,将 NFT 兑换为实体卡牌,并进行点对点资产兑换。

市场基础 URL: https://api.collectorcrypt.com 市场 Devnet URL: https://dev-api.collectorcrypt.com 扭蛋基础 URL: https://gacha.collectorcrypt.com 扭蛋 Devnet URL: https://dev-gacha.collectorcrypt.com

核心概念

产品套件
  • Marketplace — 在 Solana 上使用 USDC 买卖和交易收藏卡牌 NFT
  • Gacha Machine — 神秘卡包系统;使用 USDC 购买随机生成的 Pokemon 卡牌 NFT,并通过 VRF 验证公平性
  • Vault — 连接 NFT 与实体卡牌;存入实体卡牌以铸造 NFT,销毁 NFT 以寄送实体卡牌
  • Swap — 通过托管机制进行链上点对点资产兑换(NFT、pNFT、cNFT、SPL 代币)
  • Launchpads — 用于铸造全新收藏品系列的发售页面
  • Bidder — eBay 出价自动化;存入资金、代为出价,并将竞得的卡牌代币化
Solana 程序
程序ID
MarketplaceCcmRKTuZCGJBWQwMHvDYApBRvSZNHqGJXkznqpDTSQUr
SwapCCSwaptcDXtfjyRMYBqavqBwiW162yXFAJrXN53UuENC
支持的 NFT 类型
  • 可编程 NFT(pNFT) — 采用 Metaplex 标准并强制执行版税;使用 tokenStandard: "Pnft"
  • 压缩 NFT(cNFT) — 采用 Metaplex Bubblegum 默克尔树结构;使用 tokenStandard: "Cnft"
  • Metaplex Core(nftStandard: "core") — 单账户标准;许多正在交易的挂单都是 Core(浏览响应会返回 "nftStandard": "core")。对于 Core 挂单,买入/挂单/出价请求正文中省略 tokenStandard —— 切勿传入 "Pnft"/"Cnft"。只有当资产确实是 pNFT 或 cNFT 时,才发送 tokenStandard。
货币

所有市场和扭蛋交易均使用 Solana 上的 USDC(SPL Token)。运费支持使用 USDC 或 USDT 支付。Gas 费用以 SOL 支付。

市场价格以整数 USDC 为单位(例如,"price": 25 表示 $25.00 USDC)。

交易流程(市场与配送)

三步流程:

  1. 构建 — 向 API 端点发送 POST 请求,获取 base64 编码的未签名交易
  2. 签名 — 使用 Solana 钱包(Phantom/Solflare,或 Starchild 钱包辅助工具,见下文)签名
  3. 广播 — 将已签名交易 POST 到 /marketplace/broadcast

HTTP 状态码 —— 200 和 201 均应视为成功。 实测确认:/marketplace/buy 和 /marketplace/broadcast 返回 201,而非 200。任何 2xx 状态码都应视为成功;不要严格检查 == 200。

响应正文可能是原始 base64 文本,而非 JSON。 使用 fundingSource: "wallet" 调用 /marketplace/buy 时,未签名交易可能以纯文本正文形式返回。请采用防御式解析:

text = response.text
try:
    data = response.json()
    tx = data.get("transaction") or data.get("serializedTransaction")
except Exception:
    tx = text  # body was the raw base64 transaction

Starchild 钱包签名会返回 snake_case 格式的 signed_transaction。 使用平台钱包签名时:

from core.skill_tools import wallet
signed = wallet.wallet_sol_sign_transaction(unsigned_tx)
# → {"signed_transaction": "<base64>", "encoding": "base64"}
signed_tx = signed.get("signed_transaction") or signed.get("signedTransaction")

优先查找 signed_transaction,然后再查找 camelCase 变体。将 signed_tx 作为 signedTransaction 字段传入 /marketplace/broadcast。

扭蛋稀有度等级
稀有度概率
Epic1%
Rare(高)4%
Uncommon(中)15%
Common(低)80%
VRF(可验证随机函数)

抽卡使用可验证随机函数,确保结果防篡改且可证明公平。选择分为 两个阶段:

  1. **抽取 → 稀有度等级:**生成一个均匀分布的整数,范围为 1–100,000,000,以玩家在待处理交易上的钱包签名作为种子,再根据机器配置的权重映射到稀有度等级(参见 /api/machines 中的 tierRanges)。
  2. **卡牌 → 等级内选择:**通过可验证的选择,从该等级中选出具体的 NFT。

种子(钱包签名)和结果会记录在 Solana 的奖励交易链上备忘录中,防止预测或操纵。可独立验证:

  • GET /api/vrf/verify?memo=YOUR_MEMO — 返回证明、公钥、交易签名,以及存储的抽取结果是否与重新计算的结果相符。
  • /verify-selection/YOUR_MEMO — 在浏览器端重放卡牌选择,并与链上备忘录进行比对。

文档没有指定具体的 VRF 算法;请勿声称使用了某种算法。

如何调用

Gacha API — 无需 API 密钥(密钥并不存在)

没有 API 密钥。请勿设置 CC_API_KEY、勿发送 x-api-key 标头,也不要尝试获取密钥 — CollectorCrypt 团队已确认不存在密钥系统。 所有 Gacha 端点,无论是读取还是写入,调用时均无需身份验证。

# Reads AND writes — no auth header of any kind
curl -s "https://gacha.collectorcrypt.com/api/machines"
curl -s -X POST "https://gacha.collectorcrypt.com/api/generatePack" \
  -H "Content-Type: application/json" \
  -d '{"playerAddress":"WALLET_PUBKEY"}'

请忽略文档中的身份验证部分。 公开文档称“每个请求都必须包含有效的 x-api-key 标头”,并提到了合作伙伴的“slug”。这与实际情况不符 — 团队已确认不存在密钥系统,且实测 /api/generatePack 在未提供标头时返回 200。无需申请任何内容,也无需添加任何标头。

没有密钥时,生成的交易会携带 cc-<uuid> 备忘录。安全性来自钱包签名,而非任何 API 凭据 — 在用户签署此 API 返回的交易之前,不会执行任何操作。

参考实现:Gacha Starter Demo — https://github.com/daxherrera/gacha-starter(完整的卡包 → 签名 → 提交 → 开启流程)。可在 devnet 上实时尝试所有调用:https://dev-gacha.collectorcrypt.com(通过 USDC 水龙头为 devnet 钱包注资:https://spl-token-faucet.com/?token-name=USDC-Dev)。

Marketplace API — 读取无需身份验证

公开的 GET 端点(浏览挂单)无需身份验证。写入端点会返回未签名的交易,由钱包签名 — 不涉及 API 密钥。

# Browse listings — no auth, 5s cache for unauthenticated requests
curl -s "https://api.collectorcrypt.com/marketplace?page=1&step=20&categories=Pokemon"

# Create listing — returns base64 unsigned transaction
curl -s -X POST "https://api.collectorcrypt.com/marketplace/list" \
  -H "Content-Type: application/json" \
  -d '{
    "wallet": "YOUR_SOLANA_ADDRESS",
    "cardId": "CC_CARD_DB_ID",
    "nftAddress": "NFT_MINT_ADDRESS",
    "currency": "USDC",
    "price": 50
  }'
Shipping API — 两种身份验证方式

方式 A — Privy 身份令牌:

Authorization: Bearer <privy-identity-token>

方式 B — 使用 Solana 登录(SIWS):

  1. POST /auth/wallet/nonce — 获取 nonce 和待签名消息
  2. 使用钱包签署消息(ed25519,base58)
  3. POST /auth/wallet/verify — 用签名交换访问令牌和刷新令牌
# Step 1: Get nonce
curl -s -X POST "https://api.collectorcrypt.com/auth/wallet/nonce" \
  -H "Content-Type: application/json" \
  -d '{"wallet": "YOUR_PUBKEY", "partnerAppId": "your-slug", "domain": "your-app.com", "uri": "https://your-app.com"}'

# Step 3: Verify and get tokens
curl -s -X POST "https://api.collectorcrypt.com/auth/wallet/verify" \
  -H "Content-Type: application/json" \
  -d '{"message": "<message-from-nonce>", "signature": "<base58-ed25519-signature>"}'
# Returns: {"accessToken": "cca_...", "refreshToken": "ccr_...", "expiresAt": ...}

令牌管理:

  • 访问令牌有效期:15 分钟
  • 刷新:使用 {"refreshToken": "..."} 调用 POST /auth/wallet/refresh
  • 登出:POST /auth/wallet/logout
  • 方式 B 的限制:仅支持加密货币支付(不支持银行卡支付),且仅支持 Solana 签名

意图路由

Marketplace

基础地址:https://api.collectorcrypt.com

所有 POST 端点都会返回经过 base64 编码的未签名 Solana 交易。使用钱包签名后,通过 /marketplace/broadcast 广播。

挂售 NFT — POST /marketplace/list
字段类型必填描述
walletstring是卖家的 Solana 地址
cardIdstring是CollectorCrypt 卡牌数据库 ID
nftAddressstring是NFT 铸币地址
currencystring是"USDC"
pricenumber是以 USDC 计价的挂售价
tokenStandardenum否"Pnft" 或 "Cnft"
userHasSolboolean否若为 false,则由后端支付费用

错误:400(链上错误)、409(已挂售)

取消挂单 — POST /marketplace/cancel-listing
字段类型必填描述
walletstring是调用者的钱包
tokenMintstring是NFT 铸造地址
sellerstring否默认为 wallet

错误:400(链上错误),404(未找到挂单)

更新挂单价格 — POST /marketplace/update-listing
字段类型必填描述
walletstring是卖家的钱包
tokenMintstring是NFT 铸造地址
newPricenumber是更新后的 USDC 价格
coinstring是"USDC"

错误:400(价格未变或链上错误),404(未找到挂单)

购买 NFT — POST /marketplace/buy
字段类型必填描述
walletstring是买家的钱包
nftAddressstring是NFT 铸造地址
pricenumber是挂单价格(USDC)
currencystring是"USDC"
tokenStandardenum否"Pnft" 或 "Cnft" — Metaplex Core 挂单请省略此项(nftStandard: "core")
sellerWalletstring否如果省略,则从数据库解析
fundingSourceenum否"wallet"(默认)或 "escrow"

成功状态为 200 或 201(实时购买返回 201)。响应正文可能是原始 base64 文本,而非 JSON — 请采取稳健的解析方式(见上文的 Transaction Pattern)。

  • fundingSource: "wallet" → 单个 base64 未签名交易(JSON {"transaction": "..."} 或纯 base64 文本)
  • fundingSource: "escrow" → {"transactions": ["BASE64_WITHDRAW_TX", "BASE64_BUY_TX"], "fundingSource": "escrow"}

Escrow 要求 USDC 余额至少为 price × 1.02。

错误:400(链上错误、Escrow 余额不足),404(未找到卡片/挂单),409(所有者已变更)

端到端购买操作指南(经实时测试)
import requests
from core.skill_tools import wallet

BASE = "https://api.collectorcrypt.com"
buyer = "YOUR_WALLET_PUBKEY"

# 1. Find a listed item, cheapest first
listings = requests.get(f"{BASE}/marketplace",
    params={"page": 1, "step": 1, "marketplaceStatus": "Buy now", "orderBy": "listedPriceAsc"}
).json()["filterNFtCard"]
item = listings[0]
mint   = item["nftAddress"]
price  = float(item["listing"]["price"])
seller = item["owner"]["wallet"]
std    = item.get("nftStandard")  # "core" | "Pnft" | "Cnft"

# 2. Build buy tx. Omit tokenStandard for Core listings.
body = {"wallet": buyer, "nftAddress": mint, "price": price,
        "currency": "USDC", "sellerWallet": seller}
if std in ("Pnft", "Cnft"):
    body["tokenStandard"] = std
r = requests.post(f"{BASE}/marketplace/buy", json=body)
assert r.status_code in (200, 201)              # buy returns 201
try:    unsigned = r.json().get("transaction") or r.json().get("serializedTransaction")
except Exception: unsigned = r.text             # may be raw base64

# 3. Sign with Starchild wallet (snake_case key)
signed = wallet.wallet_sol_sign_transaction(unsigned)
signed_tx = signed.get("signed_transaction") or signed.get("signedTransaction")

# 4. Broadcast
b = requests.post(f"{BASE}/marketplace/broadcast",
    json={"wallet": buyer, "signedTransaction": signed_tx, "nftAddress": mint})
assert b.status_code in (200, 201) and b.json().get("success")  # broadcast returns 201
sig = b.json()["signature"]

# 5. Verify on Solana RPC — the SOURCE OF TRUTH (see below)
status = requests.post("https://api.mainnet-beta.solana.com", json={
    "jsonrpc": "2.0", "id": 1, "method": "getSignatureStatuses",
    "params": [[sig], {"searchTransactionHistory": True}]}
).json()["result"]["value"][0]
assert status and status["err"] is None and status["confirmationStatus"] == "finalized"

请通过 Solana RPC 签名状态进行验证,而非重新获取市场数据。 购买后,市场元数据的刷新会有延迟;同时没有 nftAddress 查找筛选器(search=<mint> 是模糊搜索,可能无法立即反映新的所有者)。广播后权威的检查方式是对广播的 signature 调用 getSignatureStatuses:

{"confirmationStatus": "finalized", "err": null, "status": {"Ok": null}}

err == null(且 confirmationStatus 为 confirmed/finalized)表示购买已在链上完成。仅在需要显示时才回退到重新获取市场数据,切勿将其作为成功判定条件。

回归测试样例 — 一笔成功的真实购买(用于对流程进行冒烟测试):

字段值
商品2017 #024 POKE BALL PSA 9 — Pokémon Japanese Sun & Moon, Ash vs. Team Rocket Deck Kit
价格19 USDC
NFT 铸造地址4AWreh7pqVb4jhANAXFz2fwSPKqWr5ZAFMgaAFWZS9nk
卖家FfveJgtFmGPCSazkjicf21WLk9rdUaMsownVVA8LRhwf
广播签名5SwxeuWGjWbiAFq8YVN3Qsw1PXnKXBakKA2ykgccc78gg6JkGnyi48StezcijXmgWHyGWvojq8TYmTXJoC9XnbjH
Solana 状态finalized,err: null
发起报价 — POST /marketplace/make-offer
字段类型必填描述
walletstring是买家的钱包
cardIdstring是CollectorCrypt 卡片数据库 ID
nftAddressstring是NFT 铸造地址
pricenumber是报价(USDC)
currencystring是"USDC"
tokenStandardenum否"Pnft" 或 "Cnft"
userHasSolboolean否如果为 false,则由后端支付费用
ownerWalletstring否当前 NFT 所有者
collectionHashstring否cNFT 集合哈希

错误:400(无法确定所有者或链上错误)

取消报价 — POST /marketplace/cancel-offer
字段类型必填描述
walletstring是买家的钱包
nftAddressstring是NFT 铸造地址
keepInEscrowboolean否如果为 true,USDC 会留在托管账户中;默认为 false

如果钱包中的 SOL 不足以支付租金,后端会自动将 keepInEscrow 设为 true。

错误:404(未找到有效报价)

更新报价 — POST /marketplace/update-offer
字段类型必填描述
walletstring是买家的钱包(签名者)
nftAddressstring是NFT 铸造地址
currencystring是"USDC"
buyerstring是买家的钱包(通常与 wallet 相同)
pricenumber是新报价,单位为 USDC

重要: 托管账户中必须已包含全部新金额 — 此指令不会转入额外的 USDC。

错误:400(价格未变、无托管资金、余额不足、链上错误),404(未找到报价)

接受报价 — POST /marketplace/accept-offer
字段类型必填描述
walletstring是卖家的钱包(NFT 所有者)
nftAddressstring是NFT 铸造地址
buyerstring是买家的钱包
currencystring是"USDC"
pricenumber是报价,单位为 USDC
tokenStandardenum否"Pnft" 或 "Cnft"
userHasSolboolean否如果为 false,则由后端支付手续费

cNFT 边缘情况: 如果 cNFT 当前已上架,则返回:

{
  "requiresCancelListing": true,
  "cancelListingTx": "BASE64_CANCEL_LISTING_TX",
  "message": "This cNFT is currently listed. Please sign..."
}

先签署取消上架交易,然后重新调用 accept-offer。

错误:400(价格偏差、链上错误),404(未找到报价)

浏览列表 — GET /marketplace

公开接口,无需身份验证。未验证请求的缓存时间为 5 秒。

分页:

参数类型默认值说明
page整数1页码从 1 开始
step整数100每页数量(最多 100)

筛选条件(均为可选):

参数类型说明
search字符串按 itemName、nftAddress、gemrateCardName、gradingID 进行子串匹配。这是按 mint 查询的唯一方式——没有 nftAddress 查询参数(GET /marketplace?nftAddress=<mint> 会返回 400)。请改用 search=<mint>。
ownerAddress字符串按持有者钱包筛选
hideOwned布尔值隐藏调用者自己的卡片(需要身份验证)
favoritesOnly布尔值仅显示收藏的卡片(需要身份验证)
followingOnly布尔值仅显示来自已关注用户的卡片(需要身份验证)
followingOf字符串显示由此钱包关注的用户所持有的卡片
marketplaceStatusCSVBuy now、Has offers
marketplaceSourceCSVCC、ME
marketplaceTagsCSV全局标签名称(例如,Hot、Featured)
listPriceMin / listPriceMax数字USDC 价格范围
insuredValueMin / insuredValueMax数字保额范围
yearMin / yearMax整数卡片年份范围
categoriesCSVPokemon、Baseball、Basketball、Football、Magic The Gathering、Yu-Gi-Oh!、Lorcana、One Piece、Non-Sport 等
cardTypeCSVCard、Comic、ComicRaw、Game、Merch、Raw、Sealed
blockchainCSVSolana 等
authenticated布尔值仅显示经过认证的卡片
autographed布尔值仅显示带签名的卡片
burnt布尔值包含已销毁的卡片(默认排除)
grade字符串子串匹配
genericGradeMin / genericGradeMax数字数字评分范围
gradingCompanyCSVPSA、Beckett、CGC、SGC、TAG、CSG、KSA、PSA/DNA、UDA、Steiner、BBCE、Rare Edition、Not graded
set / format / language / productCode字符串对密封商品/漫画元数据进行子串匹配
pokemon字符串针对 gemrateCardName 按单词边界匹配
ccBuyback布尔值仅显示启用了 CC 回购的卡片
gemrateSet / gemrateGrade / gemrateCardName / gemrateSpecId / gemrateParallel字符串Gemrate 专用筛选条件

排序 — orderBy 的取值: dateAsc、dateDesc、nameAsc、nameDesc、priceAsc、priceDesc(保额)、yearAsc、yearDesc、listedDateAsc、listedDateDesc、listedPriceAsc、listedPriceDesc 默认值:listedDateDesc

响应:

{
  "filterNFtCard": [
    {
      "id": "card_db_id",
      "itemName": "...",
      "nftAddress": "NFT_MINT_ADDRESS",
      "nftStandard": "Pnft",
      "blockchain": "Solana",
      "category": "Pokemon",
      "type": "Card",
      "year": 1999,
      "grade": "10",
      "gradeNum": 10,
      "gradingCompany": "PSA",
      "gradingID": "...",
      "insuredValue": "...",
      "listing": {
        "price": "25",
        "currency": "USDC",
        "marketplace": "CC",
        "sellerId": "...",
        "createdAt": "ISO_DATE"
      },
      "offers": [{"id": "offer_id"}],
      "owner": {
        "id": "user_id",
        "name": "...",
        "wallet": "OWNER_WALLET_ADDRESS"
      },
      "images": {
        "front": "URL",
        "frontM": "URL",
        "frontS": "URL",
        "back": "URL",
        "backM": "URL",
        "backS": "URL"
      }
    }
  ],
  "findTotal": 1234,
  "total": 50000,
  "totalPages": 25,
  "cardsQtyByCategory": {"Pokemon": 800, "Baseball": 200}
}
  • 未上架时,listing 为 null
  • offers 是有效报价 ID 的数组
  • findTotal = 符合筛选条件的总数;total = 市场中的卡片总数
  • cardsQtyByCategory = 各类别的数量(不包括 categories 筛选条件)
广播交易 — POST /marketplace/broadcast
字段类型必填说明
wallet字符串是签名者钱包地址
signedTransaction字符串是Base64 编码的已签名交易
nftAddress字符串否5 秒后触发元数据刷新

成功状态为 200 或 201(实时广播返回 201)。响应:

{
  "success": true,
  "signature": "SOLANA_TRANSACTION_SIGNATURE",
  "message": "Transaction broadcast successfully"
}

不要将 201 视为失败——请检查 success === true 或是否存在 signature,而不是检查状态码。

**余额不足时的恢复方式:**如果广播返回 400,且 "code": "INSUFFICIENT_FUNDS_RETRYABLE",请将 userHasSol: false 传入,以重新构建原始交易,让后端支付费用;然后重新签名并再次广播。

**验证:**提交前,会根据程序 ID 允许列表验证交易。

错误:400(交易无效、可重试的余额不足、提交失败),403(程序 ID 不在允许列表中)

Gacha Machine

基础 URL:https://gacha.collectorcrypt.com

方法端点主要参数描述
GET/api/status—机器运行状态(开启/关闭)
GET/api/stock—每台机器按稀有度划分的 NFT 库存数量
GET/api/machines—所有机器的完整配置:价格、odds、tierRanges(roll→tier 边界)、实时 stock、instantBuyback %,以及 ev(按稀有度加权的预期保价)
GET/api/getNftscode、rarity、page、limit支持筛选的可用 NFT
POST/api/generatePackBody:playerAddress、packType、turbo、altPlayerAddress创建一包的购买交易
POST/api/generateYoloPacksBody:count(1-100)、packType、playerAddress、turbo、altPlayerAddress批量购买多包
POST/api/openPackBody:memo打开已购买的包并获得 NFT
POST/api/buybackBody:playerAddress、nftAddress、altRecipient将 NFT 卖回以换取 USDC(72 小时内)
GET/api/buyback/checkmemo检查回购完成状态
GET/api/buyback/availablewallet、nft预先检查 NFT 是否符合回购条件,并返回退款 amount(构建交易前)
GET/api/pack/statusmemo完整的包生命周期:购买、发送 NFT(包括 prize_tier、insured_value、vrf_proof)以及回购历史
POST/api/submitTransactionBody:signedTransaction(base64)将已签名交易提交至 Solana
POST/api/generateGiftBody:sender、receiver、packType、count向另一个钱包赠送包
GET/api/getGiftedwallet赠送历史(已发送/已接收)
GET/api/purchasedPackswallet按类型统计包数量(已购买/已赠送、已使用/未使用)
POST/api/generatePurchasedPackBody:publicKey、packType、ledger创建用于打开已赠送/已购买包的签名挑战
POST/api/usePurchasedPackBody:nonce、packType、publicKey、signature/transactionSignature、ledger签名后使用已购买的包,并返回 memo
GET/api/getAllWinnerstimestamp、slug、epic、packType、count最近的获胜者,支持可选筛选
GET/api/vrf/verifymemo验证一次 roll 的 VRF 证明
Gacha 响应格式

generatePack 响应:

{"memo": "slug-uuid", "transaction": "base64_encoded_transaction"}

memo 的格式为 cc-<uuid>(没有 API 密钥,因此不适用合作方 slug 前缀)。请求 Body 为 {playerAddress, packType?, turbo?, altPlayerAddress?}——packType 默认为 pokemon_50(传奇包使用 pokemon_250)。

openPack 响应(普通获胜):

{
  "success": true,
  "transactionSignature": "...",
  "nft_address": "...",
  "nftWon": {
    "content": {
      "metadata": {"name": "...", "description": "...", "attributes": []}
    }
  },
  "points": 0,
  "roll": 12345678,
  "rarity": "Epic|Rare|Uncommon|Common"
}

roll 是范围为 1–100,000,000 的整数(不是小数)。nftWon 嵌套在 content.metadata 下——顶层没有 name/image。

**openPack 响应(turbo 模式回购,Common roll):**会添加 "code": "TURBO_MODE_BUYBACK" 和 "buybackAmount": 42500000"(USDC 基础单位)——Common NFT 会自动售出,而不是交付。

openPack 响应(付款尚未确认):

{"success": true, "code": "WAITING_FOR_WEBHOOK", "memo": "slug-uuid-string"}

不要根据此响应假设 NFT 已交付——轮询 GET /api/pack/status?memo=...(或重试 openPack),直到获胜结果确定。

**openPack 具有幂等性:**再次调用已打开的包时,会返回原始结果(相同的 transactionSignature、nftWon、points、rarity)——可以安全重试。

奖品等级映射(pack/status 和 getAllWinners 返回数字 prize_tier;openPack 返回易读的 rarity):1 = Epic,2 = Rare,3 = Uncommon,4 = Common。

buyback 响应:

{
  "serializedTransaction": "base64",
  "refundAmount": 42500000,
  "memo": "..."
}
发货 / Vault 赎回

基础 URL:https://api.collectorcrypt.com

方法端点主要参数描述
POST/redeem/estimate请求体:nftAddresses、shippingAddressId估算费用,不创建发货单;返回 price、insurancePrice、feesPrice、shippingPrice、total、numberOfCards、breakdown
POST/redeem/prepare请求体:nftAddresses、shippingAddressId、coin(USDC|USDT)、deliveryCompany、comment、insurance创建待处理发货单,返回未签名交易
POST/blockchain/:outboundShipmentId/burn请求体:transactions(base64 签名)、evmTransactions广播已签名的销毁交易;返回 id、status、transactionUrls
GET/outbound-shipment—列出用户的发货单
GET/outbound-shipment/:idid获取指定发货单的状态
发货地址管理
方法端点描述
GET/shipping-address列出已保存的地址
GET/shipping-address/:id获取指定地址
POST/shipping-address/create创建新地址
PATCH/shipping-address/update/:id更新地址
DELETE/shipping-address/:id删除地址
运费
地区基础费用每件附加费用签收服务包装附加费
美国$5.99$3.00+$3.00(价值 >= $500)$0.18/包
加拿大$20.99$3.00已包含$0.25/包
欧洲$29.99$3.00已包含$0.25/包
澳大利亚/新西兰$34.99$3.00已包含$0.25/包
世界其他地区$34.99$3.00已包含$0.25/包

当包裹价值超过 $5,000 时,将自动按申报价值的 0.5% 购买保险。

Redeem/Prepare 响应结构
{
  "outboundShipmentId": "shipment_...",
  "transactions": ["<base64-unsigned-tx>"],
  "evmTransactions": [],
  "totalCost": 14.99,
  "submitUrl": "/blockchain/shipment_.../burn",
  "breakdown": {
    "region": "USA",
    "declaredValue": 700,
    "numberOfCards": 10,
    "lines": [
      {"code": "shipping_base", "label": "Base shipping (USA, first card)", "amount": 5.99, "unitPrice": 5.99}
    ]
  }
}
身份验证(SIWS — 使用 Solana 登录)

基础 URL:https://api.collectorcrypt.com

方法端点主要参数描述
POST/auth/wallet/nonce请求体:wallet、partnerAppId、domain、uri获取 nonce 和 EIP-4361 签名消息
POST/auth/wallet/verify请求体:message、signature(base58 ed25519)使用签名换取访问令牌和刷新令牌
POST/auth/wallet/refresh请求体:refreshToken刷新已过期的访问令牌
POST/auth/wallet/logout请求体:refreshToken(以及 Authorization 标头中的访问令牌)使令牌失效
Swap 程序(链上)

程序 ID:CCSwaptcDXtfjyRMYBqavqBwiW162yXFAJrXN53UuENC

Swap 程序是一个基于 Anchor 的 Solana 智能合约。交易遵循以下生命周期:

Open → Approved → Executed → Settled → (Closed)
         ↑            ↑
    cancel_trade  cancel_trade

指令:

指令描述
create_trade初始化两个钱包之间的交易
approve_trade表示已准备就绪(双方都必须批准)
execute_trade确认执行交易(双方都必须执行)
cancel_trade中止未完成或已批准的交易
execute_nft_batch将标准 NFT 转入或转出托管账户
execute_pnft_batch转移可编程 NFT
execute_cnft_batch转移压缩 NFT
execute_token_batch转移 SPL 代币
mark_trade_settled后端确认交易完成
close_trade最终清理并退还租金

市场链上详情

账户结构
账户用途
Market单例 PDA — 配置(管理员密钥、费用、金库、暂停状态)
Listing按资产 ID 和卖家索引的销售信息,包含委托权限
Offer买家报价详情,由独立托管资金支持
UserEscrow按用户跟踪用于报价抵押的 USDC 存款
费用结构

平台费用:200 个基点(2%)。可在 0–200 个基点范围内配置。

fee = floor(price * platform_fee_bps / 10000)

使用 u128 中间精度以防止溢出。

安全属性
  • 非托管式上架 — NFT 通过委托保留在卖家钱包中,而不是通过托管转账
  • 防止抢跑 — expected_price 参数会验证链上价格是否符合预期
  • 禁止自我交易 — 强制执行 seller != buyer 验证
  • PDA 确定性 — 固定的种子方案可防止未经授权的账户替换
  • 广播允许列表 — 提交前会根据已批准的程序 ID 验证交易

错误处理

任何 2xx 状态码都表示成功 — 200 和 201 都应接受。 多个市场写入端点(/marketplace/buy、/marketplace/broadcast)成功时会返回 201。不要以 status == 200 作为判断条件;应检查是否为 2xx 状态码,并确认存在 success: true、signature 或交易正文。

所有 API 均按标准格式返回错误:

{"statusCode": 400, "message": "human-readable error", "error": "Bad Request"}
状态码含义
400输入无效、链上失败、价格不匹配、托管资金不足、签名失败
401令牌无效或已过期
403访问被拒绝,程序 ID 不在广播允许列表中
404未找到卡片、NFT、上架条目、报价或地址
409冲突(已上架、所有者已更改、钱包已关联 Privy 账户)
429超出速率限制
500机器为空、开启的卡包过多或处理错误

安全须知

  • 市场价格以整数 USDC 计。 "price": 25 表示 25.00 美元 USDC。
  • 购买/广播成功时返回 HTTP 201 — 接受任何 2xx 状态码,解析响应正文(可能是原始 base64,而非 JSON),并通过 Solana RPC(getSignatureStatuses)验证结果,而不是重新查询市场。请参阅端到端购买流程。
  • Metaplex Core(nftStandard: "core")很常见 — 对这类资产请省略 tokenStandard;只有当资产确实属于对应类型时才发送 "Pnft"/"Cnft"。
  • Starchild 钱包签名会返回 signed_transaction(蛇形命名)— 广播前读取该字段(或其驼峰命名回退字段)。
  • Gacha 的 refundAmount 以 USDC lamports 为单位。 42,500,000 = 42.50 美元 USDC(1 USDC = 1,000,000 lamports)。
  • Gacha 回购窗口为 72 小时。 超过此时间后,NFT 无法卖回给机器。
  • 回购退款按每台机器的保险价值/市场价值百分比计算(而非购买价格)。该比例通过 GET /api/machines 中的 instantBuyback 字段提供(例如,85 = 85%);不要假设所有机器都采用固定比例。构建回购交易前,请使用 GET /api/buyback/available?wallet=…&nft=… 获取确切的退款 amount(USDC 基本单位,已按机器回购比例调整,且上限为 40,000 USDC)。
  • 非托管式上架 — NFT 通过委托保留在卖家钱包中。如果卖家转移 NFT 却未取消上架,该上架将失效。后端不保证自动取消。
  • 更新报价前必须预先为托管账户注资 — update-offer 不会转入额外的 USDC;托管账户必须已包含新的全额资金。
  • 接受 cNFT 报价可能需要两笔交易 — 如果 cNFT 当前已上架,API 会返回一笔必须先签名的取消上架交易。
  • 发货会产生真实的实物配送。 调用 /redeem/prepare 前,务必与用户确认地址和 NFT 选择。
  • 签名后的交易不可撤销。 广播前请核实 NFT 地址、价格和钱包。
  • VRF 抽取结果不可更改。 卡包开启后,结果无法更改或重新抽取。
  • 路径 B(SIWS)仅支持加密货币。 不支持银行卡支付。已关联 Privy 账户的钱包会收到 409 Conflict。
  • userHasSol: false — 用户钱包缺少支付交易手续费的 SOL 时,请使用此标记;后端将代付 Gas。发生 INSUFFICIENT_FUNDS_RETRYABLE 广播错误时,也可使用此标记进行恢复。

已知限制

  • 市场采用委托而非托管机制 — 如果卖家将 NFT 转移到其他地方但未取消挂单,挂单会悄无声息地失效。购买前务必检查挂单是否有效。
  • 不同端点的字段名不一致 — 挂单使用 nftAddress,取消挂单使用 tokenMint,更新挂单使用 tokenMint + newPrice + coin。务必查看上文各端点对应的准确字段名。
  • 扭蛋的 packType 代码因机器而异(例如 pokemon_50、pokemon_250)。使用 GET /api/machines 查询可用的包类型和当前价格。
  • 无法按关键词搜索扭蛋 NFT — 使用带有 code 和 rarity 筛选条件的 GET /api/getNfts,或通过 GET /api/machines 浏览。
  • Swap 仅支持链上操作 — 没有 REST API 封装;请通过 Solana 交易与 Anchor 程序 IDL 交互。
  • 访问令牌会在 15 分钟后过期(Track B / SIWS)— 长会话需实现刷新令牌轮换。
  • eBay Bidder 没有公开 API 文档 — 这是面向消费者的工具,地址为 https://bid.collectorcrypt.com。
  • Launchpad 是由管理员管理的发售页面 — 没有用于创建或配置它们的公开 API。
  • 浏览挂单缓存 — 未经身份验证的 GET 请求会缓存 5 秒。

评论

支持 Markdown