Skip to main content

Headless Wallet Skill

The hathor-wallet-headless skill helps LLMs guide developers through practical integrations with Hathor's Headless Wallet. We recommend using this skill when you want to integrate with LLMs to help you design, implement, or debug wallet-related workflows, such as payment backends, token operations, wallet automation, transaction proposals, multisig flows, atomic swaps, or nano contract execution through the Headless Wallet.

tip

If you would like a more in-depth introduction to Headless Wallet, please refer to the Headless Wallet component documentation

Preparing Headless Wallet

Before testing application code, make sure your Headless Wallet is properly set up using the official setup documentation. Our network supports multiple installation methods, so choose the one that best fits your development needs:

tip

Source installation is mainly recommended when developing Headless Wallet use cases or derived wallet applications.

Verifying Skill Availability

After a correct skill installation, the LLM should use this skill when your request mentions:

  • wallet-headless
  • headless wallet
  • Hathor wallet API
  • /wallet/- endpoints
  • x-wallet-id
  • HTR transfers
  • token creation
  • NFTs
  • nano contracts through Headless Wallet
  • atomic swaps
  • multisig wallet flows
  • transaction proposals

To verify this, you can start a new agent session and run this test prompt:

/hathor-wallet-headless

You can then ask a small test question:

/hathor-wallet-headless

Help me design a safe backend flow for sending HTR with Hathor Headless Wallet.
Do not write code yet. Give me the architecture and the docs I should check.

A useful response should focus on the Headless Wallet workflow, mention server-side handling, warn against exposing secrets, and point you to the official Headless Wallet docs and API reference.

This skill can help you with any integration that involves the Headless Wallet component, such as:

  • Designing a wallet integration flow.
  • Creating a backend service that talks to the Headless Wallet.
  • Building a payment backend or single endpoint.
  • Checking wallet readiness before sending transactions.
  • Converting user-facing HTR values into API-safe integer values.
  • Reviewing whether requests include the required wallet headers.
  • Handling Headless Wallet error responses.
  • Creating token, NFT, multisig, atomic swap, or nano contract workflows.
  • Identifying which Hathor documentation article should be checked before implementing a specific step.

If you are still deciding whether Headless Wallet is the right component for your integration, start with the Headless Wallet component documentation. If you already know the feature you want to build and need help turning it into code, use this skill with your LLM.

Standard LLM workflow

When working with any LLM within the Hathor ecosystem, you can follow this general workflow to get the most out of the hathor-wallet-headless skill:

  1. Describe the product feature you want to build.
  2. Tell the LLM that the integration uses Hathor Headless Wallet.
  3. Ask for an architecture or implementation plan before asking for code.
  4. Ask the LLM to point out which official Hathor docs must be checked during the implementation in case of errors, updates, or changes.
  5. Ask for a review checklist before testing with real funds or production infrastructure.

For Headless Wallet setup, installation, or operation, use the Headless Wallet component docs as the starting point. For exact endpoint payloads, use the Headless Wallet API reference.

Example prompt:

/hathor-wallet-headless

I want to build a backend endpoint that sends HTR from a server-managed wallet.

Before writing code, give me:
1. The recommended architecture.
2. The Headless Wallet operations involved.
3. The security concerns.
4. The official Hathor docs I should check at each step.
5. A step-by-step development plan.

Do not repeat the full API reference. Reference the official docs where endpoint details must be verified.

Asking Better Questions

Avoid asking the LLM to explain the entire Headless Wallet API. The API reference already serves that purpose.

Instead, ask the LLM to help you move from a product requirement to a safe implementation.

Ambiguous Prompt

Explain every Headless Wallet endpoint.

Comprehensive Prompt

/hathor-wallet-headless

I need to implement a server-side HTR payment flow.

Help me identify:
- which Headless Wallet operations are needed
- which parts belong in my backend
- which endpoint details I must verify in the API reference
- which setup guide I should follow for local testnet testing
- what security issues I should check before production

Development Example

This use case shows how a developer can use the skill with an LLM to build a practical server-side HTR payment flow feature while relying on the official Headless Wallet documentation for component and endpoint details.

Use Case Description

A developer wants to add a payment endpoint to their backend:

POST /payments/send-htr

The endpoint receives:

{
"address": "destination-address",
"amount": 1.25
}

The backend should send 1.25 HTR using Headless Wallet and return the transaction hash.

Before implementing this flow, it's important to understand that Headless Wallet is the API-based wallet component intended for external systems integrating with Hathor Network.

tip

For more information, check out Headless Wallet component documentation.

LLM-defined Architecture

As a general best-practice approach, start by asking for the system design, not the code.

/hathor-wallet-headless

I want to create POST /payments/send-htr in my backend.

Give me the recommended architecture for using Hathor Headless Wallet safely.

Include:
- which logic belongs in my backend
- which logic belongs in Headless Wallet
- which secrets must stay server-side
- which official Hathor article or document is relevant for each step
- what can go wrong during development

A good LLM answer should explain that the application backend should act as the controlled integration layer between your application and Headless Wallet. The backend should own the integration, and the frontend should never call Headless Wallet directly.

Example of expected output:

  • The frontend should not directly call a privileged Headless Wallet service.
  • The backend should own the integration with Headless Wallet.
  • Seeds, API keys, and wallet configuration must stay server-side.
  • The backend should validate the destination address and amount.
  • The backend should convert user-facing HTR values into the integer format expected by Headless Wallet.
  • The backend should check wallet readiness before sending transactions.
  • The developer should verify endpoint-specific behavior in the Headless Wallet API reference.

Recommended responsibility boundary:

Frontend responsibility:
- collect the destination address
- collect the user-facing amount
- call your backend payment endpoint
- display success or failure state
- never call Headless Wallet directly
- never receive wallet secrets

Backend responsibility:
- authenticate and authorize the user request
- validate address and amount
- convert HTR values into integer units
- call Headless Wallet with server-side configuration
- handle Headless Wallet errors
- return only the data needed by the frontend

Headless Wallet responsibility:
- manage wallet operations
- build and submit transactions
- expose wallet status and transaction APIs
- interact with Hathor Network

Use this separation when asking the LLM to generate code so it does not mix frontend concerns with privileged wallet operations.

Preparing Local Environments

Before generating application code, make sure Headless Wallet is available in your development environment.

Ask the LLM:

/hathor-wallet-headless

I need to prepare my local development environment for testing a backend payment endpoint with Headless Wallet.

Do not repeat the full setup guide.

Tell me:
- which official setup article I should follow
- which environment variables my backend will likely need
- how to confirm that Headless Wallet is reachable
- how to avoid using production funds during development

Example of expected output:

  • Install or run Headless Wallet using the official setup guide.
  • Configure the wallet for testnet before testing transfers.
  • Use backend environment variables such as HEADLESS_URL, HEADLESS_WALLET_ID, and optionally HEADLESS_API_KEY.
  • Confirm the service is reachable before implementing the payment endpoint.
  • Avoid testing with production funds.

Backend environment configuration example:

# Base URL of the Headless Wallet service.
HEADLESS_WALLET_URL=http://localhost:8000

# Wallet identifier used by wallet-specific API calls.
# Confirm how your wallet ID is created and used in the official docs.
HEADLESS_WALLET_ID=your-wallet-id

# Optional API key or internal secret if your deployment protects Headless Wallet.
# Do not expose this value to the frontend.
HEADLESS_WALLET_API_KEY=change-me

# Network safety flag for local development.
HATHOR_NETWORK=testnet

Keep these values server-side. The frontend should call your backend endpoint, not the Headless Wallet service directly.

Example TypeScript configuration helper:

// src/config/headlessWalletConfig.ts

export type HeadlessWalletConfig = {
baseUrl: string;
walletId: string;
apiKey?: string;
network: 'testnet' | 'mainnet' | 'privatenet';
};

export function getHeadlessWalletConfig(): HeadlessWalletConfig {
const baseUrl = process.env.HEADLESS_WALLET_URL;
const walletId = process.env.HEADLESS_WALLET_ID;
const apiKey = process.env.HEADLESS_WALLET_API_KEY;
const network = process.env.HATHOR_NETWORK ?? 'testnet';

if (!baseUrl) {
throw new Error('Missing HEADLESS_WALLET_URL');
}

if (!walletId) {
throw new Error('Missing HEADLESS_WALLET_ID');
}

if (!['testnet', 'mainnet', 'privatenet'].includes(network)) {
throw new Error('Invalid HATHOR_NETWORK value');
}

return {
baseUrl,
walletId,
apiKey,
network: network as HeadlessWalletConfig['network'],
};
}

This helper keeps configuration validation close to application startup and prevents route handlers from reading environment variables directly.

Implementation Plan

Once the environment is clear and the development requirements are defined, we can move on to asking for a plan.

/hathor-wallet-headless

Now give me a development plan for implementing POST /payments/send-htr.

Do not write code yet.

Include:
1. files/modules to create
2. environment variables
3. request validation
4. Headless Wallet client methods
5. where to verify endpoint schemas in the official API reference
6. error handling
7. local testing steps
8. production safety checks

The LLM should tell you where API details must be verified. For example, wallet startup, wallet status, and transaction sending should be checked against the Headless Wallet API reference before finalizing the implementation.

Example of expected plan:

  1. Add Headless Wallet environment variables.
  2. Create a reusable Headless Wallet HTTP client.
  3. Add a method to read wallet status.
  4. Add a method to send HTR.
  5. Add amount conversion.
  6. Add API request validation.
  7. Add safe error handling.
  8. Test against a local or testnet Headless Wallet instance.
  9. Review endpoint payloads against the API reference.
  10. Review deployment assumptions against the Headless Wallet component documentation.

HTR amount conversion helper example:

// src/utils/htrAmount.ts

const HTR_DECIMALS = 2;
const HTR_FACTOR = 10 ** HTR_DECIMALS;

export function htrToIntegerAmount(amount: number): number {
if (!Number.isFinite(amount)) {
throw new Error('Amount must be a valid number');
}

if (amount <= 0) {
throw new Error('Amount must be greater than zero');
}

const integerAmount = Math.round(amount * HTR_FACTOR);

if (integerAmount <= 0) {
throw new Error('Amount is too small');
}

if (Math.abs(integerAmount / HTR_FACTOR - amount) > Number.EPSILON) {
throw new Error('Amount has too many decimal places');
}

return integerAmount;
}

Use this kind of helper before calling Headless Wallet so the backend does not forward user-facing decimal values directly.

Asking for Code

After the plan is approved, we can move on to asking for code.

/hathor-wallet-headless

Generate the backend code for this payment endpoint.

Use TypeScript.

Create:
- HeadlessWalletClient
- htrToIntegerAmount helper
- POST /payments/send-htr route handler

Requirements:
- read configuration from environment variables
- keep secrets server-side
- check wallet readiness before sending
- parse Headless Wallet errors defensively
- return only the transaction hash to the client
- add comments where I must confirm endpoint-specific fields in the official API reference

Example HeadlessWalletClient draft:

// src/integrations/headless-wallet/HeadlessWalletClient.ts

export type HeadlessWalletClientOptions = {
baseUrl: string;
walletId: string;
apiKey?: string;
};

export type SendHtrInput = {
address: string;
amount: number;
};

export type SendHtrResult = {
txId: string;
};

export class HeadlessWalletClient {
private readonly baseUrl: string;
private readonly walletId: string;
private readonly apiKey?: string;

constructor(options: HeadlessWalletClientOptions) {
this.baseUrl = options.baseUrl.replace(/\/$/, '');
this.walletId = options.walletId;
this.apiKey = options.apiKey;
}

private buildHeaders(): HeadersInit {
const headers: HeadersInit = {
'content-type': 'application/json',

// Confirm the exact wallet identifier header in the official API reference.
'x-wallet-id': this.walletId,
};

if (this.apiKey) {
// Confirm the authentication mechanism used by your deployment.
headers.authorization = `Bearer ${this.apiKey}`;
}

return headers;
}

async getWalletStatus(): Promise<unknown> {
// Confirm the exact status endpoint in the official API reference.
const response = await fetch(`${this.baseUrl}/wallet/status`, {
method: 'GET',
headers: this.buildHeaders(),
});

if (!response.ok) {
throw await this.toHeadlessWalletError(response);
}

return response.json();
}

async sendHtr(input: SendHtrInput): Promise<SendHtrResult> {
// Confirm the exact transfer endpoint, request body, and response shape
// in the official Headless Wallet API reference.
const response = await fetch(`${this.baseUrl}/wallet/simple-send-tx`, {
method: 'POST',
headers: this.buildHeaders(),
body: JSON.stringify({
outputs: [
{
address: input.address,
value: input.amount,
},
],
}),
});

if (!response.ok) {
throw await this.toHeadlessWalletError(response);
}

const data = await response.json();

return {
// Confirm the exact transaction hash field in the API response.
txId: data.tx_id ?? data.hash ?? data.txId,
};
}

private async toHeadlessWalletError(response: Response): Promise<Error> {
let details: unknown;

try {
details = await response.json();
} catch {
details = await response.text();
}

return new Error(
`Headless Wallet request failed with status ${response.status}: ${JSON.stringify(details)}`
);
}
}

This sample is intentionally marked with verification comments. It demonstrates the integration shape while keeping endpoint-specific details tied to the official API reference.

Example Express-style route handler:

// src/routes/payments.ts

import { Router } from 'express';
import { getHeadlessWalletConfig } from '../config/headlessWalletConfig';
import { HeadlessWalletClient } from '../integrations/headless-wallet/HeadlessWalletClient';
import { htrToIntegerAmount } from '../utils/htrAmount';

const router = Router();

router.post('/payments/send-htr', async (req, res) => {
try {
const { address, amount } = req.body;

if (typeof address !== 'string' || address.trim().length === 0) {
return res.status(400).json({
message: 'Destination address is required',
});
}

if (typeof amount !== 'number') {
return res.status(400).json({
message: 'Amount must be a number',
});
}

const config = getHeadlessWalletConfig();

if (config.network !== 'testnet') {
// Keep this guard during early development.
// Remove or adjust it only after production readiness review.
return res.status(400).json({
message: 'This endpoint is currently restricted to testnet',
});
}

const integerAmount = htrToIntegerAmount(amount);

const client = new HeadlessWalletClient({
baseUrl: config.baseUrl,
walletId: config.walletId,
apiKey: config.apiKey,
});

// Confirm what "ready" means for your wallet using the official API reference.
await client.getWalletStatus();

const result = await client.sendHtr({
address,
amount: integerAmount,
});

return res.status(200).json({
txId: result.txId,
});
} catch (error) {
console.error('Failed to send HTR', {
// Avoid logging secrets, seeds, private keys, or full wallet config.
message: error instanceof Error ? error.message : 'Unknown error',
});

return res.status(500).json({
message: 'Failed to send HTR',
});
}
});

export default router;

This route keeps privileged wallet operations in the backend and returns only the transaction identifier to the client.

The generated code should not hardcode endpoint assumptions that should be checked in the API reference. A useful implementation can include comments such as:

note

Confirm the exact request body and response shape in the official Headless Wallet API reference before using this in production.

This keeps the generated code practical without turning the LLM article into an endpoint reference.

LLM Output Self-review

Before testing the generated code, request the LLM for a review of its own output following a self-review pattern or criteria.

/hathor-wallet-headless

Review the generated implementation.

Check it against this checklist:
- No seed is hardcoded.
- No API key is logged.
- Headless Wallet is called only from the backend.
- The wallet is checked before sending.
- The amount is converted before calling Headless Wallet.
- The response does not expose unnecessary wallet data.
- Error messages are useful but do not leak secrets.
- Any endpoint-specific assumption is marked for verification in the official API reference.
- Local testing points to the Headless Wallet testnet setup guide.

If the LLM finds that the code assumes too much about endpoint payloads or response shapes, ask it to revise the code and point the developer to the Headless Wallet API reference for final verification.

Testing locally

Once the implementation is reviewed, ask for a testing checklist.

/hathor-wallet-headless

Give me a local testing checklist for POST /payments/send-htr.

Assume I already have Headless Wallet installed.

Reference the official Headless Wallet docs instead of repeating setup instructions.

Focus on:
- environment variables
- wallet status
- testnet usage
- sample request
- expected response
- common integration mistakes

For testnet-specific setup, use Connect Headless Wallet to testnet. If the service is being installed from scratch, use Install Headless Wallet with Docker.

If the LLM suggests mainnet testing before testnet validation, ask it to revise the plan.

Example of expected checklist:

  • Confirm Headless Wallet is running.
  • Confirm the backend points to the correct Headless Wallet URL.
  • Confirm the wallet is configured for testnet.
  • Confirm the backend has the expected wallet identifier configured.
  • Confirm the wallet is ready before sending.
  • Send a small testnet request.
  • Confirm the backend returns only the required transaction data.
  • Confirm no secrets are printed in logs.

Example local request:

curl -X POST http://localhost:3000/payments/send-htr \
-H "Content-Type: application/json" \
-d '{
"address": "destination-address",
"amount": 1.25
}'

Example successful backend response:

{
"txId": "transaction-hash"
}

Example validation error response:

{
"message": "Amount must be a number"
}

The exact transaction hash field returned by Headless Wallet should be confirmed in the official API reference before finalizing the backend response mapping.

Prompt Patterns for Common Tasks

Building a Headless Wallet client

/hathor-wallet-headless

Create a reusable backend client for Hathor Headless Wallet.

The client should:
- read its base URL and credentials from environment variables
- support the wallet identifier required by wallet-specific calls
- expose methods for wallet status and simple HTR transfer
- handle non-uniform error responses defensively
- include comments where endpoint details must be checked in the official API reference

Do not duplicate the API reference.

Use this when you are ready to write application code. If you are unsure what Headless Wallet is or how it should be operated, first read the Headless Wallet component documentation.

Adding Tokens/NFT Functionalities

/hathor-wallet-headless

Help me design a token or NFT flow using Hathor Headless Wallet.

Start with the development workflow:
- what the user action is
- what my backend should validate
- which Headless Wallet operation is involved
- which endpoint details I must verify in the API reference
- what security checks are needed before sending the request

Do not list every token endpoint.

Use the LLM to design the flow and review your application logic. Use the Headless Wallet API reference to confirm the exact token or NFT endpoint schema.

Debugging Integrations

/hathor-wallet-headless

I am getting an error from Headless Wallet.

Help me debug it step by step.

Ask me to provide:
- the endpoint being called
- the request method
- the headers, without secrets
- the request body, without seeds or private data
- the response body
- whether the wallet is started and synced

Do not ask me to share seeds, API keys, or private keys.
Point me to the official Headless Wallet docs when the issue depends on setup or endpoint schema.

If the issue is about installation, networking, or running the service, check the Headless Wallet component documentation and the relevant setup guide. If the issue is about request fields or response formats, check the API reference.

Reviewing Existing Code

/hathor-wallet-headless

Review this Headless Wallet integration.

Check whether:
- wallet operations are server-side only
- sensitive values are not logged
- wallet-specific requests include the required wallet identifier
- HTR amounts are converted safely
- wallet readiness is checked before sending transactions
- errors are handled defensively
- endpoint assumptions are verified against the official API reference
- setup assumptions are verified against the Headless Wallet component docs

Here is the code:

This is especially useful before opening a pull request or testing against a shared environment.

LLM guardrails

When using this skill, the LLM should follow these rules:

  • Do not invent endpoint schemas.
  • Do not replace the official Headless Wallet API reference.
  • Do not ask the user to paste seeds, private keys, or API keys.
  • Do not suggest logging sensitive wallet data.
  • Prefer server-side wallet integrations for privileged operations.
  • Ask the user to verify endpoint-specific payloads against the API reference.
  • Reference the Headless Wallet component docs for installation and operation.
  • Reference the setup guides when the user needs Docker, source-code installation, or testnet instructions.
  • Explain assumptions clearly.