payment-skill 1.1.18 → 1.1.19
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 +3 -3
- package/SKILL.md +2 -2
- package/dashboard.html +20 -0
- package/data/config.json +81 -0
- package/data/transactions.json +436 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/config.js +65 -28
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/wise.js +29 -0
- package/dist/commands/wise.js.map +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +7 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +7 -1
- package/dist/core/transaction.js.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +55 -2
- package/dist/server/server.js.map +1 -1
- package/package.json +3 -3
- package/public/dashboard.js +39 -0
- package/src/cli.ts +1 -1
- package/src/commands/config.ts +71 -26
- package/src/commands/wise.ts +37 -0
- package/src/core/config.ts +9 -1
- package/src/core/transaction.ts +9 -1
- package/src/server/server.ts +21 -2
- package/verified-merchants.json +2 -2
package/src/commands/config.ts
CHANGED
|
@@ -14,8 +14,45 @@ export const configCommands = new Command('config')
|
|
|
14
14
|
configCommands
|
|
15
15
|
.command('get')
|
|
16
16
|
.description('Get configuration value')
|
|
17
|
-
.argument('<key>', 'Configuration key')
|
|
17
|
+
.argument('<key>', 'Configuration key (e.g., providers.wise.environment)')
|
|
18
18
|
.action((key) => {
|
|
19
|
+
// Handle provider-specific keys
|
|
20
|
+
if (key.startsWith('providers.')) {
|
|
21
|
+
const parts = key.split('.');
|
|
22
|
+
const providerName = parts[1];
|
|
23
|
+
const providerKey = parts[2];
|
|
24
|
+
|
|
25
|
+
const provider = configManager.getProvider(providerName);
|
|
26
|
+
if (provider && providerKey) {
|
|
27
|
+
const value = (provider as any)[providerKey];
|
|
28
|
+
if (value !== undefined) {
|
|
29
|
+
console.log(JSON.stringify(value, null, 2));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
console.log(chalk.yellow(`Key '${key}' not found`));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Handle nested keys
|
|
38
|
+
if (key.includes('.')) {
|
|
39
|
+
const parts = key.split('.');
|
|
40
|
+
const config = configManager.getConfig();
|
|
41
|
+
let current = config;
|
|
42
|
+
|
|
43
|
+
for (const part of parts) {
|
|
44
|
+
if (current && typeof current === 'object' && part in current) {
|
|
45
|
+
current = current[part];
|
|
46
|
+
} else {
|
|
47
|
+
console.log(chalk.yellow(`Key '${key}' not found`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
console.log(JSON.stringify(current, null, 2));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Simple key
|
|
19
56
|
const config = configManager.getConfig();
|
|
20
57
|
const value = config[key];
|
|
21
58
|
if (value !== undefined) {
|
|
@@ -31,39 +68,47 @@ configCommands
|
|
|
31
68
|
.argument('<key>', 'Configuration key (e.g., providers.wise.environment)')
|
|
32
69
|
.argument('<value>', 'Configuration value')
|
|
33
70
|
.action((key, value) => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
37
|
-
if (!current[keys[i]]) current[keys[i]] = {};
|
|
38
|
-
current = current[keys[i]];
|
|
39
|
-
}
|
|
40
|
-
current[keys[keys.length - 1]] = val;
|
|
41
|
-
};
|
|
42
|
-
|
|
71
|
+
// Parse the value (try JSON first, then use as string)
|
|
72
|
+
let parsedValue: any;
|
|
43
73
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
74
|
+
parsedValue = JSON.parse(value);
|
|
75
|
+
} catch {
|
|
76
|
+
parsedValue = value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Handle nested keys like providers.wise.environment
|
|
80
|
+
if (key.startsWith('providers.')) {
|
|
81
|
+
const parts = key.split('.');
|
|
82
|
+
const providerName = parts[1];
|
|
83
|
+
const providerKey = parts[2];
|
|
46
84
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
configManager.setConfig(parts[0], config[parts[0]]);
|
|
51
|
-
} else {
|
|
52
|
-
configManager.setConfig(key, parsedValue);
|
|
53
|
-
}
|
|
85
|
+
const provider = configManager.getProvider(providerName) || { name: providerName };
|
|
86
|
+
(provider as any)[providerKey] = parsedValue;
|
|
87
|
+
configManager.setProvider(providerName, provider as any);
|
|
54
88
|
console.log(chalk.green(`✓ Set ${key} = ${value}`));
|
|
55
|
-
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle other nested keys
|
|
93
|
+
if (key.includes('.')) {
|
|
94
|
+
const parts = key.split('.');
|
|
56
95
|
const config = configManager.getConfig();
|
|
96
|
+
let current = config;
|
|
57
97
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
configManager.setConfig(parts[0], config[parts[0]]);
|
|
62
|
-
} else {
|
|
63
|
-
configManager.setConfig(key, value);
|
|
98
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
99
|
+
if (!current[parts[i]]) current[parts[i]] = {};
|
|
100
|
+
current = current[parts[i]];
|
|
64
101
|
}
|
|
102
|
+
current[parts[parts.length - 1]] = parsedValue;
|
|
103
|
+
|
|
104
|
+
configManager.setConfig(parts[0], config[parts[0]]);
|
|
65
105
|
console.log(chalk.green(`✓ Set ${key} = ${value}`));
|
|
106
|
+
return;
|
|
66
107
|
}
|
|
108
|
+
|
|
109
|
+
// Simple key
|
|
110
|
+
configManager.setConfig(key, parsedValue);
|
|
111
|
+
console.log(chalk.green(`✓ Set ${key} = ${value}`));
|
|
67
112
|
});
|
|
68
113
|
|
|
69
114
|
configCommands
|
package/src/commands/wise.ts
CHANGED
|
@@ -175,6 +175,43 @@ wiseCommands
|
|
|
175
175
|
}
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
+
// Create recipient
|
|
179
|
+
wiseCommands
|
|
180
|
+
.command('create-recipient')
|
|
181
|
+
.description('Create a recipient account')
|
|
182
|
+
.requiredOption('-n, --name <name>', 'Account holder name')
|
|
183
|
+
.requiredOption('-c, --currency <currency>', 'Currency (EUR, USD, etc)')
|
|
184
|
+
.requiredOption('--iban <iban>', 'IBAN number')
|
|
185
|
+
.option('-p, --profile <id>', 'Profile ID')
|
|
186
|
+
.action(async (options) => {
|
|
187
|
+
const spinner = ora('Creating recipient...').start();
|
|
188
|
+
try {
|
|
189
|
+
const config = configManager.getProvider('wise');
|
|
190
|
+
if (!config) {
|
|
191
|
+
throw new Error('Wise not configured');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const client = new WiseClient(config as any);
|
|
195
|
+
const profileId = options.profile || config.profileId;
|
|
196
|
+
|
|
197
|
+
const recipient = await client.createRecipient(
|
|
198
|
+
profileId,
|
|
199
|
+
options.currency,
|
|
200
|
+
options.name,
|
|
201
|
+
{ iban: options.iban }
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
spinner.stop();
|
|
205
|
+
console.log(chalk.green('✓ Recipient created'));
|
|
206
|
+
console.log(` ID: ${recipient.id}`);
|
|
207
|
+
console.log(` Name: ${recipient.accountHolderName}`);
|
|
208
|
+
console.log(` IBAN: ${recipient.details.iban}`);
|
|
209
|
+
} catch (error: any) {
|
|
210
|
+
spinner.fail(error.message);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
178
215
|
// List transfers
|
|
179
216
|
wiseCommands
|
|
180
217
|
.command('list')
|
package/src/core/config.ts
CHANGED
|
@@ -15,7 +15,15 @@ import {
|
|
|
15
15
|
BunqConfig
|
|
16
16
|
} from '../types';
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
// Support both old location (~/.payment-skill) and new location (./data)
|
|
19
|
+
const OLD_CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.payment-skill');
|
|
20
|
+
const NEW_CONFIG_DIR = path.join(__dirname, '..', '..', 'data');
|
|
21
|
+
|
|
22
|
+
// Use new location if it exists and has config, otherwise fall back to old location
|
|
23
|
+
const CONFIG_DIR = fs.existsSync(path.join(NEW_CONFIG_DIR, 'config.json'))
|
|
24
|
+
? NEW_CONFIG_DIR
|
|
25
|
+
: (fs.existsSync(OLD_CONFIG_DIR) ? OLD_CONFIG_DIR : NEW_CONFIG_DIR);
|
|
26
|
+
|
|
19
27
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
20
28
|
const EMERGENCY_FILE = path.join(CONFIG_DIR, 'emergency.json');
|
|
21
29
|
|
package/src/core/transaction.ts
CHANGED
|
@@ -9,7 +9,15 @@ import * as path from 'path';
|
|
|
9
9
|
import { Transaction, TransactionStatus } from '../types';
|
|
10
10
|
import { configManager } from './config';
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// Support both old location (~/.payment-skill) and new location (./data)
|
|
13
|
+
const OLD_DATA_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.payment-skill');
|
|
14
|
+
const NEW_DATA_DIR = path.join(__dirname, '..', '..', 'data');
|
|
15
|
+
|
|
16
|
+
// Use new location if it exists and has config, otherwise fall back to old location
|
|
17
|
+
const DATA_DIR = fs.existsSync(path.join(NEW_DATA_DIR, 'config.json'))
|
|
18
|
+
? NEW_DATA_DIR
|
|
19
|
+
: (fs.existsSync(OLD_DATA_DIR) ? OLD_DATA_DIR : NEW_DATA_DIR);
|
|
20
|
+
|
|
13
21
|
const TRANSACTIONS_FILE = path.join(DATA_DIR, 'transactions.json');
|
|
14
22
|
|
|
15
23
|
export class TransactionManager {
|
package/src/server/server.ts
CHANGED
|
@@ -8,6 +8,7 @@ import express from 'express';
|
|
|
8
8
|
import cors from 'cors';
|
|
9
9
|
import helmet from 'helmet';
|
|
10
10
|
import path from 'path';
|
|
11
|
+
import * as fs from 'fs-extra';
|
|
11
12
|
import { configManager } from '../core/config';
|
|
12
13
|
import { transactionManager } from '../core/transaction';
|
|
13
14
|
import { fetchAndSaveWiseProfile } from '../api/wise-profile';
|
|
@@ -16,7 +17,7 @@ export class PaymentSkillServer {
|
|
|
16
17
|
private app: express.Application;
|
|
17
18
|
private port: number;
|
|
18
19
|
|
|
19
|
-
constructor(port: number =
|
|
20
|
+
constructor(port: number = 18790) {
|
|
20
21
|
this.app = express();
|
|
21
22
|
this.port = port;
|
|
22
23
|
this.setupMiddleware();
|
|
@@ -250,6 +251,24 @@ export class PaymentSkillServer {
|
|
|
250
251
|
res.status(200).send('OK');
|
|
251
252
|
});
|
|
252
253
|
|
|
254
|
+
// Verified Merchants
|
|
255
|
+
this.app.get('/api/verified-merchants', (req, res) => {
|
|
256
|
+
try {
|
|
257
|
+
const merchantsPath = path.join(__dirname, '../../verified-merchants.json');
|
|
258
|
+
console.log('Looking for verified merchants at:', merchantsPath);
|
|
259
|
+
if (fs.existsSync(merchantsPath)) {
|
|
260
|
+
const data = fs.readJsonSync(merchantsPath);
|
|
261
|
+
res.json(data);
|
|
262
|
+
} else {
|
|
263
|
+
console.log('File not found, returning empty list');
|
|
264
|
+
res.json({ merchants: [], version: '1.0.0' });
|
|
265
|
+
}
|
|
266
|
+
} catch (error: any) {
|
|
267
|
+
console.error('Error loading verified merchants:', error.message);
|
|
268
|
+
res.status(500).json({ error: 'Failed to load verified merchants', details: error.message });
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
|
|
253
272
|
// Dashboard route - serve dashboard.html
|
|
254
273
|
this.app.get('/', (req, res) => {
|
|
255
274
|
res.sendFile(path.join(__dirname, '../../dashboard.html'));
|
|
@@ -270,7 +289,7 @@ export class PaymentSkillServer {
|
|
|
270
289
|
|
|
271
290
|
// Start server if run directly
|
|
272
291
|
if (require.main === module) {
|
|
273
|
-
const port = parseInt(process.env.PORT || '
|
|
292
|
+
const port = parseInt(process.env.PORT || '18790');
|
|
274
293
|
const server = new PaymentSkillServer(port);
|
|
275
294
|
server.start();
|
|
276
295
|
}
|
package/verified-merchants.json
CHANGED
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"id": "clickclack-market",
|
|
41
|
-
"name": "
|
|
42
|
-
"domains": ["
|
|
41
|
+
"name": "ManyClaws",
|
|
42
|
+
"domains": ["manyclaws.store"],
|
|
43
43
|
"categories": ["marketplace", "shopping"],
|
|
44
44
|
"verified": true,
|
|
45
45
|
"riskLevel": "low",
|