mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-08-09 02:54:37 +00:00
217 lines
5.4 KiB
TypeScript
217 lines
5.4 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;
|
|
error_code?: 'rate_limited' | 'unreachable' | 'cooldown' | 'mint_error';
|
|
retry_after_seconds?: number;
|
|
}
|
|
|
|
export interface WithdrawResponse {
|
|
token: string;
|
|
mint_url: 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;
|
|
}
|
|
}
|
|
}
|