globodai-mcp-payment-manager 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.env.example +23 -0
  2. package/.github/workflows/ci.yml +26 -0
  3. package/.github/workflows/release.yml +82 -0
  4. package/LICENSE +21 -0
  5. package/README.md +362 -0
  6. package/dist/index.d.ts +31 -0
  7. package/dist/index.js +122 -0
  8. package/dist/lib/blockchain.d.ts +50 -0
  9. package/dist/lib/blockchain.js +287 -0
  10. package/dist/lib/cards.d.ts +83 -0
  11. package/dist/lib/cards.js +276 -0
  12. package/dist/lib/cli-runner.d.ts +31 -0
  13. package/dist/lib/cli-runner.js +77 -0
  14. package/dist/lib/crypto.d.ts +39 -0
  15. package/dist/lib/crypto.js +228 -0
  16. package/dist/lib/cvv-crypto.d.ts +23 -0
  17. package/dist/lib/cvv-crypto.js +67 -0
  18. package/dist/lib/mcp-core.d.ts +46 -0
  19. package/dist/lib/mcp-core.js +86 -0
  20. package/dist/lib/pin-manager.d.ts +69 -0
  21. package/dist/lib/pin-manager.js +199 -0
  22. package/dist/lib/wallets.d.ts +91 -0
  23. package/dist/lib/wallets.js +227 -0
  24. package/dist/tools/add-card.d.ts +65 -0
  25. package/dist/tools/add-card.js +97 -0
  26. package/dist/tools/add-wallet.d.ts +65 -0
  27. package/dist/tools/add-wallet.js +104 -0
  28. package/dist/tools/card-status.d.ts +20 -0
  29. package/dist/tools/card-status.js +26 -0
  30. package/dist/tools/confirm-payment.d.ts +44 -0
  31. package/dist/tools/confirm-payment.js +88 -0
  32. package/dist/tools/get-total-balance.d.ts +41 -0
  33. package/dist/tools/get-total-balance.js +98 -0
  34. package/dist/tools/get-transactions.d.ts +39 -0
  35. package/dist/tools/get-transactions.js +40 -0
  36. package/dist/tools/get-wallet-balance.d.ts +43 -0
  37. package/dist/tools/get-wallet-balance.js +69 -0
  38. package/dist/tools/list-cards.d.ts +36 -0
  39. package/dist/tools/list-cards.js +39 -0
  40. package/dist/tools/list-wallet-transactions.d.ts +63 -0
  41. package/dist/tools/list-wallet-transactions.js +76 -0
  42. package/dist/tools/list-wallets.d.ts +41 -0
  43. package/dist/tools/list-wallets.js +50 -0
  44. package/dist/tools/lock-cards.d.ts +16 -0
  45. package/dist/tools/lock-cards.js +23 -0
  46. package/dist/tools/prepare-crypto-tx.d.ts +69 -0
  47. package/dist/tools/prepare-crypto-tx.js +93 -0
  48. package/dist/tools/prepare-payment.d.ts +57 -0
  49. package/dist/tools/prepare-payment.js +93 -0
  50. package/dist/tools/remove-card.d.ts +25 -0
  51. package/dist/tools/remove-card.js +39 -0
  52. package/dist/tools/remove-wallet.d.ts +27 -0
  53. package/dist/tools/remove-wallet.js +40 -0
  54. package/dist/tools/setup-pin.d.ts +26 -0
  55. package/dist/tools/setup-pin.js +33 -0
  56. package/dist/tools/sign-crypto-tx.d.ts +42 -0
  57. package/dist/tools/sign-crypto-tx.js +75 -0
  58. package/dist/tools/unlock-cards.d.ts +35 -0
  59. package/dist/tools/unlock-cards.js +41 -0
  60. package/package.json +50 -0
  61. package/src/index.ts +139 -0
  62. package/src/lib/blockchain.ts +375 -0
  63. package/src/lib/cards.ts +372 -0
  64. package/src/lib/cli-runner.ts +113 -0
  65. package/src/lib/crypto.ts +284 -0
  66. package/src/lib/cvv-crypto.ts +81 -0
  67. package/src/lib/mcp-core.ts +127 -0
  68. package/src/lib/pin-manager.ts +252 -0
  69. package/src/lib/wallets.ts +331 -0
  70. package/src/tools/add-card.ts +108 -0
  71. package/src/tools/add-wallet.ts +114 -0
  72. package/src/tools/card-status.ts +32 -0
  73. package/src/tools/confirm-payment.ts +103 -0
  74. package/src/tools/get-total-balance.ts +123 -0
  75. package/src/tools/get-transactions.ts +49 -0
  76. package/src/tools/get-wallet-balance.ts +75 -0
  77. package/src/tools/list-cards.ts +52 -0
  78. package/src/tools/list-wallet-transactions.ts +83 -0
  79. package/src/tools/list-wallets.ts +63 -0
  80. package/src/tools/lock-cards.ts +31 -0
  81. package/src/tools/prepare-crypto-tx.ts +108 -0
  82. package/src/tools/prepare-payment.ts +108 -0
  83. package/src/tools/remove-card.ts +46 -0
  84. package/src/tools/remove-wallet.ts +47 -0
  85. package/src/tools/setup-pin.ts +39 -0
  86. package/src/tools/sign-crypto-tx.ts +90 -0
  87. package/src/tools/unlock-cards.ts +48 -0
  88. package/tsconfig.json +19 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Add a new crypto wallet
3
+ */
4
+ import { z } from "zod";
5
+ export declare const name = "add_wallet";
6
+ export declare const description = "Add a new crypto wallet. Supports hot wallets (with private key - encrypted), watch-only (address only), and hardware wallets (address + device info).\n\nFor hot wallets: private key will be encrypted at rest.\nFor watch-only: only the address is stored, no spending capability.\nFor hardware: address is stored, transactions require hardware signing.";
7
+ export declare const parameters: z.ZodObject<{
8
+ nickname: z.ZodString;
9
+ address: z.ZodString;
10
+ chain: z.ZodEnum<["ethereum", "polygon", "arbitrum", "optimism", "base", "avalanche", "bsc", "bitcoin", "solana", "starknet"]>;
11
+ type: z.ZodEnum<["hot", "watch-only", "hardware"]>;
12
+ private_key: z.ZodOptional<z.ZodString>;
13
+ mnemonic: z.ZodOptional<z.ZodString>;
14
+ hardware_type: z.ZodOptional<z.ZodEnum<["ledger", "trezor", "other"]>>;
15
+ derivation_path: z.ZodOptional<z.ZodString>;
16
+ allowed_operations: z.ZodOptional<z.ZodArray<z.ZodEnum<["send", "swap", "approve", "sign"]>, "many">>;
17
+ per_transaction_limit: z.ZodOptional<z.ZodNumber>;
18
+ daily_limit: z.ZodOptional<z.ZodNumber>;
19
+ limit_token: z.ZodOptional<z.ZodString>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ nickname: string;
22
+ type: "hot" | "watch-only" | "hardware";
23
+ address: string;
24
+ chain: "ethereum" | "polygon" | "arbitrum" | "optimism" | "base" | "avalanche" | "bsc" | "bitcoin" | "solana" | "starknet";
25
+ per_transaction_limit?: number | undefined;
26
+ daily_limit?: number | undefined;
27
+ mnemonic?: string | undefined;
28
+ private_key?: string | undefined;
29
+ hardware_type?: "other" | "ledger" | "trezor" | undefined;
30
+ derivation_path?: string | undefined;
31
+ allowed_operations?: ("send" | "swap" | "approve" | "sign")[] | undefined;
32
+ limit_token?: string | undefined;
33
+ }, {
34
+ nickname: string;
35
+ type: "hot" | "watch-only" | "hardware";
36
+ address: string;
37
+ chain: "ethereum" | "polygon" | "arbitrum" | "optimism" | "base" | "avalanche" | "bsc" | "bitcoin" | "solana" | "starknet";
38
+ per_transaction_limit?: number | undefined;
39
+ daily_limit?: number | undefined;
40
+ mnemonic?: string | undefined;
41
+ private_key?: string | undefined;
42
+ hardware_type?: "other" | "ledger" | "trezor" | undefined;
43
+ derivation_path?: string | undefined;
44
+ allowed_operations?: ("send" | "swap" | "approve" | "sign")[] | undefined;
45
+ limit_token?: string | undefined;
46
+ }>;
47
+ export declare function execute(args: z.infer<typeof parameters>): Promise<{
48
+ success: boolean;
49
+ error: string;
50
+ message?: undefined;
51
+ wallet_id?: undefined;
52
+ type?: undefined;
53
+ chain?: undefined;
54
+ address?: undefined;
55
+ security_note?: undefined;
56
+ } | {
57
+ success: boolean;
58
+ message: string;
59
+ wallet_id: `${string}-${string}-${string}-${string}-${string}`;
60
+ type: "hot" | "watch-only" | "hardware";
61
+ chain: "ethereum" | "polygon" | "arbitrum" | "optimism" | "base" | "avalanche" | "bsc" | "bitcoin" | "solana" | "starknet";
62
+ address: string;
63
+ security_note: string;
64
+ error?: undefined;
65
+ }>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Add a new crypto wallet
3
+ */
4
+ import { z } from "zod";
5
+ import { randomUUID } from "crypto";
6
+ import { addWallet } from "../lib/wallets";
7
+ export const name = "add_wallet";
8
+ export const description = `Add a new crypto wallet. Supports hot wallets (with private key - encrypted), watch-only (address only), and hardware wallets (address + device info).
9
+
10
+ For hot wallets: private key will be encrypted at rest.
11
+ For watch-only: only the address is stored, no spending capability.
12
+ For hardware: address is stored, transactions require hardware signing.`;
13
+ export const parameters = z.object({
14
+ nickname: z.string().describe("Friendly name for the wallet (e.g., 'ETH principal', 'Trading wallet')"),
15
+ address: z.string().describe("Public wallet address"),
16
+ chain: z.enum(["ethereum", "polygon", "arbitrum", "optimism", "base", "avalanche", "bsc", "bitcoin", "solana", "starknet"])
17
+ .describe("Blockchain network"),
18
+ type: z.enum(["hot", "watch-only", "hardware"]).describe("Wallet type"),
19
+ private_key: z.string().optional().describe("Private key (for hot wallets only - will be encrypted)"),
20
+ mnemonic: z.string().optional().describe("Seed phrase (for hot wallets only - will be encrypted)"),
21
+ hardware_type: z.enum(["ledger", "trezor", "other"]).optional().describe("Hardware wallet type"),
22
+ derivation_path: z.string().optional().describe("Derivation path (e.g., m/44'/60'/0'/0/0)"),
23
+ allowed_operations: z.array(z.enum(["send", "swap", "approve", "sign"])).optional()
24
+ .describe("Allowed operations (default: all for hot, none for watch-only)"),
25
+ per_transaction_limit: z.number().optional().describe("Max amount per transaction"),
26
+ daily_limit: z.number().optional().describe("Max daily spending"),
27
+ limit_token: z.string().optional().describe("Token symbol for limits (e.g., 'ETH', 'USDC')"),
28
+ });
29
+ export async function execute(args) {
30
+ try {
31
+ // Validate based on type
32
+ if (args.type === "hot" && !args.private_key && !args.mnemonic) {
33
+ return {
34
+ success: false,
35
+ error: "Hot wallets require either a private_key or mnemonic",
36
+ };
37
+ }
38
+ if (args.type === "watch-only" && (args.private_key || args.mnemonic)) {
39
+ return {
40
+ success: false,
41
+ error: "Watch-only wallets cannot have private keys",
42
+ };
43
+ }
44
+ if (args.type === "hardware" && !args.hardware_type) {
45
+ return {
46
+ success: false,
47
+ error: "Hardware wallets must specify hardware_type",
48
+ };
49
+ }
50
+ const walletId = randomUUID();
51
+ // Default operations based on type
52
+ let operations = args.allowed_operations;
53
+ if (!operations) {
54
+ if (args.type === "hot") {
55
+ operations = ["send", "swap", "approve", "sign"];
56
+ }
57
+ else if (args.type === "hardware") {
58
+ operations = ["send", "swap", "approve", "sign"]; // Requires hardware confirmation
59
+ }
60
+ else {
61
+ operations = []; // Watch-only can't do anything
62
+ }
63
+ }
64
+ await addWallet({
65
+ id: walletId,
66
+ nickname: args.nickname,
67
+ address: args.address,
68
+ chain: args.chain,
69
+ type: args.type,
70
+ privateKey: args.private_key,
71
+ mnemonic: args.mnemonic,
72
+ hardwareType: args.hardware_type,
73
+ derivationPath: args.derivation_path,
74
+ enabled: true,
75
+ allowedOperations: operations,
76
+ limits: args.per_transaction_limit || args.daily_limit ? {
77
+ perTransaction: args.per_transaction_limit,
78
+ daily: args.daily_limit,
79
+ tokenSymbol: args.limit_token ?? "ETH",
80
+ } : undefined,
81
+ addedAt: new Date().toISOString(),
82
+ });
83
+ const typeInfo = {
84
+ hot: "Private key encrypted and stored securely",
85
+ "watch-only": "Address only - no spending capability",
86
+ hardware: `${args.hardware_type} wallet - requires device for signing`,
87
+ };
88
+ return {
89
+ success: true,
90
+ message: `Wallet "${args.nickname}" added successfully`,
91
+ wallet_id: walletId,
92
+ type: args.type,
93
+ chain: args.chain,
94
+ address: `${args.address.slice(0, 10)}...${args.address.slice(-8)}`,
95
+ security_note: typeInfo[args.type],
96
+ };
97
+ }
98
+ catch (error) {
99
+ return {
100
+ success: false,
101
+ error: error instanceof Error ? error.message : "Failed to add wallet",
102
+ };
103
+ }
104
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Get card lock status
3
+ */
4
+ import { z } from "zod";
5
+ export declare const name = "card_status";
6
+ export declare const description = "Check if cards are locked or unlocked, and how many cards are saved.";
7
+ export declare const parameters: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
8
+ export declare function execute(_args: z.infer<typeof parameters>): Promise<{
9
+ success: boolean;
10
+ pin_configured: boolean;
11
+ cards_unlocked: boolean;
12
+ remaining_minutes: number | null;
13
+ saved_cards: number;
14
+ cards: {
15
+ nickname: string;
16
+ type: string;
17
+ lastFour: string;
18
+ enabled: boolean;
19
+ }[];
20
+ }>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Get card lock status
3
+ */
4
+ import { z } from "zod";
5
+ import { getStatus } from "../lib/pin-manager";
6
+ import { getCardsSafe } from "../lib/cards";
7
+ export const name = "card_status";
8
+ export const description = "Check if cards are locked or unlocked, and how many cards are saved.";
9
+ export const parameters = z.object({});
10
+ export async function execute(_args) {
11
+ const pinStatus = getStatus();
12
+ const cards = await getCardsSafe();
13
+ return {
14
+ success: true,
15
+ pin_configured: pinStatus.configured,
16
+ cards_unlocked: pinStatus.unlocked,
17
+ remaining_minutes: pinStatus.remainingMinutes ?? null,
18
+ saved_cards: cards.length,
19
+ cards: cards.map((c) => ({
20
+ nickname: c.nickname,
21
+ type: c.cardType.toUpperCase(),
22
+ lastFour: `****${c.lastFourDigits}`,
23
+ enabled: c.enabled,
24
+ })),
25
+ };
26
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Confirm and execute a prepared payment
3
+ *
4
+ * This is where the actual charge would happen.
5
+ * CVV is retrieved from encrypted storage (requires PIN unlock).
6
+ */
7
+ import { z } from "zod";
8
+ export declare const name = "confirm_payment";
9
+ export declare const description = "Confirm and execute a prepared payment. Cards must be unlocked with your PIN. CVV is retrieved from secure storage.";
10
+ export declare const parameters: z.ZodObject<{
11
+ transaction_id: z.ZodString;
12
+ confirm: z.ZodBoolean;
13
+ }, "strip", z.ZodTypeAny, {
14
+ confirm: boolean;
15
+ transaction_id: string;
16
+ }, {
17
+ confirm: boolean;
18
+ transaction_id: string;
19
+ }>;
20
+ export declare function execute(args: z.infer<typeof parameters>): Promise<{
21
+ success: boolean;
22
+ error: string;
23
+ status?: undefined;
24
+ transaction_id?: undefined;
25
+ message?: undefined;
26
+ summary?: undefined;
27
+ note?: undefined;
28
+ next_steps?: undefined;
29
+ } | {
30
+ success: boolean;
31
+ status: string;
32
+ transaction_id: string;
33
+ message: string;
34
+ summary: {
35
+ card: string;
36
+ amount: string;
37
+ type: "flight" | "train" | "hotel" | "general";
38
+ description: string;
39
+ provider: string;
40
+ };
41
+ note: string;
42
+ next_steps: string[];
43
+ error?: undefined;
44
+ }>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Confirm and execute a prepared payment
3
+ *
4
+ * This is where the actual charge would happen.
5
+ * CVV is retrieved from encrypted storage (requires PIN unlock).
6
+ */
7
+ import { z } from "zod";
8
+ import { getCard, getCardCvv, getTransactions, updateTransaction, updateCardUsage } from "../lib/cards";
9
+ import { isUnlocked } from "../lib/pin-manager";
10
+ export const name = "confirm_payment";
11
+ export const description = "Confirm and execute a prepared payment. Cards must be unlocked with your PIN. CVV is retrieved from secure storage.";
12
+ export const parameters = z.object({
13
+ transaction_id: z.string().describe("ID of the pending transaction to confirm"),
14
+ confirm: z.boolean().describe("Must be true to confirm you want to proceed with the charge"),
15
+ });
16
+ export async function execute(args) {
17
+ if (!args.confirm) {
18
+ return {
19
+ success: false,
20
+ error: "You must set confirm=true to proceed with the payment",
21
+ };
22
+ }
23
+ // Check cards are unlocked
24
+ if (!isUnlocked()) {
25
+ return {
26
+ success: false,
27
+ error: "Cards are locked. Use unlock_cards with your PIN first.",
28
+ };
29
+ }
30
+ // Find the pending transaction
31
+ const transactions = await getTransactions(100);
32
+ const tx = transactions.find((t) => t.id === args.transaction_id);
33
+ if (!tx) {
34
+ return {
35
+ success: false,
36
+ error: "Transaction not found",
37
+ };
38
+ }
39
+ if (tx.status !== "pending") {
40
+ return {
41
+ success: false,
42
+ error: `Transaction is already ${tx.status}`,
43
+ };
44
+ }
45
+ // Get the card
46
+ const card = await getCard(tx.cardId);
47
+ if (!card) {
48
+ return {
49
+ success: false,
50
+ error: "Card no longer exists",
51
+ };
52
+ }
53
+ // Get CVV from encrypted storage
54
+ const cvv = await getCardCvv(tx.cardId);
55
+ if (!cvv) {
56
+ return {
57
+ success: false,
58
+ error: "Could not retrieve CVV. Make sure cards are unlocked.",
59
+ };
60
+ }
61
+ // Here we would integrate with actual payment providers
62
+ // CVV is available in `cvv` variable for the API call
63
+ // For now, we mark as confirmed and return what would be needed
64
+ await updateTransaction(tx.id, {
65
+ status: "confirmed",
66
+ confirmedAt: new Date().toISOString(),
67
+ });
68
+ await updateCardUsage(card.id);
69
+ return {
70
+ success: true,
71
+ status: "confirmed",
72
+ transaction_id: tx.id,
73
+ message: `Payment of ${tx.amount} ${tx.currency} confirmed`,
74
+ summary: {
75
+ card: `${card.nickname} (****${card.lastFourDigits})`,
76
+ amount: `${tx.amount} ${tx.currency}`,
77
+ type: tx.type,
78
+ description: tx.description,
79
+ provider: tx.provider,
80
+ },
81
+ // In production, this would return actual booking reference
82
+ note: "Integration with payment provider needed. Transaction marked as confirmed.",
83
+ next_steps: [
84
+ "Integrate with Stripe/payment processor for actual charge",
85
+ "Integrate with booking APIs (Amadeus, Trainline, etc.) for reservations",
86
+ ],
87
+ };
88
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Get consolidated view of all balances
3
+ */
4
+ import { z } from "zod";
5
+ export declare const name = "get_total_balance";
6
+ export declare const description = "Get a consolidated view of all financial accounts: cards and crypto wallets. Shows individual and total balances.";
7
+ export declare const parameters: z.ZodObject<{
8
+ include_disabled: z.ZodOptional<z.ZodBoolean>;
9
+ crypto_only: z.ZodOptional<z.ZodBoolean>;
10
+ cards_only: z.ZodOptional<z.ZodBoolean>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ include_disabled?: boolean | undefined;
13
+ crypto_only?: boolean | undefined;
14
+ cards_only?: boolean | undefined;
15
+ }, {
16
+ include_disabled?: boolean | undefined;
17
+ crypto_only?: boolean | undefined;
18
+ cards_only?: boolean | undefined;
19
+ }>;
20
+ export declare function execute(args: z.infer<typeof parameters>): Promise<{
21
+ success: boolean;
22
+ summary: {
23
+ totalAccounts: number;
24
+ cards: number;
25
+ wallets: number;
26
+ errors: number;
27
+ totalCryptoUsd: string | null;
28
+ note: string | undefined;
29
+ };
30
+ accounts: {
31
+ error?: string | undefined;
32
+ id: string;
33
+ type: "wallet" | "card";
34
+ name: string;
35
+ chain: string | undefined;
36
+ balance: string;
37
+ currency: string | undefined;
38
+ usdValue: string | null;
39
+ status: "error" | "active" | "disabled";
40
+ }[];
41
+ }>;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Get consolidated view of all balances
3
+ */
4
+ import { z } from "zod";
5
+ import { getCardsSafe } from "../lib/cards";
6
+ import { getWalletsSafe } from "../lib/wallets";
7
+ import { getWalletBalance, getUsdPrice } from "../lib/blockchain";
8
+ export const name = "get_total_balance";
9
+ export const description = "Get a consolidated view of all financial accounts: cards and crypto wallets. Shows individual and total balances.";
10
+ export const parameters = z.object({
11
+ include_disabled: z.boolean().optional().describe("Include disabled accounts (default: false)"),
12
+ crypto_only: z.boolean().optional().describe("Only show crypto wallets"),
13
+ cards_only: z.boolean().optional().describe("Only show payment cards"),
14
+ });
15
+ export async function execute(args) {
16
+ const includeDisabled = args.include_disabled ?? false;
17
+ const items = [];
18
+ let totalUsdValue = 0;
19
+ // Get cards (if not crypto_only)
20
+ if (!args.crypto_only) {
21
+ const cards = await getCardsSafe();
22
+ const filteredCards = includeDisabled ? cards : cards.filter(c => c.enabled);
23
+ for (const card of filteredCards) {
24
+ items.push({
25
+ id: card.id,
26
+ type: "card",
27
+ name: `${card.nickname} (****${card.lastFourDigits})`,
28
+ currency: card.limits?.currency || "EUR",
29
+ balance: "N/A", // Requires bank integration
30
+ status: card.enabled ? "active" : "disabled",
31
+ });
32
+ }
33
+ }
34
+ // Get wallets (if not cards_only)
35
+ if (!args.cards_only) {
36
+ const wallets = await getWalletsSafe();
37
+ const filteredWallets = includeDisabled ? wallets : wallets.filter(w => w.enabled);
38
+ // Fetch balances in parallel
39
+ const balancePromises = filteredWallets.map(async (wallet) => {
40
+ try {
41
+ const balance = await getWalletBalance(wallet.address, wallet.chain);
42
+ const price = await getUsdPrice(balance.nativeCurrency);
43
+ const usdValue = price ? parseFloat(balance.nativeBalanceFormatted) * price : undefined;
44
+ if (usdValue) {
45
+ totalUsdValue += usdValue;
46
+ }
47
+ return {
48
+ id: wallet.id,
49
+ type: "wallet",
50
+ name: wallet.nickname,
51
+ chain: wallet.chain,
52
+ balance: balance.nativeBalanceFormatted,
53
+ currency: balance.nativeCurrency,
54
+ usdValue,
55
+ status: wallet.enabled ? "active" : "disabled",
56
+ };
57
+ }
58
+ catch (err) {
59
+ return {
60
+ id: wallet.id,
61
+ type: "wallet",
62
+ name: wallet.nickname,
63
+ chain: wallet.chain,
64
+ status: "error",
65
+ error: err instanceof Error ? err.message : "Failed to fetch balance",
66
+ };
67
+ }
68
+ });
69
+ const walletResults = await Promise.all(balancePromises);
70
+ items.push(...walletResults);
71
+ }
72
+ // Separate by type for summary
73
+ const cardItems = items.filter(i => i.type === "card");
74
+ const walletItems = items.filter(i => i.type === "wallet");
75
+ const errorItems = items.filter(i => i.status === "error");
76
+ return {
77
+ success: true,
78
+ summary: {
79
+ totalAccounts: items.length,
80
+ cards: cardItems.length,
81
+ wallets: walletItems.length,
82
+ errors: errorItems.length,
83
+ totalCryptoUsd: totalUsdValue > 0 ? `$${totalUsdValue.toFixed(2)}` : null,
84
+ note: cardItems.length > 0 ? "Card balances require bank integration (Plaid/Tink)" : undefined,
85
+ },
86
+ accounts: items.map(item => ({
87
+ id: item.id,
88
+ type: item.type,
89
+ name: item.name,
90
+ chain: item.chain,
91
+ balance: item.balance || "N/A",
92
+ currency: item.currency,
93
+ usdValue: item.usdValue ? `$${item.usdValue.toFixed(2)}` : null,
94
+ status: item.status,
95
+ ...(item.error && { error: item.error }),
96
+ })),
97
+ };
98
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Get transaction history
3
+ */
4
+ import { z } from "zod";
5
+ export declare const name = "get_transactions";
6
+ export declare const description = "Get payment transaction history. Shows all bookings and payments made through the system.";
7
+ export declare const parameters: z.ZodObject<{
8
+ limit: z.ZodOptional<z.ZodNumber>;
9
+ status: z.ZodOptional<z.ZodEnum<["pending", "confirmed", "completed", "failed", "refunded"]>>;
10
+ type: z.ZodOptional<z.ZodEnum<["flight", "train", "hotel", "other"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ type?: "other" | "flight" | "train" | "hotel" | undefined;
13
+ status?: "pending" | "confirmed" | "completed" | "failed" | "refunded" | undefined;
14
+ limit?: number | undefined;
15
+ }, {
16
+ type?: "other" | "flight" | "train" | "hotel" | undefined;
17
+ status?: "pending" | "confirmed" | "completed" | "failed" | "refunded" | undefined;
18
+ limit?: number | undefined;
19
+ }>;
20
+ export declare function execute(args: z.infer<typeof parameters>): Promise<{
21
+ success: boolean;
22
+ transactions: never[];
23
+ message: string;
24
+ count?: undefined;
25
+ } | {
26
+ success: boolean;
27
+ count: number;
28
+ transactions: {
29
+ id: string;
30
+ type: "flight" | "train" | "hotel" | "general";
31
+ amount: string;
32
+ description: string;
33
+ provider: string;
34
+ status: "pending" | "confirmed" | "completed" | "failed" | "refunded";
35
+ reference: string;
36
+ date: string;
37
+ }[];
38
+ message?: undefined;
39
+ }>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Get transaction history
3
+ */
4
+ import { z } from "zod";
5
+ import { getTransactions } from "../lib/cards";
6
+ export const name = "get_transactions";
7
+ export const description = "Get payment transaction history. Shows all bookings and payments made through the system.";
8
+ export const parameters = z.object({
9
+ limit: z.number().optional().describe("Number of transactions to return (default: 20)"),
10
+ status: z.enum(["pending", "confirmed", "completed", "failed", "refunded"]).optional()
11
+ .describe("Filter by transaction status"),
12
+ type: z.enum(["flight", "train", "hotel", "other"]).optional()
13
+ .describe("Filter by transaction type"),
14
+ });
15
+ export async function execute(args) {
16
+ let transactions = await getTransactions(args.limit ?? 20);
17
+ if (args.status) {
18
+ transactions = transactions.filter((t) => t.status === args.status);
19
+ }
20
+ if (args.type) {
21
+ transactions = transactions.filter((t) => t.type === args.type);
22
+ }
23
+ if (transactions.length === 0) {
24
+ return { success: true, transactions: [], message: "No transactions found" };
25
+ }
26
+ return {
27
+ success: true,
28
+ count: transactions.length,
29
+ transactions: transactions.map((t) => ({
30
+ id: t.id,
31
+ type: t.type,
32
+ amount: `${t.amount} ${t.currency}`,
33
+ description: t.description,
34
+ provider: t.provider,
35
+ status: t.status,
36
+ reference: t.reference ?? "N/A",
37
+ date: t.createdAt,
38
+ })),
39
+ };
40
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Get wallet balance via blockchain API
3
+ */
4
+ import { z } from "zod";
5
+ import { type Chain } from "../lib/wallets";
6
+ export declare const name = "get_wallet_balance";
7
+ export declare const description = "Get the current balance of a crypto wallet. Fetches live data from the blockchain.";
8
+ export declare const parameters: z.ZodObject<{
9
+ wallet_id: z.ZodOptional<z.ZodString>;
10
+ address: z.ZodOptional<z.ZodString>;
11
+ chain: z.ZodOptional<z.ZodEnum<["ethereum", "polygon", "arbitrum", "optimism", "base", "avalanche", "bsc", "bitcoin", "solana", "starknet"]>>;
12
+ include_usd: z.ZodOptional<z.ZodBoolean>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ address?: string | undefined;
15
+ chain?: "ethereum" | "polygon" | "arbitrum" | "optimism" | "base" | "avalanche" | "bsc" | "bitcoin" | "solana" | "starknet" | undefined;
16
+ wallet_id?: string | undefined;
17
+ include_usd?: boolean | undefined;
18
+ }, {
19
+ address?: string | undefined;
20
+ chain?: "ethereum" | "polygon" | "arbitrum" | "optimism" | "base" | "avalanche" | "bsc" | "bitcoin" | "solana" | "starknet" | undefined;
21
+ wallet_id?: string | undefined;
22
+ include_usd?: boolean | undefined;
23
+ }>;
24
+ export declare function execute(args: z.infer<typeof parameters>): Promise<{
25
+ success: boolean;
26
+ error: string;
27
+ wallet?: undefined;
28
+ balance?: undefined;
29
+ } | {
30
+ success: boolean;
31
+ wallet: {
32
+ address: string;
33
+ fullAddress: string;
34
+ chain: Chain;
35
+ };
36
+ balance: {
37
+ native: string;
38
+ currency: string;
39
+ raw: string;
40
+ usdValue: string | null;
41
+ };
42
+ error?: undefined;
43
+ }>;