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.
- package/README.md +162 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +34 -0
- package/dist/cli.js.map +1 -0
- package/dist/handlers/sms.d.ts +7 -0
- package/dist/handlers/sms.d.ts.map +1 -0
- package/dist/handlers/sms.js +53 -0
- package/dist/handlers/sms.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/intent.d.ts +5 -0
- package/dist/parser/intent.d.ts.map +1 -0
- package/dist/parser/intent.js +49 -0
- package/dist/parser/intent.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +50 -0
- package/dist/server.js.map +1 -0
- package/dist/services/tracker.d.ts +17 -0
- package/dist/services/tracker.d.ts.map +1 -0
- package/dist/services/tracker.js +120 -0
- package/dist/services/tracker.js.map +1 -0
- package/dist/services/wallet.d.ts +21 -0
- package/dist/services/wallet.d.ts.map +1 -0
- package/dist/services/wallet.js +263 -0
- package/dist/services/wallet.js.map +1 -0
- package/dist/storage/index.d.ts +14 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +103 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/index.d.ts +93 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +15 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +7 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +36 -0
- package/dist/utils/validation.js.map +1 -0
- 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 @@
|
|
|
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
|
package/dist/cli.js.map
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/server.d.ts
ADDED
|
@@ -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"}
|