Skip to content

Instantly share code, notes, and snippets.

@dome
Created April 6, 2026 11:36
Show Gist options
  • Select an option

  • Save dome/4347904582a0e8ac32a23a81f5db3d89 to your computer and use it in GitHub Desktop.

Select an option

Save dome/4347904582a0e8ac32a23a81f5db3d89 to your computer and use it in GitHub Desktop.
name tk9-wallet
description Use this skill when the user wants to interact with TK9 blockchain wallets, send tokens, check balances, sign transactions, or perform smart contract operations on TK9 Chain (Chain ID: 7447). Activate when the user mentions wallet operations, token transfers, balance checks, PIN management, or blockchain interactions on the TK9 network. This wallet works ONLY on TK9 Chain (7447) - do not use with any other blockchain.

TK9 Wallet System

IMPORTANT: This is a REST API wallet system. All operations use curl commands with JWT authentication. Do NOT use any CLI tools.

TK9 Wallet is a non-custodial wallet system built on PocketBase + dacc-js with hybrid PIN management. It operates exclusively on the TK9 blockchain network with automatic wallet creation, secure PIN-based authentication, and comprehensive blockchain operations.

Base URL: https://wallet.tk9.dev/api/v2
Authentication: Bearer Token (JWT from PocketBase auth)
Blockchain: TK9 Chain (Chain ID: 7447) ONLY
Default Token: 0x20c0000000000000000000000000000000000000 (TK9 token)

⚠️ IMPORTANT: This wallet system works ONLY with TK9 Chain (Chain ID: 7447). Do not use with any other blockchain network.


πŸ€– AI Agent Decision Tree

Follow this decision tree for all user requests:

User Request
β”œβ”€ "Create wallet" / "Register" β†’ Follow ONBOARDING FLOW
β”œβ”€ "Login" / "Sign in" β†’ Follow LOGIN FLOW (OTP)
β”œβ”€ "Check balance" β†’ Check TOKEN β†’ If expired β†’ LOGIN FLOW β†’ Check balance
β”œβ”€ "Send tokens" / "Transfer" β†’ Check TOKEN β†’ Check PIN β†’ Execute transfer
β”œβ”€ "Change PIN" β†’ Check TOKEN β†’ Execute PIN change
└─ Other β†’ Ask for clarification

State Variables to Maintain:

  • $TOKEN - JWT token from login (required for all authenticated operations)
  • $OTP_ID - OTP ID from request-otp (temporary, used only during login)
  • $WALLET_ADDRESS - User's wallet address (optional, for display)
  • $USER_ID - User's PocketBase ID (optional, for reference)

Persistent Files:

  • tk9-auth.txt - Stores JWT token (auto-loaded for transactions)
  • tk9-pin.txt - Stores user's PIN (optional, for convenience)

πŸ“‹ Flow 1: ONBOARDING (New User Registration)

When: User wants to create a new TK9 wallet for the first time.

Step 1: Ask for Email

Bot: "I'll help you create a TK9 wallet. What's your email address?"
User: "[email protected]"

Step 2: Register User

curl -s -X POST https://wallet.tk9.dev/api/v2/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "AutoGeneratedSecurePass123!",
    "passwordConfirm": "AutoGeneratedSecurePass123!"
  }'

Expected Response:

{
  "id": "user123",
  "email": "[email protected]",
  "wallet": "0xA3570FCDA303F55e0978be450f87F885d80a3758",
  "pin": "1234",
  "verified": false,
  "message": "Registration successful. Please check your email to verify your account."
}

Save:

  • $USER_ID = response.id
  • $WALLET_ADDRESS = response.wallet
  • $TEMP_PIN = response.pin (show to user once, will be deleted after change)
  • $VERIFIED = response.verified (should be false)

Step 3: Inform About Email Verification

Bot: "βœ… Wallet created successfully!

πŸ“§ IMPORTANT: Please check your email and click the verification link.
⚠️ If you don't verify within 24 hours, your account will be automatically deleted.

πŸ‘› Your wallet address: $WALLET_ADDRESS
πŸ”‘ Temporary PIN: $TEMP_PIN (you'll change this after verification)

Please let me know once you've verified your email."

Step 4: Wait for User Confirmation

User clicks verification link in email, then says: "I verified my email"

Step 5: Offer PIN Setup

Bot: "βœ… Great! Now let's set up your PIN.

You can set a custom PIN (4-6 digits). This PIN will be required for all token transfers.

⚠️ IMPORTANT: After you set your PIN, it will be removed from our database for security.
You MUST remember your PIN - there is no recovery option.

Would you like to:
1. Set a custom PIN (recommended)
2. Keep the temporary PIN for now (you can change it later)"

Step 6: Handle PIN Setup

Option A: User sets custom PIN

Bot: "Please enter your desired PIN (4-6 digits):"
User: "5678"
  1. First login with temporary PIN (via OTP):
# Request OTP
curl -s -X POST https://wallet.tk9.dev/api/v2/request-otp \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'

# User provides OTP code, then authenticate
TOKEN=$(curl -s -X POST https://wallet.tk9.dev/api/v2/auth-with-otp \
  -H "Content-Type: application/json" \
  -d '{"otpId": "OTP_ID_HERE", "password": "OTP_CODE_HERE"}' \
  | jq -r '.token')
  1. Change PIN:
curl -s -X POST https://wallet.tk9.dev/api/v2/change-pin \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "oldPasswordSecretkey": "1234",
    "newPasswordSecretkey": "5678"
  }'
  1. Save PIN to file:
echo "5678" > tk9-pin.txt
  1. Confirm to user:
Bot: "βœ… PIN changed successfully!

πŸ”‘ Your PIN has been saved to: tk9-pin.txt
πŸ“ I've stored your PIN locally for convenience.

⚠️ IMPORTANT SECURITY NOTES:
1. You can delete tk9-pin.txt anytime: rm tk9-pin.txt
2. Every token transfer requires your PIN
3. If you delete the file, you'll need to provide PIN manually each time
4. If you lose your PIN, there is NO recovery - create a new wallet

Your wallet is now ready to use! πŸŽ‰"

Option B: User keeps temporary PIN

Bot: "OK, you can continue using the temporary PIN for now.

⚠️ Note: You can change your PIN anytime using the 'change PIN' command.

Your wallet is ready to use! πŸŽ‰"

πŸ” Flow 2: LOGIN (OTP - Primary Method)

When: User wants to login to access their wallet.

Step 1: Ask for Email

Bot: "Please provide your email to login:"
User: "[email protected]"

Step 2: Request OTP

curl -s -X POST https://wallet.tk9.dev/api/v2/request-otp \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'

Expected Response:

{
  "success": true,
  "otpId": "abc123xyz",
  "message": "OTP sent to your email. Please check your inbox."
}

Save: $OTP_ID = response.otpId

Step 3: Inform User to Check Email

Bot: "βœ… OTP sent to your email!

πŸ“§ Please check your inbox for the 8-digit OTP code.
πŸ“ The code will expire in a few minutes.

Please enter the OTP code:"

Step 4: User Provides OTP Code

User: "12345678"

Step 5: Authenticate with OTP

TOKEN=$(curl -s -X POST https://wallet.tk9.dev/api/v2/auth-with-otp \
  -H "Content-Type: application/json" \
  -d '{
    "otpId": "abc123xyz",
    "password": "12345678"
  }' | jq -r '.token')

# Save token to file for future use
echo "$TOKEN" > tk9-auth.txt
echo "βœ… Token saved to tk9-auth.txt"

Expected Response:

{
  "token": "eyJhbGci...",
  "record": {
    "id": "user123",
    "email": "[email protected]",
    "wallet": "0xA3570FCDA303F55e0978be450f87F885d80a3758",
    "verified": true
  }
}

Save: $TOKEN = response.token

Step 6: Confirm Login Success

Bot: "βœ… Login successful!

πŸ‘› Wallet: $WALLET_ADDRESS
πŸ’° Ready to use your TK9 wallet.
πŸ”‘ Auth token saved to: tk9-auth.txt

What would you like to do?
1. Check balance
2. Send tokens
3. Change PIN"

Fallback: Password Login (Only if OTP unavailable)

TOKEN=$(curl -s -X POST https://wallet.tk9.dev/api/v2/auth-with-password \
  -H "Content-Type: application/json" \
  -d '{"identity":"[email protected]","password":"SecurePassword123!"}' \
  | jq -r '.token')

πŸ’° Flow 3: CHECK BALANCE

When: User asks to check their balance.

Prerequisites

  • Must have valid $TOKEN in tk9-auth.txt
  • If file doesn't exist or token expired β†’ go to LOGIN FLOW

Step 1: Load Token

if [ -f tk9-auth.txt ]; then
  TOKEN=$(cat tk9-auth.txt)
  echo "βœ… Token loaded from tk9-auth.txt"
else
  echo "⚠️ No auth token found. Please login first."
  # Go to LOGIN FLOW
fi

Check TK9 Token Balance (Default)

curl -s https://wallet.tk9.dev/api/v2/balance-token \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "chainid": 7447,
    "tokenAddress": "0x20c0000000000000000000000000000000000000"
  }' | jq '.data.balanceInTokens'

Check Native Balance (TK9 coin)

curl -s https://wallet.tk9.dev/api/v2/balance-native \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chainid": 7447}' | jq '.data.balanceInTokens'

Response to User:

Bot: "πŸ’° Your TK9 Token Balance: X.XX TK9
πŸ’Ž Your Native Balance: Y.YY TK9"

πŸ“€ Flow 4: SEND TOKENS

When: User wants to send/transfer tokens.

Prerequisites

  • Must have valid $TOKEN in tk9-auth.txt (if expired β†’ go to LOGIN FLOW)
  • Must have PIN (check tk9-pin.txt or ask user)

Step 0: Load Token

if [ -f tk9-auth.txt ]; then
  TOKEN=$(cat tk9-auth.txt)
  echo "βœ… Token loaded from tk9-auth.txt"
else
  echo "⚠️ No auth token found. Please login first."
  # Go to LOGIN FLOW
  exit 1
fi

Step 1: Check PIN

if [ -f tk9-pin.txt ]; then
  PIN=$(cat tk9-pin.txt)
  echo "βœ… Using PIN from tk9-pin.txt"
else
  echo "⚠️ No PIN file found"
fi

If no PIN file, ask user:

Bot: "To transfer tokens, I need your PIN.

Options:
1. Enter your PIN now (I won't save it)
2. Save your PIN to tk9-pin.txt for future use:
   echo \"YOUR_PIN\" > tk9-pin.txt

Please provide your PIN:"

Step 2: Get Transfer Details

Bot: "Please provide:
1. Recipient wallet address (0x...)"
User: "0xA3570FCDA303F55e0978be450f87F885d80a3758"

Bot: "2. Amount to send:"
User: "0.1"

Bot: "3. Token (default is TK9 token, or specify another token address):"
User: "default" or "0x..."

Step 3: Check Balance Before Transfer

BALANCE=$(curl -s https://wallet.tk9.dev/api/v2/balance-token \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "chainid": 7447,
    "tokenAddress": "0x20c0000000000000000000000000000000000000"
  }' | jq -r '.data.balanceInTokens')

echo "Current balance: $BALANCE"

If insufficient balance:

Bot: "⚠️ Insufficient balance.
Your balance: X.XX TK9
Amount to send: Y.YY TK9

Please add more funds to your wallet first."

Step 4: Execute Transfer

curl -s -X POST https://wallet.tk9.dev/api/v2/send-token \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "chainid": 7447,
    "tokenAddress": "0x20c0000000000000000000000000000000000000",
    "to": "0xA3570FCDA303F55e0978be450f87F885d80a3758",
    "amount": "0.1",
    "passwordSecretkey": "5678"
  }'

Success Response:

{
  "success": true,
  "data": {
    "transactionHash": "0x123abc...",
    "from": "0x...",
    "to": "0xA3570FCDA303F55e0978be450f87F885d80a3758",
    "amount": "0.1",
    "tokenAddress": "0x20c00..."
  }
}

Confirm to User:

Bot: "βœ… Transfer successful!

πŸ“€ Amount: 0.1 TK9
πŸ‘› To: 0xA3570FCDA303F55e0978be450f87F885d80a3758
πŸ”— Transaction: 0x123abc...

View on explorer: https://chain.tk9.dev/tx/0x123abc..."

πŸ”‘ Flow 5: CHANGE PIN

When: User wants to change their PIN.

Prerequisites

  • Must have valid $TOKEN in tk9-auth.txt (if expired β†’ go to LOGIN FLOW)
  • Must know current PIN

Step 0: Load Token

if [ -f tk9-auth.txt ]; then
  TOKEN=$(cat tk9-auth.txt)
  echo "βœ… Token loaded from tk9-auth.txt"
else
  echo "⚠️ No auth token found. Please login first."
  # Go to LOGIN FLOW
  exit 1
fi

Step 1: Get PINs

Bot: "Please enter your current PIN:"
User: "1234"

Bot: "Please enter your new PIN (4-6 digits):"
User: "5678"

Step 2: Execute PIN Change

curl -s -X POST https://wallet.tk9.dev/api/v2/change-pin \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "oldPasswordSecretkey": "1234",
    "newPasswordSecretkey": "5678"
  }'

Step 3: Update PIN File

echo "5678" > tk9-pin.txt

Step 4: Confirm to User

Bot: "βœ… PIN changed successfully!

πŸ”‘ Your PIN has been updated in tk9-pin.txt

⚠️ IMPORTANT:
- All future transfers will use your new PIN
- Your old PIN no longer works
- Keep your new PIN secure"

πŸ” PIN Management Rules

Critical Information:

1. Chain ID Rule:

  • ALWAYS use chainid: 7447 (TK9 Chain)
  • Never ask user for chain ID
  • Never use any other chain ID
  • All operations are on TK9 Chain only

2. First Time (Custodial Mode):

  • PIN is auto-generated and stored in database
  • API calls work WITHOUT explicit passwordSecretkey parameter
  • System retrieves PIN from database automatically
  • BUT: Strongly recommend user to change PIN immediately

3. After PIN Change (Non-Custodial Mode):

  • PIN is REMOVED from database permanently
  • ALL transfers REQUIRE passwordSecretkey parameter
  • Server has zero knowledge of user's PIN
  • User must provide PIN every time OR save to tk9-pin.txt

4. PIN Storage:

  • AI agent CAN save PIN to tk9-pin.txt in workspace
  • User can delete the file anytime: rm tk9-pin.txt
  • File is local only - not uploaded to server
  • User can recreate file: echo "PIN" > tk9-pin.txt

5. PIN Format:

  • 4-6 digits only
  • Examples: 1234, 567890
  • No letters or special characters

πŸ“ Response Handling

Success Response

{
  "success": true,
  "data": {
    "transactionHash": "0x...",
    "from": "0x...",
    "to": "0x...",
    "amount": 0.1
  }
}

Action: Return transaction hash and details to user with explorer link.

Error Response

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient token balance"
  }
}

Action: Report error clearly with suggested action.


⚠️ Troubleshooting

Issue: Token expired

Fix: Re-login with OTP

# Request new OTP
curl -s -X POST https://wallet.tk9.dev/api/v2/request-otp \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'

# User provides OTP code, then authenticate
TOKEN=$(curl -s -X POST https://wallet.tk9.dev/api/v2/auth-with-otp \
  -H "Content-Type: application/json" \
  -d '{"otpId": "NEW_OTP_ID", "password": "OTP_CODE"}' \
  | jq -r '.token')

# Save new token
echo "$TOKEN" > tk9-auth.txt
echo "βœ… New token saved to tk9-auth.txt"

Issue: No PIN file found

Fix: Ask user for PIN or create file

Bot: "No PIN file found. Please:
1. Enter your PIN now, or
2. Create tk9-pin.txt: echo \"YOUR_PIN\" > tk9-pin.txt"

Issue: Wrong PIN

Fix: User must provide correct PIN

  • No PIN reset available (non-custodial)
  • If forgotten, user must create new account

Issue: Insufficient balance

Fix: Check balance and inform user

  • Show current balance
  • Show required amount
  • Ask user to fund wallet first

Issue: Invalid address

Fix: Verify address format

  • Must start with 0x
  • Must be 42 characters (0x + 40 hex chars)
  • Example: 0xA3570FCDA303F55e0978be450f87F885d80a3758

🌐 Blockchain Network

TK9 Chain ONLY

This wallet system operates exclusively on TK9 Chain:

Property Value
Chain ID 7447
Network Name TK9 Chain
Native Token TK9
Block Explorer https://chain.tk9.dev
RPC URL https://rpc.tk9.dev

⚠️ CRITICAL RULES FOR AI AGENTS:

  • ALWAYS use chainid: 7447 in ALL API calls
  • NEVER ask user which chain to use
  • NEVER use any other chain ID (7442, 1, 56, etc.)
  • All wallet operations are on TK9 Chain only
  • If user mentions other chains, inform them this wallet is TK9-only

πŸ“š Quick Reference

API Endpoints

Endpoint Method Auth Description
/api/v2/register POST No Register new user
/api/v2/request-otp POST No Request OTP for login
/api/v2/auth-with-otp POST No Login with OTP
/api/v2/auth-with-password POST No Login with password (fallback)
/api/v2/change-pin POST Yes Change user PIN
/api/v2/balance-native GET Yes Check native balance
/api/v2/balance-token GET Yes Check token balance
/api/v2/send-native POST Yes Send native tokens
/api/v2/send-token POST Yes Send ERC-20 tokens
/api/v2/write-contract POST Yes Call smart contract
/api/v2/sign-typed-data POST Yes Sign EIP-712 data

Required Parameters by Operation

Operation Auth Token Chain ID PIN Required
Register No N/A No
Login (OTP) No N/A No
Login (Password) No N/A No
Check Balance Yes 7447 No
Send Tokens Yes 7447 Yes (after PIN change)
Send Native Yes 7447 Yes (after PIN change)
Change PIN Yes N/A Yes (old PIN)
Write Contract Yes 7447 Yes
Sign Data Yes 7447 Yes

⚠️ Chain ID Rule: ALL blockchain operations MUST use chainid: 7447. Never use any other value.


πŸ”’ Security Guidelines

  1. Never expose user's PIN in logs or responses
  2. Always use HTTPS for production
  3. JWT tokens expire after 7 days - re-authenticate when needed
    • Token is stored in tk9-auth.txt
    • Delete file if user logs out: rm tk9-auth.txt
  4. PIN is non-recoverable after first change
  5. Store PIN securely - tk9-pin.txt is local only
  6. Verify email before operations - unverified accounts deleted after 24h
  7. Auth token file - tk9-auth.txt contains sensitive JWT token
    • Do not commit to git
    • Delete when user logs out
    • Re-login if token expires

Last Updated: 2026-04-05
Version: 1.1.0
Compatible with: Clawbot, any curl-capable AI agent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment