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,31 @@
1
+ /**
2
+ * Lock cards (clear PIN from memory)
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { lock, getStatus } from "../lib/pin-manager";
7
+
8
+ export const name = "lock_cards";
9
+
10
+ export const description = "Lock your cards immediately. Clears the PIN from memory. You'll need to unlock again to make payments.";
11
+
12
+ export const parameters = z.object({});
13
+
14
+ export async function execute(_args: z.infer<typeof parameters>) {
15
+ const status = getStatus();
16
+
17
+ if (!status.unlocked) {
18
+ return {
19
+ success: true,
20
+ message: "Cards are already locked",
21
+ };
22
+ }
23
+
24
+ lock();
25
+
26
+ return {
27
+ success: true,
28
+ message: "Cards locked. PIN cleared from memory.",
29
+ note: "Use unlock_cards to unlock again when needed.",
30
+ };
31
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Prepare a crypto transaction for confirmation
3
+ *
4
+ * Creates a pending transaction that must be signed and broadcast.
5
+ * For hardware wallets, signing happens on the device.
6
+ */
7
+
8
+ import { z } from "zod";
9
+ import { randomUUID } from "crypto";
10
+ import { getWallet, logCryptoTransaction, CHAIN_CONFIG } from "../lib/wallets";
11
+ import type { CryptoTransaction } from "../lib/wallets";
12
+
13
+ export const name = "prepare_crypto_tx";
14
+
15
+ export const description = `Prepare a crypto transaction for signing. This creates a PENDING transaction that must be confirmed with sign_crypto_tx before broadcast.
16
+
17
+ Supports:
18
+ - Native token transfers (ETH, MATIC, etc.)
19
+ - ERC20/token transfers
20
+ - Contract interactions`;
21
+
22
+ export const parameters = z.object({
23
+ wallet_id: z.string().describe("ID of the wallet to send from"),
24
+ to: z.string().describe("Recipient address"),
25
+ // Native or token
26
+ amount: z.string().optional().describe("Amount to send (in human readable units, e.g., '0.5' for 0.5 ETH)"),
27
+ token_address: z.string().optional().describe("Token contract address (omit for native currency)"),
28
+ token_symbol: z.string().optional().describe("Token symbol (e.g., 'USDC')"),
29
+ // Or raw contract call
30
+ data: z.string().optional().describe("Raw transaction data (hex) for contract calls"),
31
+ // Gas settings
32
+ gas_limit: z.string().optional().describe("Gas limit (default: estimated)"),
33
+ max_fee_per_gas: z.string().optional().describe("Max fee per gas in gwei"),
34
+ max_priority_fee: z.string().optional().describe("Max priority fee in gwei"),
35
+ // Description
36
+ description: z.string().describe("What this transaction is for"),
37
+ });
38
+
39
+ export async function execute(args: z.infer<typeof parameters>) {
40
+ // Get wallet
41
+ const wallet = await getWallet(args.wallet_id);
42
+
43
+ if (!wallet) {
44
+ return { success: false, error: "Wallet not found" };
45
+ }
46
+
47
+ if (!wallet.enabled) {
48
+ return { success: false, error: "Wallet is disabled" };
49
+ }
50
+
51
+ if (!wallet.allowedOperations.includes("send")) {
52
+ return { success: false, error: "This wallet is not allowed to send transactions" };
53
+ }
54
+
55
+ // Validate recipient address (basic check)
56
+ const chainConfig = CHAIN_CONFIG[wallet.chain];
57
+
58
+ // Determine transaction type
59
+ let txType: CryptoTransaction["type"] = "send";
60
+ if (args.data) {
61
+ txType = "contract";
62
+ }
63
+
64
+ // Create pending transaction
65
+ const txId = randomUUID();
66
+ const transaction: CryptoTransaction = {
67
+ id: txId,
68
+ walletId: wallet.id,
69
+ chain: wallet.chain,
70
+ type: txType,
71
+ status: "pending",
72
+ from: wallet.address,
73
+ to: args.to,
74
+ value: args.amount,
75
+ tokenAddress: args.token_address,
76
+ tokenSymbol: args.token_symbol,
77
+ gasLimit: args.gas_limit,
78
+ maxFeePerGas: args.max_fee_per_gas,
79
+ maxPriorityFeePerGas: args.max_priority_fee,
80
+ description: args.description,
81
+ createdAt: new Date().toISOString(),
82
+ };
83
+
84
+ await logCryptoTransaction(transaction);
85
+
86
+ const amountDisplay = args.token_symbol
87
+ ? `${args.amount} ${args.token_symbol}`
88
+ : `${args.amount} ${chainConfig?.nativeCurrency ?? "tokens"}`;
89
+
90
+ return {
91
+ success: true,
92
+ transaction_id: txId,
93
+ status: "pending",
94
+ summary: {
95
+ from: `${wallet.nickname} (${wallet.address.slice(0, 10)}...)`,
96
+ to: `${args.to.slice(0, 10)}...${args.to.slice(-8)}`,
97
+ amount: amountDisplay,
98
+ chain: chainConfig?.name ?? wallet.chain,
99
+ type: txType,
100
+ description: args.description,
101
+ },
102
+ wallet_type: wallet.type,
103
+ next_step: wallet.type === "hardware"
104
+ ? "Connect your hardware wallet and call sign_crypto_tx to sign on device"
105
+ : "Call sign_crypto_tx to sign and broadcast the transaction",
106
+ warning: "NO TRANSACTION has been broadcast yet. You must sign to proceed.",
107
+ };
108
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Prepare a payment for confirmation
3
+ *
4
+ * This creates a pending transaction that must be confirmed before execution.
5
+ * Security: User must explicitly confirm with CVV before any charge.
6
+ */
7
+
8
+ import { z } from "zod";
9
+ import { randomUUID } from "crypto";
10
+ import { getCard, logTransaction } from "../lib/cards";
11
+ import type { Transaction, CardUsage } from "../lib/cards";
12
+ import { isUnlocked, isPinConfigured } from "../lib/pin-manager";
13
+
14
+ export const name = "prepare_payment";
15
+
16
+ export const description = "Prepare a payment for a booking (flight, train, hotel, etc.). This creates a PENDING transaction that must be confirmed with confirm_payment before any charge is made.";
17
+
18
+ export const parameters = z.object({
19
+ card_id: z.string().describe("ID of the card to use"),
20
+ amount: z.number().describe("Amount to charge"),
21
+ currency: z.string().describe("Currency code (EUR, USD, etc.)"),
22
+ type: z.enum(["flight", "train", "hotel", "general"]).describe("Type of purchase"),
23
+ description: z.string().describe("What is being purchased (e.g., 'Paris-London Eurostar 15 Feb')"),
24
+ provider: z.string().describe("Booking provider (e.g., 'Trainline', 'Air France', 'Booking.com')"),
25
+ details: z.record(z.unknown()).optional().describe("Additional booking details"),
26
+ });
27
+
28
+ export async function execute(args: z.infer<typeof parameters>) {
29
+ // Check cards are unlocked
30
+ if (!isPinConfigured()) {
31
+ return {
32
+ success: false,
33
+ error: "Master PIN not configured. Use setup_pin first.",
34
+ };
35
+ }
36
+
37
+ if (!isUnlocked()) {
38
+ return {
39
+ success: false,
40
+ error: "Cards are locked. Use unlock_cards with your PIN first.",
41
+ };
42
+ }
43
+
44
+ // Verify card exists and is enabled
45
+ const card = await getCard(args.card_id);
46
+
47
+ if (!card) {
48
+ return {
49
+ success: false,
50
+ error: "Card not found",
51
+ };
52
+ }
53
+
54
+ if (!card.enabled) {
55
+ return {
56
+ success: false,
57
+ error: "Card is disabled",
58
+ };
59
+ }
60
+
61
+ // Check usage restrictions
62
+ if (!card.allowedUsage.includes("all") && !card.allowedUsage.includes(args.type)) {
63
+ return {
64
+ success: false,
65
+ error: `Card "${card.nickname}" is not allowed for ${args.type} purchases. Allowed: ${card.allowedUsage.join(", ")}`,
66
+ };
67
+ }
68
+
69
+ // Check limits
70
+ if (card.limits?.perTransaction && args.amount > card.limits.perTransaction) {
71
+ return {
72
+ success: false,
73
+ error: `Amount exceeds per-transaction limit of ${card.limits.perTransaction} ${card.limits.currency}`,
74
+ };
75
+ }
76
+
77
+ // Create pending transaction
78
+ const txId = randomUUID();
79
+ const transaction: Transaction = {
80
+ id: txId,
81
+ cardId: card.id,
82
+ type: args.type,
83
+ amount: args.amount,
84
+ currency: args.currency,
85
+ description: args.description,
86
+ provider: args.provider,
87
+ status: "pending",
88
+ createdAt: new Date().toISOString(),
89
+ details: args.details,
90
+ };
91
+
92
+ await logTransaction(transaction);
93
+
94
+ return {
95
+ success: true,
96
+ transaction_id: txId,
97
+ status: "pending",
98
+ summary: {
99
+ card: `${card.nickname} (****${card.lastFourDigits})`,
100
+ amount: `${args.amount} ${args.currency}`,
101
+ type: args.type,
102
+ description: args.description,
103
+ provider: args.provider,
104
+ },
105
+ next_step: "Call confirm_payment with this transaction_id and the card CVV to complete the payment",
106
+ warning: "NO CHARGE has been made yet. You must confirm to proceed.",
107
+ };
108
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Remove a payment card
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { removeCard, getCard } from "../lib/cards";
7
+
8
+ export const name = "remove_card";
9
+
10
+ export const description = "Remove a saved payment card. This action is irreversible.";
11
+
12
+ export const parameters = z.object({
13
+ card_id: z.string().describe("ID of the card to remove"),
14
+ confirm: z.boolean().describe("Must be true to confirm deletion"),
15
+ });
16
+
17
+ export async function execute(args: z.infer<typeof parameters>) {
18
+ if (!args.confirm) {
19
+ return {
20
+ success: false,
21
+ error: "You must set confirm=true to delete a card",
22
+ };
23
+ }
24
+
25
+ const card = await getCard(args.card_id);
26
+ if (!card) {
27
+ return {
28
+ success: false,
29
+ error: "Card not found",
30
+ };
31
+ }
32
+
33
+ const removed = await removeCard(args.card_id);
34
+
35
+ if (removed) {
36
+ return {
37
+ success: true,
38
+ message: `Card "${card.nickname}" (****${card.lastFourDigits}) has been removed`,
39
+ };
40
+ } else {
41
+ return {
42
+ success: false,
43
+ error: "Failed to remove card",
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Remove a crypto wallet
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { removeWallet, getWallet } from "../lib/wallets";
7
+
8
+ export const name = "remove_wallet";
9
+
10
+ export const description = "Remove a saved crypto wallet. This deletes the stored keys (if any). This action is irreversible.";
11
+
12
+ export const parameters = z.object({
13
+ wallet_id: z.string().describe("ID of the wallet to remove"),
14
+ confirm: z.boolean().describe("Must be true to confirm deletion"),
15
+ });
16
+
17
+ export async function execute(args: z.infer<typeof parameters>) {
18
+ if (!args.confirm) {
19
+ return {
20
+ success: false,
21
+ error: "You must set confirm=true to delete a wallet",
22
+ };
23
+ }
24
+
25
+ const wallet = await getWallet(args.wallet_id);
26
+ if (!wallet) {
27
+ return {
28
+ success: false,
29
+ error: "Wallet not found",
30
+ };
31
+ }
32
+
33
+ const removed = await removeWallet(args.wallet_id);
34
+
35
+ if (removed) {
36
+ return {
37
+ success: true,
38
+ message: `Wallet "${wallet.nickname}" (${wallet.address.slice(0, 10)}...) has been removed`,
39
+ warning: wallet.type === "hot" ? "Private key has been deleted" : undefined,
40
+ };
41
+ } else {
42
+ return {
43
+ success: false,
44
+ error: "Failed to remove wallet",
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Set up master PIN for card access
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { setupPin, isPinConfigured } from "../lib/pin-manager";
7
+
8
+ export const name = "setup_pin";
9
+
10
+ export const description = "Set up a master PIN (4-8 characters) for card access. This PIN encrypts your CVVs and must be entered to unlock cards for payments. Choose something you'll remember!";
11
+
12
+ export const parameters = z.object({
13
+ pin: z.string().describe("Your master PIN (4-8 characters). This will encrypt your CVVs."),
14
+ });
15
+
16
+ export async function execute(args: z.infer<typeof parameters>) {
17
+ if (isPinConfigured()) {
18
+ return {
19
+ success: false,
20
+ error: "PIN already configured. Use change_pin to modify it.",
21
+ };
22
+ }
23
+
24
+ const result = setupPin(args.pin);
25
+
26
+ if (result.success) {
27
+ return {
28
+ success: true,
29
+ message: "Master PIN configured! Cards are now unlocked.",
30
+ note: "Your PIN encrypts all CVVs. Without it, cards cannot be used.",
31
+ session_timeout: "30 minutes of inactivity will lock cards automatically",
32
+ };
33
+ } else {
34
+ return {
35
+ success: false,
36
+ error: result.error,
37
+ };
38
+ }
39
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Sign and broadcast a prepared crypto transaction
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { getWallet, getCryptoTransactions, updateCryptoTransaction, CHAIN_CONFIG } from "../lib/wallets";
7
+
8
+ export const name = "sign_crypto_tx";
9
+
10
+ export const description = `Sign and broadcast a prepared crypto transaction.
11
+
12
+ For hot wallets: signs with the stored private key.
13
+ For hardware wallets: requires the device to be connected (integration needed).
14
+ For watch-only: not allowed.`;
15
+
16
+ export const parameters = z.object({
17
+ transaction_id: z.string().describe("ID of the pending transaction to sign"),
18
+ confirm: z.boolean().describe("Must be true to confirm you want to sign and broadcast"),
19
+ });
20
+
21
+ export async function execute(args: z.infer<typeof parameters>) {
22
+ if (!args.confirm) {
23
+ return {
24
+ success: false,
25
+ error: "You must set confirm=true to sign and broadcast the transaction",
26
+ };
27
+ }
28
+
29
+ // Find the pending transaction
30
+ const transactions = await getCryptoTransactions(100);
31
+ const tx = transactions.find((t) => t.id === args.transaction_id);
32
+
33
+ if (!tx) {
34
+ return { success: false, error: "Transaction not found" };
35
+ }
36
+
37
+ if (tx.status !== "pending") {
38
+ return { success: false, error: `Transaction is already ${tx.status}` };
39
+ }
40
+
41
+ // Get the wallet
42
+ const wallet = await getWallet(tx.walletId);
43
+ if (!wallet) {
44
+ return { success: false, error: "Wallet no longer exists" };
45
+ }
46
+
47
+ if (wallet.type === "watch-only") {
48
+ return { success: false, error: "Watch-only wallets cannot sign transactions" };
49
+ }
50
+
51
+ const chainConfig = CHAIN_CONFIG[wallet.chain];
52
+
53
+ // Here we would:
54
+ // 1. For hot wallets: sign with ethers.js/viem using the private key
55
+ // 2. For hardware wallets: prompt for Ledger/Trezor connection
56
+ // 3. Broadcast to the network
57
+
58
+ // For now, mark as signed and return what would be needed
59
+ await updateCryptoTransaction(tx.id, {
60
+ status: "signed",
61
+ signedAt: new Date().toISOString(),
62
+ });
63
+
64
+ const amountDisplay = tx.tokenSymbol
65
+ ? `${tx.value} ${tx.tokenSymbol}`
66
+ : `${tx.value} ${chainConfig?.nativeCurrency ?? "tokens"}`;
67
+
68
+ return {
69
+ success: true,
70
+ status: "signed",
71
+ transaction_id: tx.id,
72
+ message: wallet.type === "hardware"
73
+ ? "Transaction prepared for hardware signing"
74
+ : "Transaction signed (ready for broadcast)",
75
+ summary: {
76
+ from: wallet.nickname,
77
+ to: tx.to,
78
+ amount: amountDisplay,
79
+ chain: chainConfig?.name ?? wallet.chain,
80
+ },
81
+ // In production, this would return the actual tx hash
82
+ note: "Integration with ethers.js/viem needed for actual signing and broadcast",
83
+ next_steps: [
84
+ "Integrate with ethers.js or viem for transaction signing",
85
+ "Add RPC endpoint configuration for each chain",
86
+ "For hardware wallets, integrate with @ledgerhq/hw-transport or similar",
87
+ ],
88
+ explorer: chainConfig?.explorerUrl,
89
+ };
90
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Unlock cards with master PIN
3
+ */
4
+
5
+ import { z } from "zod";
6
+ import { unlock, isPinConfigured, getStatus } from "../lib/pin-manager";
7
+
8
+ export const name = "unlock_cards";
9
+
10
+ export const description = "Unlock your cards by entering your master PIN. Required before making any payment. Cards stay unlocked for 30 minutes of activity.";
11
+
12
+ export const parameters = z.object({
13
+ pin: z.string().describe("Your master PIN"),
14
+ });
15
+
16
+ export async function execute(args: z.infer<typeof parameters>) {
17
+ if (!isPinConfigured()) {
18
+ return {
19
+ success: false,
20
+ error: "No PIN configured. Use setup_pin first.",
21
+ };
22
+ }
23
+
24
+ const status = getStatus();
25
+ if (status.unlocked) {
26
+ return {
27
+ success: true,
28
+ message: "Cards already unlocked",
29
+ remaining_minutes: status.remainingMinutes,
30
+ };
31
+ }
32
+
33
+ const result = unlock(args.pin);
34
+
35
+ if (result.success) {
36
+ return {
37
+ success: true,
38
+ message: "Cards unlocked! You can now make payments.",
39
+ session_expires_in: `${result.expiresIn} minutes`,
40
+ tip: "Cards will auto-lock after 30 minutes of inactivity",
41
+ };
42
+ } else {
43
+ return {
44
+ success: false,
45
+ error: result.error,
46
+ };
47
+ }
48
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "allowSyntheticDefaultImports": true,
7
+ "esModuleInterop": true,
8
+ "allowJs": true,
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "outDir": "./dist",
14
+ "rootDir": "./src",
15
+ "resolveJsonModule": true
16
+ },
17
+ "include": ["src/**/*"],
18
+ "exclude": ["node_modules", "dist"]
19
+ }