Blowfish Token Launch
Launch Solana tokens via the Blowfish Agent API at https://api-blowfish.neuko.ai.
Overview
This skill enables autonomous token launches on Solana through a simple REST API. The flow is:
- Authenticate — wallet-based challenge-response to obtain a JWT
- Launch — submit token parameters (async, returns an eventId)
- Poll — check deployment status until terminal state
- Manage — list tokens, view fees, claim earnings
Authentication
All endpoints except /health require a Bearer JWT obtained via the challenge-response flow.
Step 1: Request Challenge
curl -s -X POST https://api-blowfish.neuko.ai/api/auth/challenge \
-H "Content-Type: application/json" \
-d '{"wallet": "<WALLET_PUBLIC_KEY>"}'
Response:
{"nonce": "<random-nonce>"}
The nonce expires after 5 minutes.
Step 2: Sign the Challenge
Sign the raw nonce with the wallet's ed25519 keypair. Encode the signature as base58.
Step 3: Verify and Get JWT
curl -s -X POST https://api-blowfish.neuko.ai/api/auth/verify \
-H "Content-Type: application/json" \
-d '{"wallet": "<WALLET_PUBLIC_KEY>", "nonce": "<nonce>", "signature": "<base58-signature>"}'
Response:
{"token": "<jwt>", "expiresIn": 900}
The JWT is valid for 15 minutes (900 seconds). Use it in all subsequent requests:
Authorization: Bearer <jwt>
See references/authentication.md for the complete TypeScript implementation.
Launch a Token
curl -s -X POST https://api-blowfish.neuko.ai/api/v1/tokens/launch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <jwt>" \
-d '{
"name": "My Token",
"ticker": "MYTKN",
"description": "A description of the token",
"imageUrl": "https://example.com/logo.png"
}'
Parameters
| Field | Type | Required | Constraints |
|---|---|---|---|
name |
string | yes | 1–255 characters |
ticker |
string | yes | 2–10 chars, ^[A-Z0-9]+$ |
description |
string | no | max 1000 characters |
imageUrl |
string | no | valid URL, max 255 characters |
Response
{
"success": true,
"message": "We will notify you when your token is deployed",
"eventId": "<uuid>"
}
Constraints
- Rate limit: 1 launch per agent per UTC day (resets at midnight UTC)
- Ticker uniqueness: each ticker can only be used once globally
Check Deployment Status
curl -s https://api-blowfish.neuko.ai/api/v1/tokens/launch/status/<eventId> \
-H "Authorization: Bearer <jwt>"
Response:
{
"status": "pending | success | failed | rate_limited",
"processedAt": "<ISO-8601 or null>"
}
Poll every 5–10 seconds until status is success, failed, or rate_limited.
List Your Tokens
curl -s https://api-blowfish.neuko.ai/api/v1/tokens/ \
-H "Authorization: Bearer <jwt>"
Response:
{
"tokens": [
{
"poolAddress": "string",
"tokenMint": "string",
"ticker": "string",
"tokenName": "string",
"isClaimed": false,
"claimedAt": null,
"claimedToAddress": null,
"deployedAt": "2026-01-15T12:00:00Z"
}
]
}
Get a Specific Token
curl -s https://api-blowfish.neuko.ai/api/v1/tokens/<mintAddress> \
-H "Authorization: Bearer <jwt>"
Returns a single token object matching the structure above.
View Claimable Fees
curl -s https://api-blowfish.neuko.ai/api/v1/tokens/claims \
-H "Authorization: Bearer <jwt>"
Response:
{
"success": true,
"tokens": [
{
"poolAddress": "string",
"tokenMint": "string",
"ticker": "MCT",
"tokenName": "My Cool Token",
"createdAt": "2024-01-15T12:00:00.000Z",
"dbcClaimableFees": 0.25,
"dbcTotalFees": 1.0,
"dbcClaimedFees": 0.75,
"lpClaimableFees": 0.1,
"lpTotalFees": 0.3,
"lpClaimedFees": 0,
"isMigrated": true,
"feeError": null
}
]
}
The feeError field is non-null when on-chain fee lookup failed for a specific token. Other tokens in the response are unaffected.
Claim Fees
Two-step process — get unsigned transactions, sign them locally, then submit each back.
Step 1: Get Unsigned Transactions
curl -s -X POST https://api-blowfish.neuko.ai/api/v1/tokens/claims/<mintAddress> \
-H "Authorization: Bearer <jwt>"
Response:
{
"success": true,
"dbcTransaction": {
"success": true,
"transaction": "base64-encoded-unsigned-transaction",
"claimedQuoteFeeSOL": 0.5,
"feeType": "dbc"
},
"lpTransaction": {
"success": true,
"transaction": "base64-encoded-unsigned-transaction",
"feeType": "lp"
},
"transactionExpirySeconds": 90
}
Either dbcTransaction or lpTransaction may be absent if that fee type is unavailable. Transactions expire in ~60-90 seconds — sign and submit immediately.
Step 2: Submit Signed Transaction
Sign each transaction with the wallet keypair, then submit:
curl -s -X POST https://api-blowfish.neuko.ai/api/v1/tokens/claims/<mintAddress> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <jwt>" \
-d '{"signedTransaction": "<base64-encoded-signed-transaction>"}'
Response:
{
"success": true,
"transactionHash": "tx-signature",
"message": "Transaction submitted successfully"
}
If you see a "Blockhash not found" error, request new unsigned transactions and try again.
See references/fee-claims.md for detailed walkthrough.
Health Check
curl -s https://api-blowfish.neuko.ai/health
No authentication required.
{"ok": true, "db": "connected", "timestamp": "2026-01-15T12:00:00Z"}
Error Handling
All errors return: {"error": "Human-readable message"}
Validation errors also include a details array:
{"error": "Validation failed", "details": [{"field": "ticker", "message": "Must be 2-10 uppercase alphanumeric characters"}]}
| Status | Scenario | Action |
|---|---|---|
| 400 | Invalid request body | Check details array for per-field errors |
| 401 | Missing or expired JWT | Re-authenticate for a fresh token |
| 403 | Wallet address mismatch | Authenticate with the wallet that launched the token |
| 404 | Event or token not found | Verify the eventId or mintAddress |
| 409 | Duplicate ticker | Choose a different ticker |
Note: Rate limiting is not enforced via HTTP status. The API accepts the launch (200) and the background worker sets the status to rate_limited — check via the status polling endpoint.
See references/error-handling.md for full error catalog.