本地交易 API
通过 API 交易 Solana 土狗币的非托管方式。钱包留在你自己的电脑上,我们永远看不到你的私钥。 签名后的交易通过我们的中继提交,或者用你自己的 RPC。
你需要
- 一个 Solana 钱包,以及它的 base58 私钥。(Phantom:设置 → 显示助记词 → 显示私钥。)
- 钱包里有一些 SOL:交易金额加上少量网络费。
- 一种提交方式。 默认把签名后的交易发回
/api/send,由我们通过自己的节点广播,不需要 RPC。想用自己的 Solana RPC(Helius、Triton、QuickNode 或公共节点)也可以。 - 想原样运行下面的示例,需要装好 Node.js 或 Python。
示例
- JavaScript
- Python
import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
import bs58 from "bs58";
const wallet = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_SECRET));
// 1. 让 shrine.trade 构建一笔未签名交易。
const res = await fetch("https://sol.shrine.trade/api/local-trade", {
method: "POST",
headers: { "content-type": "application/json", "accept": "application/json" },
body: JSON.stringify({
action: "buy", // "buy" 或 "sell"
publicKey: wallet.publicKey.toBase58(),
mint: "<token mint>", // base58 代币 mint
amount: 0.01, // 买入时为 SOL;卖出时为代币数量或 "100%"
slippage: 10, // 百分比
priorityFee: 0.0001, // SOL
}),
});
const { tx } = await res.json();
// 2. 本地签名:私钥不会离开这个脚本。
const txObj = VersionedTransaction.deserialize(Buffer.from(tx, "base64"));
txObj.sign([wallet]);
// 3. 通过 shrine.trade 中继发送,不需要 RPC。会等待确认。
const sent = await (await fetch("https://sol.shrine.trade/api/send", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ signedTx: Buffer.from(txObj.serialize()).toString("base64") }),
})).json();
console.log(sent.status, sent.explorer); // "landed" https://solscan.io/tx/…
// 或者用你自己的 RPC:
// const conn = new Connection("https://your-rpc");
// const sig = await conn.sendRawTransaction(txObj.serialize());
import base64, requests, base58
from solana.rpc.api import Client
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
wallet = Keypair.from_bytes(base58.b58decode(WALLET_SECRET))
# 1. 让 shrine.trade 构建一笔未签名交易。
res = requests.post(
"https://sol.shrine.trade/api/local-trade",
headers={"accept": "application/json"},
json={
"action": "buy", # "buy" 或 "sell"
"publicKey": str(wallet.pubkey()),
"mint": "<token mint>", # base58 代币 mint
"amount": 0.01, # 买入时为 SOL;卖出时为代币数量或 "100%"
"slippage": 10, # 百分比
"priorityFee": 0.0001, # SOL
},
)
tx_b64 = res.json()["tx"]
# 2. 本地签名:私钥不会离开这个脚本。
raw = VersionedTransaction.from_bytes(base64.b64decode(tx_b64))
signed = VersionedTransaction(raw.message, [wallet])
# 3. 通过 shrine.trade 中继发送,不需要 RPC。会等待确认。
sent = requests.post("https://sol.shrine.trade/api/send",
json={"signedTx": base64.b64encode(bytes(signed)).decode()}).json()
print(sent["status"], sent["explorer"]) # landed https://solscan.io/tx/…
# 或者用你自己的 RPC:
# sig = Client("https://your-rpc").send_raw_transaction(bytes(signed)).value
print(f"https://solscan.io/tx/{sig}")
工作原理
- 你发起请求,shrine.trade 构建一笔未签名交易。
- 你在自己的机器上签名,用你自己的钱包。
- 你提交已签名的交易:发到
/api/send由我们广播,或者通过你自己的 RPC。
发送
POST https://sol.shrine.trade/api/send 接收一笔已签名的交易,通过我们的 Solana 节点广播,脚本完全不需要 RPC。它只转发本 API 构建的交易:每次构建都会被记住 15 分钟,签名后的交易必须与其中之一完全一致。在别处组装的、或构建后被改动过的交易,一律以 not_ours 拒绝。是否使用它是可选的,已签名的交易随时可以改走你自己的 RPC。
| 字段 | ||
|---|---|---|
signedTx | base64 | 已签名的交易:web3.js 用 Buffer.from(tx.serialize()).toString("base64"),solders 用 base64.b64encode(bytes(signed))。 |
wait | 布尔,可选 | 默认 true:等待确认。false 则节点一接受就返回签名。 |
{ "signature": "5Kd…", "status": "landed", "slot": 372114820, "explorer": "https://solscan.io/tx/5Kd…" }
status 为 landed(已确认)、failed(已执行但链上报错,error 带程序错误)或 pending(未等待,或 60 秒内未确认)。节点在预检时拒绝的交易(SOL 不够、超出滑点、区块哈希过期)以 400 返回并附节点原因。
请求字段
| 字段 | 类型 | 说明 |
|---|---|---|
action | "buy" / "sell" | |
publicKey | string | 你的钱包。负责签名并支付费用。 |
mint | string | 代币 mint。 |
amount | number 或 string | 买入时投入的数量:SOL,或者对以其他资产计价的 pump.fun 币来说是它的计价资产(USDC 等)。卖出时为代币数量,或钱包持仓的比例:"100%" 全部卖出,"50%" 卖一半。 |
slippage | number | 百分比。默认 5。 |
priorityFee | number | SOL。默认约 0.0002。 |
pool | string | 走哪个发射台,见下表。省略则按 mint 自动路由。 |
poolAddress | string | raydium_cpmm、raydium_amm_v4、meteora_damm_v2 在 mint 尚未缓存池子时必填;meteora_dbc 可选。 |
jitoTip | number | SOL。附加一笔到 Jito 小费账户的转账,签名后的交易可以直接发给 block engine。 |
发射台
数据流覆盖的每个发射台和 AMM 都能用同一个接口交易。不填 pool 时按 mint 查找并自动路由到它当前的池子,会跟随迁移。只有想强制指定发射台时才填。
pool | 发射台 |
|---|---|
pumpfun(或 pump) | pump.fun 联合曲线 |
pumpswap | PumpSwap,pump.fun 币毕业后的发射台 |
bonk、stonkfun | Raydium LaunchLab:letsbonk.fun、StonkFun 以及其他所有 LaunchLab 平台 |
meteora_dbc(或 bags、moonshot) | Meteora 动态联合曲线:Bags、Moonshot 及其他 Meteora 发射台 |
raydium_cpmm | Raydium CPMM,LaunchLab 币毕业后的发射台 |
raydium_amm_v4 | Raydium AMM v4 |
meteora_damm_v2 | Meteora DAMM v2,DBC 币毕业后的发射台 |
以其他资产计价的 pump.fun 币
pump.fun 币可以用 USDC 或其他代币计价,而不是 SOL。API 会从曲线读取该币的计价资产:买入的 amount 就是该资产的数量,卖出以该资产结算,0.25% 手续费也用它收取。响应里的 quoteMint 和 feeMint 会说明具体是哪种资产;feeLamports 是手续费资产的最小单位。不需要设置任何字段,token-info 会提前给出币的 quote。
把多个操作放进同一笔原子交易,包括先发币再由其他钱包买入,请看 local-actions。转账、销毁、SOL 包装和余额读取在钱包工具。
meteora_dbc 支持以 SOL 计价的池子。DBC 上的滑点按现货价计算,所以在陡峭曲线上大额买入时请留出余量。
手续费为交易 SOL 一侧的 0.25%,已包含在交易里。见手续费。
试一试
不需要 API 密钥,这个接口是无密钥的。粘贴你的钱包私钥和代币 mint,点 Sign & send。API 只会收到你的公钥并返回未签名交易;由你的浏览器签名,再把签名后的字节发到 /api/send,或者发到你填的自有 RPC。私钥不会离开这个页面。这是主网上的真实交易,请先用小额测试。
出错时
你会收到类似 { "error": "..." } 的响应和一句简短说明。常见原因:钱包地址错误、代币 mint 错误,或者 SOL 不够。来自 /api/send 的 400 会引用节点的预检原因(滑点、余额、区块哈希过期),not_ours 表示这笔交易不是本 API 构建的,或者构建后被改动过。