sms-wallet-agent 1.0.0

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 (46) hide show
  1. package/README.md +162 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +34 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/handlers/sms.d.ts +7 -0
  7. package/dist/handlers/sms.d.ts.map +1 -0
  8. package/dist/handlers/sms.js +53 -0
  9. package/dist/handlers/sms.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +15 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/parser/intent.d.ts +5 -0
  15. package/dist/parser/intent.d.ts.map +1 -0
  16. package/dist/parser/intent.js +49 -0
  17. package/dist/parser/intent.js.map +1 -0
  18. package/dist/server.d.ts +7 -0
  19. package/dist/server.d.ts.map +1 -0
  20. package/dist/server.js +50 -0
  21. package/dist/server.js.map +1 -0
  22. package/dist/services/tracker.d.ts +17 -0
  23. package/dist/services/tracker.d.ts.map +1 -0
  24. package/dist/services/tracker.js +120 -0
  25. package/dist/services/tracker.js.map +1 -0
  26. package/dist/services/wallet.d.ts +21 -0
  27. package/dist/services/wallet.d.ts.map +1 -0
  28. package/dist/services/wallet.js +263 -0
  29. package/dist/services/wallet.js.map +1 -0
  30. package/dist/storage/index.d.ts +14 -0
  31. package/dist/storage/index.d.ts.map +1 -0
  32. package/dist/storage/index.js +103 -0
  33. package/dist/storage/index.js.map +1 -0
  34. package/dist/types/index.d.ts +93 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/index.js +19 -0
  37. package/dist/types/index.js.map +1 -0
  38. package/dist/utils/logger.d.ts +8 -0
  39. package/dist/utils/logger.d.ts.map +1 -0
  40. package/dist/utils/logger.js +15 -0
  41. package/dist/utils/logger.js.map +1 -0
  42. package/dist/utils/validation.d.ts +7 -0
  43. package/dist/utils/validation.d.ts.map +1 -0
  44. package/dist/utils/validation.js +36 -0
  45. package/dist/utils/validation.js.map +1 -0
  46. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # sms-wallet-agent
2
+
3
+ Interact with Solana blockchain wallets through SMS messages. Text a phone number and receive wallet information instantly — no crypto knowledge required.
4
+
5
+ ## How It Works
6
+
7
+ ```
8
+ SMS → Twilio → Express Webhook → Intent Parser → Wallet Service → SMS Response
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **balance** — Get SOL balance for any wallet
14
+ - **activity** — View recent transactions summarized for SMS
15
+ - **portfolio** — SOL balance + top SPL tokens
16
+ - **track** — Get notified when a wallet has activity
17
+ - **stop** — Stop tracking a wallet
18
+
19
+ Read-only. Never requests private keys, seed phrases, or passwords. Never signs or broadcasts transactions.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install -g sms-wallet-agent
25
+ ```
26
+
27
+ Or clone and install locally:
28
+
29
+ ```bash
30
+ git clone <repo-url>
31
+ cd sms-wallet-agent
32
+ npm install
33
+ npm run build
34
+ npm link
35
+ ```
36
+
37
+ ## Configuration
38
+
39
+ Copy the example env file and fill in your credentials:
40
+
41
+ ```bash
42
+ cp .env.example .env
43
+ ```
44
+
45
+ | Variable | Description |
46
+ |---|---|
47
+ | `PORT` | Server port (default: `3000`) |
48
+ | `SOLANA_RPC_URL` | Solana RPC endpoint |
49
+ | `TWILIO_ACCOUNT_SID` | Twilio account SID |
50
+ | `TWILIO_AUTH_TOKEN` | Twilio auth token |
51
+ | `TWILIO_PHONE_NUMBER` | Your Twilio phone number |
52
+
53
+ Data is stored in `~/.config/sms-wallet-agent/`:
54
+
55
+ - `config.json` — App configuration
56
+ - `tracked-wallets.json` — Phone-to-wallet tracking mappings
57
+ - `state.json` — Last-known wallet state for change detection
58
+
59
+ ## Run
60
+
61
+ ```bash
62
+ sms-wallet-agent start
63
+ ```
64
+
65
+ You should see:
66
+
67
+ ```
68
+ ✓ SMS server running on port 3000
69
+ ✓ Tracking active
70
+ ```
71
+
72
+ ## Twilio Setup
73
+
74
+ 1. Expose your local server with ngrok:
75
+
76
+ ```bash
77
+ ngrok http 3000
78
+ ```
79
+
80
+ 2. In the [Twilio Console](https://console.twilio.com/), go to your phone number settings.
81
+
82
+ 3. Set the webhook URL for incoming messages:
83
+
84
+ ```
85
+ https://YOUR_NGROK_URL/sms
86
+ ```
87
+
88
+ Method: `POST`
89
+
90
+ 4. Send a text to your Twilio number:
91
+
92
+ ```
93
+ balance 8xQeWvG816bUx9EPjZmqJ9jZmqJ9jZmqJ9jZmqJ9jZmq
94
+ ```
95
+
96
+ ## Commands
97
+
98
+ Text any of these to your Twilio number:
99
+
100
+ | Command | Example | Response |
101
+ |---|---|---|
102
+ | `help` | `help` | List of available commands |
103
+ | `balance` | `balance 8xQe...` | SOL balance |
104
+ | `activity` | `activity 8xQe...` | Recent activity summary + Solscan link |
105
+ | `portfolio` | `portfolio 8xQe...` | SOL + top tokens |
106
+ | `track` | `track 8xQe...` | Start activity notifications |
107
+ | `stop` | `stop 8xQe...` | Stop tracking |
108
+
109
+ ### Example Conversation
110
+
111
+ ```
112
+ You: balance 8xQeWvG816bUx9EP...
113
+ Agent: Balance:
114
+ 2.41 SOL
115
+
116
+ You: activity 8xQeWvG816bUx9EP...
117
+ Agent: Recent Activity:
118
+
119
+ • SOL received
120
+ • Swapped BONK -> SOL
121
+ • NFT Transfer
122
+
123
+ View:
124
+ https://solscan.io/account/8xQe...
125
+
126
+ You: track 8xQeWvG816bUx9EP...
127
+ Agent: Done.
128
+
129
+ I will notify you when this wallet has activity.
130
+
131
+ [Later, automatically:]
132
+ Agent: 🚨 Wallet Activity
133
+
134
+ Wallet:
135
+ 8xQe...EPjZ
136
+
137
+ Event:
138
+ NFT Sale
139
+
140
+ Amount:
141
+ 4.2 SOL
142
+ ```
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ npm install
148
+ npm run dev # Run with tsx (hot reload)
149
+ npm run build # Compile TypeScript
150
+ npm start # Run compiled build
151
+ ```
152
+
153
+ ## Security
154
+
155
+ - Read-only wallet queries only
156
+ - No private keys, seed phrases, or passwords ever requested
157
+ - No transaction signing or broadcasting
158
+ - All tracking data stored locally on your machine
159
+
160
+ ## License
161
+
162
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function buildCli(): Command;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,QAAQ,IAAI,OAAO,CA4BlC"}
package/dist/cli.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildCli = buildCli;
7
+ const commander_1 = require("commander");
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const server_1 = require("./server");
10
+ const storage_1 = require("./storage");
11
+ const logger_1 = require("./utils/logger");
12
+ function buildCli() {
13
+ const program = new commander_1.Command();
14
+ program
15
+ .name('sms-wallet-agent')
16
+ .description('Interact with Solana wallets through SMS')
17
+ .version('1.0.0');
18
+ program
19
+ .command('start')
20
+ .description('Start the SMS webhook server and wallet tracking engine')
21
+ .action(() => {
22
+ const spinner = (0, ora_1.default)('Starting SMS wallet agent...').start();
23
+ const config = (0, storage_1.loadConfig)();
24
+ const port = Number(process.env.PORT) || config.port;
25
+ const rpcUrl = process.env.SOLANA_RPC_URL || config.rpcUrl;
26
+ (0, storage_1.saveConfig)({ port, rpcUrl });
27
+ spinner.succeed('Configuration loaded');
28
+ logger_1.log.info(`Config directory: ${(0, storage_1.getConfigDir)()}`);
29
+ logger_1.log.info(`Solana RPC: ${rpcUrl}`);
30
+ (0, server_1.createServer)();
31
+ });
32
+ return program;
33
+ }
34
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;AAMA,4BA4BC;AAlCD,yCAAoC;AACpC,8CAAsB;AACtB,qCAAwC;AACxC,uCAAiE;AACjE,2CAAqC;AAErC,SAAgB,QAAQ;IACtB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,kBAAkB,CAAC;SACxB,WAAW,CAAC,0CAA0C,CAAC;SACvD,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,8BAA8B,CAAC,CAAC,KAAK,EAAE,CAAC;QAE5D,MAAM,MAAM,GAAG,IAAA,oBAAU,GAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;QACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC;QAE3D,IAAA,oBAAU,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7B,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACxC,YAAG,CAAC,IAAI,CAAC,qBAAqB,IAAA,sBAAY,GAAE,EAAE,CAAC,CAAC;QAChD,YAAG,CAAC,IAAI,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;QAElC,IAAA,qBAAY,GAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { WalletService } from '../services/wallet';
2
+ export declare class SmsHandler {
3
+ private walletService;
4
+ constructor(walletService: WalletService);
5
+ handle(body: string, from: string): Promise<string>;
6
+ }
7
+ //# sourceMappingURL=sms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sms.d.ts","sourceRoot":"","sources":["../../src/handlers/sms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASnD,qBAAa,UAAU;IACT,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAE1C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA+C1D"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SmsHandler = void 0;
4
+ const intent_1 = require("../parser/intent");
5
+ const storage_1 = require("../storage");
6
+ const logger_1 = require("../utils/logger");
7
+ const validation_1 = require("../utils/validation");
8
+ class SmsHandler {
9
+ walletService;
10
+ constructor(walletService) {
11
+ this.walletService = walletService;
12
+ }
13
+ async handle(body, from) {
14
+ const command = (0, intent_1.parseIntent)(body);
15
+ logger_1.log.info(`SMS from ${from}: ${body.slice(0, 50)}${body.length > 50 ? '...' : ''}`);
16
+ switch (command.type) {
17
+ case 'help':
18
+ return intent_1.HELP_TEXT;
19
+ case 'balance':
20
+ return this.walletService.getBalance(command.wallet);
21
+ case 'activity':
22
+ return this.walletService.getActivity(command.wallet);
23
+ case 'portfolio':
24
+ return this.walletService.getPortfolio(command.wallet);
25
+ case 'track': {
26
+ const error = this.walletService.validateWallet(command.wallet);
27
+ if (error)
28
+ return error;
29
+ (0, storage_1.addTrackedWallet)(from, command.wallet);
30
+ const latestSig = await this.walletService.getLatestSignature(command.wallet);
31
+ (0, storage_1.updateWalletState)(command.wallet, {
32
+ lastSignature: latestSig,
33
+ lastChecked: new Date().toISOString(),
34
+ });
35
+ logger_1.log.success(`Wallet added: ${(0, validation_1.truncateAddress)(command.wallet)} for ${from}`);
36
+ return 'Done.\n\nI will notify you when this wallet has activity.';
37
+ }
38
+ case 'stop': {
39
+ const removed = (0, storage_1.removeTrackedWallet)(from, command.wallet);
40
+ if (!removed) {
41
+ return 'This wallet is not being tracked.';
42
+ }
43
+ logger_1.log.success(`Tracking removed: ${(0, validation_1.truncateAddress)(command.wallet)} for ${from}`);
44
+ return 'Tracking removed.';
45
+ }
46
+ case 'unknown':
47
+ default:
48
+ return intent_1.UNKNOWN_TEXT;
49
+ }
50
+ }
51
+ }
52
+ exports.SmsHandler = SmsHandler;
53
+ //# sourceMappingURL=sms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sms.js","sourceRoot":"","sources":["../../src/handlers/sms.ts"],"names":[],"mappings":";;;AAAA,6CAAwE;AAExE,wCAIoB;AACpB,4CAAsC;AACtC,oDAAsD;AAEtD,MAAa,UAAU;IACD;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,IAAY;QACrC,MAAM,OAAO,GAAG,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;QAClC,YAAG,CAAC,IAAI,CAAC,YAAY,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEnF,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,MAAM;gBACT,OAAO,kBAAS,CAAC;YAEnB,KAAK,SAAS;gBACZ,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAEvD,KAAK,UAAU;gBACb,OAAO,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAExD,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAEzD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChE,IAAI,KAAK;oBAAE,OAAO,KAAK,CAAC;gBAExB,IAAA,0BAAgB,EAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAEvC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC9E,IAAA,2BAAiB,EAAC,OAAO,CAAC,MAAM,EAAE;oBAChC,aAAa,EAAE,SAAS;oBACxB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACtC,CAAC,CAAC;gBAEH,YAAG,CAAC,OAAO,CAAC,iBAAiB,IAAA,4BAAe,EAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;gBAC5E,OAAO,2DAA2D,CAAC;YACrE,CAAC;YAED,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,OAAO,GAAG,IAAA,6BAAmB,EAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,mCAAmC,CAAC;gBAC7C,CAAC;gBACD,YAAG,CAAC,OAAO,CAAC,qBAAqB,IAAA,4BAAe,EAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;gBAChF,OAAO,mBAAmB,CAAC;YAC7B,CAAC;YAED,KAAK,SAAS,CAAC;YACf;gBACE,OAAO,qBAAY,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAlDD,gCAkDC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ const cli_1 = require("./cli");
9
+ dotenv_1.default.config();
10
+ const program = (0, cli_1.buildCli)();
11
+ program.parse(process.argv);
12
+ if (!process.argv.slice(2).length) {
13
+ program.outputHelp();
14
+ }
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAEA,oDAA4B;AAC5B,+BAAiC;AAEjC,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,OAAO,GAAG,IAAA,cAAQ,GAAE,CAAC;AAC3B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Command } from '../types';
2
+ export declare function parseIntent(body: string): Command;
3
+ export declare const HELP_TEXT = "Commands:\n\nbalance <wallet>\nactivity <wallet>\nportfolio <wallet>\ntrack <wallet>\nstop <wallet>";
4
+ export declare const UNKNOWN_TEXT = "Unknown command. Text \"help\" for available commands.";
5
+ //# sourceMappingURL=intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../src/parser/intent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAInC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAuCjD;AAED,eAAO,MAAM,SAAS,wGAMR,CAAC;AAEf,eAAO,MAAM,YAAY,2DAAyD,CAAC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UNKNOWN_TEXT = exports.HELP_TEXT = void 0;
4
+ exports.parseIntent = parseIntent;
5
+ const COMMANDS = ['help', 'balance', 'activity', 'portfolio', 'track', 'stop'];
6
+ function parseIntent(body) {
7
+ const trimmed = body.trim();
8
+ if (!trimmed) {
9
+ return { type: 'unknown', raw: '' };
10
+ }
11
+ const parts = trimmed.split(/\s+/);
12
+ const command = parts[0].toLowerCase();
13
+ if (!COMMANDS.includes(command)) {
14
+ if (command === '?' || command === 'commands') {
15
+ return { type: 'help' };
16
+ }
17
+ return { type: 'unknown', raw: trimmed };
18
+ }
19
+ if (command === 'help') {
20
+ return { type: 'help' };
21
+ }
22
+ const wallet = parts.slice(1).join(' ').trim();
23
+ if (!wallet) {
24
+ return { type: 'unknown', raw: trimmed };
25
+ }
26
+ switch (command) {
27
+ case 'balance':
28
+ return { type: 'balance', wallet };
29
+ case 'activity':
30
+ return { type: 'activity', wallet };
31
+ case 'portfolio':
32
+ return { type: 'portfolio', wallet };
33
+ case 'track':
34
+ return { type: 'track', wallet };
35
+ case 'stop':
36
+ return { type: 'stop', wallet };
37
+ default:
38
+ return { type: 'unknown', raw: trimmed };
39
+ }
40
+ }
41
+ exports.HELP_TEXT = `Commands:
42
+
43
+ balance <wallet>
44
+ activity <wallet>
45
+ portfolio <wallet>
46
+ track <wallet>
47
+ stop <wallet>`;
48
+ exports.UNKNOWN_TEXT = `Unknown command. Text "help" for available commands.`;
49
+ //# sourceMappingURL=intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.js","sourceRoot":"","sources":["../../src/parser/intent.ts"],"names":[],"mappings":";;;AAIA,kCAuCC;AAzCD,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AAExF,SAAgB,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAoC,CAAC,EAAE,CAAC;QAC7D,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC3C,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACrC,KAAK,UAAU;YACb,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACtC,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QACvC,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAClC;YACE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC7C,CAAC;AACH,CAAC;AAEY,QAAA,SAAS,GAAG;;;;;;cAMX,CAAC;AAEF,QAAA,YAAY,GAAG,sDAAsD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import express from 'express';
2
+ import { TrackingEngine } from './services/tracker';
3
+ export declare function createServer(): {
4
+ app: express.Application;
5
+ tracker: TrackingEngine;
6
+ };
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AAIrD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMpD,wBAAgB,YAAY,IAAI;IAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;CACzB,CA0CA"}
package/dist/server.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createServer = createServer;
7
+ const express_1 = __importDefault(require("express"));
8
+ const twilio_1 = __importDefault(require("twilio"));
9
+ const sms_1 = require("./handlers/sms");
10
+ const wallet_1 = require("./services/wallet");
11
+ const tracker_1 = require("./services/tracker");
12
+ const storage_1 = require("./storage");
13
+ const logger_1 = require("./utils/logger");
14
+ const MessagingResponse = twilio_1.default.twiml.MessagingResponse;
15
+ function createServer() {
16
+ const config = (0, storage_1.loadConfig)();
17
+ const port = Number(process.env.PORT) || config.port;
18
+ const rpcUrl = process.env.SOLANA_RPC_URL || config.rpcUrl;
19
+ const walletService = new wallet_1.WalletService(rpcUrl);
20
+ const smsHandler = new sms_1.SmsHandler(walletService);
21
+ const tracker = new tracker_1.TrackingEngine(walletService);
22
+ const app = (0, express_1.default)();
23
+ app.use(express_1.default.urlencoded({ extended: false }));
24
+ app.use(express_1.default.json());
25
+ app.get('/health', (_req, res) => {
26
+ res.json({ status: 'ok', service: 'sms-wallet-agent' });
27
+ });
28
+ app.post('/sms', async (req, res) => {
29
+ const body = req.body.Body ?? '';
30
+ const from = req.body.From ?? '';
31
+ const twiml = new MessagingResponse();
32
+ try {
33
+ const reply = await smsHandler.handle(body, from);
34
+ twiml.message(reply);
35
+ }
36
+ catch (err) {
37
+ logger_1.log.error(`SMS handler error: ${String(err)}`);
38
+ twiml.message('Something went wrong. Please try again later.');
39
+ }
40
+ res.type('text/xml');
41
+ res.send(twiml.toString());
42
+ });
43
+ app.listen(port, () => {
44
+ logger_1.log.success(`SMS server running on port ${port}`);
45
+ logger_1.log.info(`Webhook: POST http://localhost:${port}/sms`);
46
+ tracker.start();
47
+ });
48
+ return { app, tracker };
49
+ }
50
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;AAUA,oCA6CC;AAvDD,sDAAqD;AACrD,oDAA4B;AAC5B,wCAA4C;AAC5C,8CAAkD;AAClD,gDAAoD;AACpD,uCAAuC;AACvC,2CAAqC;AAErC,MAAM,iBAAiB,GAAG,gBAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC;AAEzD,SAAgB,YAAY;IAI1B,MAAM,MAAM,GAAG,IAAA,oBAAU,GAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC;IAE3D,MAAM,aAAa,GAAG,IAAI,sBAAa,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,IAAI,gBAAU,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,wBAAc,CAAC,aAAa,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QAClD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACrD,MAAM,IAAI,GAAW,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACzC,MAAM,IAAI,GAAW,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAEzC,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAClD,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAG,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/C,KAAK,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;QACjE,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACpB,YAAG,CAAC,OAAO,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC;QAClD,YAAG,CAAC,IAAI,CAAC,kCAAkC,IAAI,MAAM,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { WalletService } from './wallet';
2
+ export declare class TrackingEngine {
3
+ private walletService;
4
+ private twilioClient;
5
+ private fromNumber;
6
+ private intervalId;
7
+ private running;
8
+ constructor(walletService: WalletService);
9
+ private initTwilio;
10
+ start(): void;
11
+ stop(): void;
12
+ private poll;
13
+ private notifySubscribers;
14
+ private formatNotification;
15
+ private sendSms;
16
+ }
17
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/services/tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAazC,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,OAAO,CAAS;gBAEZ,aAAa,EAAE,aAAa;IAKxC,OAAO,CAAC,UAAU;IAalB,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;YAQE,IAAI;YAuCJ,iBAAiB;IAU/B,OAAO,CAAC,kBAAkB;YAgBZ,OAAO;CAatB"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TrackingEngine = void 0;
7
+ const twilio_1 = __importDefault(require("twilio"));
8
+ const storage_1 = require("../storage");
9
+ const logger_1 = require("../utils/logger");
10
+ const validation_1 = require("../utils/validation");
11
+ const POLL_INTERVAL_MS = 60_000;
12
+ class TrackingEngine {
13
+ walletService;
14
+ twilioClient = null;
15
+ fromNumber = null;
16
+ intervalId = null;
17
+ running = false;
18
+ constructor(walletService) {
19
+ this.walletService = walletService;
20
+ this.initTwilio();
21
+ }
22
+ initTwilio() {
23
+ const accountSid = process.env.TWILIO_ACCOUNT_SID;
24
+ const authToken = process.env.TWILIO_AUTH_TOKEN;
25
+ const phoneNumber = process.env.TWILIO_PHONE_NUMBER;
26
+ if (accountSid && authToken && phoneNumber) {
27
+ this.twilioClient = (0, twilio_1.default)(accountSid, authToken);
28
+ this.fromNumber = phoneNumber;
29
+ }
30
+ else {
31
+ logger_1.log.warn('Twilio credentials missing — tracking notifications disabled');
32
+ }
33
+ }
34
+ start() {
35
+ if (this.running)
36
+ return;
37
+ this.running = true;
38
+ logger_1.log.success('Tracking active');
39
+ void this.poll();
40
+ this.intervalId = setInterval(() => void this.poll(), POLL_INTERVAL_MS);
41
+ }
42
+ stop() {
43
+ if (this.intervalId) {
44
+ clearInterval(this.intervalId);
45
+ this.intervalId = null;
46
+ }
47
+ this.running = false;
48
+ }
49
+ async poll() {
50
+ const tracked = (0, storage_1.getAllTrackedWallets)();
51
+ if (tracked.length === 0)
52
+ return;
53
+ const state = (0, storage_1.loadState)();
54
+ const walletsSeen = new Set();
55
+ for (const entry of tracked) {
56
+ walletsSeen.add(entry.wallet);
57
+ try {
58
+ const lastSig = state[entry.wallet]?.lastSignature;
59
+ const events = await this.walletService.detectNewEvents(entry.wallet, lastSig);
60
+ if (events.length > 0) {
61
+ for (const event of events) {
62
+ await this.notifySubscribers(entry.wallet, event);
63
+ }
64
+ }
65
+ const latestSig = await this.walletService.getLatestSignature(entry.wallet);
66
+ (0, storage_1.updateWalletState)(entry.wallet, {
67
+ lastSignature: latestSig,
68
+ lastChecked: new Date().toISOString(),
69
+ });
70
+ }
71
+ catch (err) {
72
+ logger_1.log.error(`Failed to check wallet ${(0, validation_1.truncateAddress)(entry.wallet)}: ${String(err)}`);
73
+ }
74
+ }
75
+ const updatedState = (0, storage_1.loadState)();
76
+ for (const wallet of Object.keys(updatedState)) {
77
+ if (!walletsSeen.has(wallet)) {
78
+ delete updatedState[wallet];
79
+ }
80
+ }
81
+ (0, storage_1.saveState)(updatedState);
82
+ }
83
+ async notifySubscribers(wallet, event) {
84
+ const subscribers = (0, storage_1.getAllTrackedWallets)().filter((w) => w.wallet === wallet);
85
+ const message = this.formatNotification(event);
86
+ for (const sub of subscribers) {
87
+ await this.sendSms(sub.phone, message);
88
+ logger_1.log.info(`Notified ${sub.phone} about ${event.event} on ${(0, validation_1.truncateAddress)(wallet)}`);
89
+ }
90
+ }
91
+ formatNotification(event) {
92
+ const lines = [
93
+ '🚨 Wallet Activity',
94
+ '',
95
+ `Wallet:\n${(0, validation_1.truncateAddress)(event.wallet, 6)}`,
96
+ '',
97
+ `Event:\n${event.event}`,
98
+ ];
99
+ if (event.amount) {
100
+ lines.push('', `Amount:\n${event.amount}`);
101
+ }
102
+ return lines.join('\n');
103
+ }
104
+ async sendSms(to, body) {
105
+ if (!this.twilioClient || !this.fromNumber)
106
+ return;
107
+ try {
108
+ await this.twilioClient.messages.create({
109
+ body,
110
+ from: this.fromNumber,
111
+ to,
112
+ });
113
+ }
114
+ catch (err) {
115
+ logger_1.log.error(`Failed to send SMS to ${to}: ${String(err)}`);
116
+ }
117
+ }
118
+ }
119
+ exports.TrackingEngine = TrackingEngine;
120
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/services/tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { DetectedEvent, WalletActivity, WalletPortfolio } from '../types';
2
+ export declare class WalletService {
3
+ private connection;
4
+ constructor(rpcUrl: string);
5
+ validateWallet(address: string): string | null;
6
+ getBalance(wallet: string): Promise<string>;
7
+ getActivity(wallet: string): Promise<string>;
8
+ getPortfolio(wallet: string): Promise<string>;
9
+ fetchRecentActivity(wallet: string, limit?: number): Promise<WalletActivity>;
10
+ fetchPortfolio(wallet: string): Promise<WalletPortfolio>;
11
+ detectNewEvents(wallet: string, lastSignature?: string): Promise<DetectedEvent[]>;
12
+ getLatestSignature(wallet: string): Promise<string | undefined>;
13
+ private summarizeSignature;
14
+ private detectEventFromSignature;
15
+ private classifyTransaction;
16
+ private detectTokenTransfer;
17
+ private extractSwapDetail;
18
+ private fetchEstimatedValue;
19
+ private fetchSolPrice;
20
+ }
21
+ //# sourceMappingURL=wallet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/services/wallet.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,aAAa,EAEb,cAAc,EACd,eAAe,EAChB,MAAM,UAAU,CAAC;AAWlB,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAa;gBAEnB,MAAM,EAAE,MAAM;IAI1B,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOxC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS3C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa5C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8B7C,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,cAAc,CAAC;IAavE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAmCxD,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,EAAE,CAAC;IAiB3B,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAOjD,kBAAkB;YAQlB,wBAAwB;IAqBtC,OAAO,CAAC,mBAAmB;IAqD3B,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,iBAAiB;YAuBX,mBAAmB;YAgBnB,aAAa;CAW5B"}