Files
2026-02-02 22:29:54 +01:00

214 lines
5.3 KiB
TypeScript

import { z } from 'zod';
import { apiClient } from '../client';
// Schema for redeeming tokens
export const RedeemTokenRequestSchema = z.object({
token: z.string().min(1),
});
export const RedeemTokenResponseSchema = z.object({
success: z.boolean(),
amount: z.number().optional(),
message: z.string().optional(),
});
// Schema for sending tokens
export const SendTokenRequestSchema = z.object({
amount: z.number().positive(),
offline: z.boolean().optional(),
});
export const SendTokenResponseSchema = z.object({
token: z.string(),
balance: z.number(),
npub: z.string().optional(),
});
export type RedeemTokenRequest = z.infer<typeof RedeemTokenRequestSchema>;
export type RedeemTokenResponse = z.infer<typeof RedeemTokenResponseSchema>;
export type SendTokenRequest = z.infer<typeof SendTokenRequestSchema>;
export type SendTokenResponse = z.infer<typeof SendTokenResponseSchema>;
export interface BalanceDetail {
mint_url: string;
unit: string;
wallet_balance: number;
user_balance: number;
owner_balance: number;
error?: string;
}
export interface WithdrawResponse {
token: string;
}
export interface CreateChildKeyResponse {
api_keys: string[];
count: number;
cost_msats: number;
cost_sats: number;
parent_balance: number;
parent_balance_sats: number;
}
export class WalletService {
static async redeemToken(token: string): Promise<RedeemTokenResponse> {
try {
const response = await apiClient.post<RedeemTokenResponse>(
'/api/wallet/redeem',
{ token }
);
return response;
} catch (error) {
console.error('Error redeeming token:', error);
return {
success: false,
message: 'Failed to redeem token. Please try again.',
};
}
}
static async sendToken(amount: number): Promise<SendTokenResponse> {
try {
const response = await apiClient.post<SendTokenResponse>(
'/api/wallet/send',
{ amount }
);
return response;
} catch (error) {
console.error('Error generating token:', error);
throw new Error('Failed to generate token. Please try again.');
}
}
static async getBalance(): Promise<{ balance: number }> {
try {
const response = await apiClient.get<{ balance: number }>(
'/api/wallet/balance'
);
return response;
} catch (error) {
console.error('Error fetching balance:', error);
throw error;
}
}
static async getDetailedBalances(): Promise<BalanceDetail[]> {
try {
const response = await apiClient.get<BalanceDetail[]>(
'/admin/api/balances'
);
return response;
} catch (error) {
console.error('Error fetching detailed balances:', error);
throw error;
}
}
static async withdraw(
amount: number,
mintUrl?: string,
unit: string = 'sat'
): Promise<WithdrawResponse> {
try {
const response = await apiClient.post<WithdrawResponse>(
'/admin/withdraw',
{
amount,
mint_url: mintUrl,
unit,
}
);
return response;
} catch (error) {
console.error('Error withdrawing funds:', error);
throw error;
}
}
static async createChildKey(
baseUrl?: string,
apiKey?: string,
count: number = 1,
balanceLimit?: number,
balanceLimitReset?: string,
validityDate?: number
): Promise<CreateChildKeyResponse> {
try {
if (baseUrl && apiKey) {
const response = await fetch(`${baseUrl}/v1/balance/child-key`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
count,
balance_limit: balanceLimit,
balance_limit_reset: balanceLimitReset,
validity_date: validityDate,
}),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(errorText || 'Failed to create child key');
}
return (await response.json()) as CreateChildKeyResponse;
}
return await apiClient.post<CreateChildKeyResponse>(
'/v1/balance/child-key',
{
count,
balance_limit: balanceLimit,
balance_limit_reset: balanceLimitReset,
validity_date: validityDate,
}
);
} catch (error) {
console.error('Error creating child key:', error);
throw error;
}
}
static async resetChildKeySpent(
baseUrl: string | undefined,
parentKey: string,
childKey: string
): Promise<{ success: boolean; message: string }> {
try {
const url = baseUrl
? `${baseUrl}/v1/balance/child-key/reset`
: '/v1/balance/child-key/reset';
const headers: Record<string, string> = {
'Content-Type': 'application/json',
Authorization: `Bearer ${parentKey}`,
};
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ child_key: childKey }),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(errorText || 'Failed to reset child key');
}
return await response.json();
} catch (error) {
console.error('Error resetting child key:', error);
throw error;
}
}
}