@ktmcp-cli/nordigen 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/.env.example +11 -0
- package/.eslintrc.json +17 -0
- package/AGENT.md +480 -0
- package/CHANGELOG.md +69 -0
- package/CONTRIBUTING.md +198 -0
- package/EXAMPLES.md +561 -0
- package/INDEX.md +193 -0
- package/LICENSE +21 -0
- package/OPENCLAW.md +468 -0
- package/PROJECT.md +366 -0
- package/QUICKREF.md +231 -0
- package/README.md +424 -0
- package/SETUP.md +259 -0
- package/SUMMARY.md +419 -0
- package/banner.png +0 -0
- package/bin/nordigen.js +84 -0
- package/logo.png +0 -0
- package/package.json +40 -0
- package/scripts/quickstart.sh +110 -0
- package/src/commands/accounts.js +205 -0
- package/src/commands/agreements.js +241 -0
- package/src/commands/auth.js +86 -0
- package/src/commands/config.js +173 -0
- package/src/commands/institutions.js +181 -0
- package/src/commands/payments.js +228 -0
- package/src/commands/requisitions.js +239 -0
- package/src/lib/api.js +491 -0
- package/src/lib/auth.js +113 -0
- package/src/lib/config.js +145 -0
- package/src/lib/output.js +255 -0
- package/test/api.test.js +88 -0
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
# Nordigen CLI - Usage Examples
|
|
2
|
+
|
|
3
|
+
Practical examples for common use cases.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Initial Setup](#initial-setup)
|
|
8
|
+
2. [Institution Discovery](#institution-discovery)
|
|
9
|
+
3. [Connecting Bank Accounts](#connecting-bank-accounts)
|
|
10
|
+
4. [Retrieving Account Data](#retrieving-account-data)
|
|
11
|
+
5. [Transaction Analysis](#transaction-analysis)
|
|
12
|
+
6. [Scripting and Automation](#scripting-and-automation)
|
|
13
|
+
7. [Error Handling](#error-handling)
|
|
14
|
+
8. [Advanced Use Cases](#advanced-use-cases)
|
|
15
|
+
|
|
16
|
+
## Initial Setup
|
|
17
|
+
|
|
18
|
+
### First-time authentication
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Get your API credentials from https://nordigen.com
|
|
22
|
+
export NORDIGEN_SECRET_ID="your-secret-id"
|
|
23
|
+
export NORDIGEN_SECRET_KEY="your-secret-key"
|
|
24
|
+
|
|
25
|
+
# Login
|
|
26
|
+
nordigen auth login \
|
|
27
|
+
--secret-id "$NORDIGEN_SECRET_ID" \
|
|
28
|
+
--secret-key "$NORDIGEN_SECRET_KEY"
|
|
29
|
+
|
|
30
|
+
# Verify authentication
|
|
31
|
+
nordigen auth status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Check stored configuration
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# View all config (secrets redacted)
|
|
38
|
+
nordigen config show
|
|
39
|
+
|
|
40
|
+
# View config with secrets visible (be careful!)
|
|
41
|
+
nordigen config show --show-secrets
|
|
42
|
+
|
|
43
|
+
# Get specific config value
|
|
44
|
+
nordigen config get auth.secret_id
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Institution Discovery
|
|
48
|
+
|
|
49
|
+
### List all banks in a country
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# List all UK banks
|
|
53
|
+
nordigen institutions list --country GB
|
|
54
|
+
|
|
55
|
+
# List German banks with JSON output
|
|
56
|
+
nordigen institutions list --country GB --json
|
|
57
|
+
|
|
58
|
+
# List only banks that support payments
|
|
59
|
+
nordigen institutions list --country GB --payments
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Search for specific banks
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Search for Barclays in UK
|
|
66
|
+
nordigen institutions search "Barclays" --country GB
|
|
67
|
+
|
|
68
|
+
# Search for multiple countries
|
|
69
|
+
for country in GB DE FR; do
|
|
70
|
+
echo "=== Banks in $country ==="
|
|
71
|
+
nordigen institutions search "N26" --country $country
|
|
72
|
+
done
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Get detailed bank information
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Get full details for a specific institution
|
|
79
|
+
nordigen institutions get BARCLAYS_BARCGB22
|
|
80
|
+
|
|
81
|
+
# Get details as JSON
|
|
82
|
+
nordigen institutions get BARCLAYS_BARCGB22 --json
|
|
83
|
+
|
|
84
|
+
# Extract specific field with jq
|
|
85
|
+
nordigen institutions get BARCLAYS_BARCGB22 --json | jq '.transaction_total_days'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Connecting Bank Accounts
|
|
89
|
+
|
|
90
|
+
### Complete connection flow
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Step 1: Find your bank
|
|
94
|
+
nordigen institutions search "Barclays" --country GB --json | jq '.[0].id'
|
|
95
|
+
INST_ID="BARCLAYS_BARCGB22"
|
|
96
|
+
|
|
97
|
+
# Step 2: Create end user agreement
|
|
98
|
+
AGREEMENT=$(nordigen agreements create \
|
|
99
|
+
--institution-id "$INST_ID" \
|
|
100
|
+
--max-days 90 \
|
|
101
|
+
--valid-days 90 \
|
|
102
|
+
--json | jq -r '.id')
|
|
103
|
+
|
|
104
|
+
echo "Created agreement: $AGREEMENT"
|
|
105
|
+
|
|
106
|
+
# Step 3: Create requisition
|
|
107
|
+
REQUISITION=$(nordigen requisitions create \
|
|
108
|
+
--institution-id "$INST_ID" \
|
|
109
|
+
--redirect "https://yourapp.com/callback" \
|
|
110
|
+
--agreement "$AGREEMENT" \
|
|
111
|
+
--json)
|
|
112
|
+
|
|
113
|
+
# Extract auth link
|
|
114
|
+
AUTH_LINK=$(echo "$REQUISITION" | jq -r '.link')
|
|
115
|
+
REQ_ID=$(echo "$REQUISITION" | jq -r '.id')
|
|
116
|
+
|
|
117
|
+
echo "Send this link to user: $AUTH_LINK"
|
|
118
|
+
echo "Requisition ID: $REQ_ID"
|
|
119
|
+
|
|
120
|
+
# Step 4: After user authenticates, get account IDs
|
|
121
|
+
sleep 10 # Wait for user authentication
|
|
122
|
+
nordigen requisitions get "$REQ_ID" --json | jq '.accounts[]'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Quick connection (one-liner)
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Create agreement and requisition in one go
|
|
129
|
+
nordigen agreements create --institution-id BARCLAYS_BARCGB22 --max-days 90 --json | \
|
|
130
|
+
jq -r '.id' | \
|
|
131
|
+
xargs -I {} nordigen requisitions create \
|
|
132
|
+
--institution-id BARCLAYS_BARCGB22 \
|
|
133
|
+
--redirect "https://app.example.com/callback" \
|
|
134
|
+
--agreement {} \
|
|
135
|
+
--json | \
|
|
136
|
+
jq -r '.link'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Retrieving Account Data
|
|
140
|
+
|
|
141
|
+
### Get account balances
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Simple balance check
|
|
145
|
+
nordigen accounts balances abc-123-def-456
|
|
146
|
+
|
|
147
|
+
# JSON output
|
|
148
|
+
nordigen accounts balances abc-123-def-456 --json
|
|
149
|
+
|
|
150
|
+
# Extract specific balance type
|
|
151
|
+
nordigen accounts balances abc-123-def-456 --json | \
|
|
152
|
+
jq '.balances[] | select(.balanceType == "expected") | .balanceAmount'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Get account details
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Get IBAN and account details
|
|
159
|
+
nordigen accounts details abc-123-def-456
|
|
160
|
+
|
|
161
|
+
# Extract IBAN only
|
|
162
|
+
nordigen accounts details abc-123-def-456 --json | jq -r '.account.iban'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Check multiple accounts
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Get balances for all accounts in a requisition
|
|
169
|
+
REQ_ID="your-requisition-id"
|
|
170
|
+
nordigen requisitions get "$REQ_ID" --json | \
|
|
171
|
+
jq -r '.accounts[]' | \
|
|
172
|
+
while read account_id; do
|
|
173
|
+
echo "=== Account: $account_id ==="
|
|
174
|
+
nordigen accounts balances "$account_id"
|
|
175
|
+
echo
|
|
176
|
+
done
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Transaction Analysis
|
|
180
|
+
|
|
181
|
+
### Get recent transactions
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Last 30 days
|
|
185
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
186
|
+
--from 2024-01-01 \
|
|
187
|
+
--to 2024-01-31
|
|
188
|
+
|
|
189
|
+
# Last month with JSON
|
|
190
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
191
|
+
--from $(date -d '1 month ago' +%Y-%m-%d) \
|
|
192
|
+
--to $(date +%Y-%m-%d) \
|
|
193
|
+
--json
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Analyze spending
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Get all transactions and sum amounts
|
|
200
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
201
|
+
--from 2024-01-01 \
|
|
202
|
+
--to 2024-01-31 \
|
|
203
|
+
--json | \
|
|
204
|
+
jq '.transactions.booked[] | .transactionAmount.amount' | \
|
|
205
|
+
awk '{sum+=$1} END {print "Total:", sum}'
|
|
206
|
+
|
|
207
|
+
# Count transactions by type
|
|
208
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
209
|
+
--from 2024-01-01 \
|
|
210
|
+
--to 2024-01-31 \
|
|
211
|
+
--json | \
|
|
212
|
+
jq '.transactions.booked[] | .transactionAmount.amount' | \
|
|
213
|
+
awk '{if ($1 < 0) debit++; else credit++} END {print "Debits:", debit, "Credits:", credit}'
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Export transactions to CSV
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Convert JSON to CSV
|
|
220
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
221
|
+
--from 2024-01-01 \
|
|
222
|
+
--to 2024-12-31 \
|
|
223
|
+
--json | \
|
|
224
|
+
jq -r '.transactions.booked[] |
|
|
225
|
+
[.bookingDate, .transactionAmount.amount, .transactionAmount.currency, .remittanceInformationUnstructured] |
|
|
226
|
+
@csv' > transactions.csv
|
|
227
|
+
|
|
228
|
+
# Add headers
|
|
229
|
+
echo "date,amount,currency,description" | cat - transactions.csv > transactions_final.csv
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Find largest transactions
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Top 10 expenses
|
|
236
|
+
nordigen accounts transactions abc-123-def-456 \
|
|
237
|
+
--from 2024-01-01 \
|
|
238
|
+
--to 2024-12-31 \
|
|
239
|
+
--json | \
|
|
240
|
+
jq '.transactions.booked[] |
|
|
241
|
+
select(.transactionAmount.amount | tonumber < 0) |
|
|
242
|
+
{date: .bookingDate, amount: .transactionAmount.amount, description: .remittanceInformationUnstructured}' | \
|
|
243
|
+
jq -s 'sort_by(.amount | tonumber) | .[0:10]'
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Scripting and Automation
|
|
247
|
+
|
|
248
|
+
### Daily balance check script
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
#!/bin/bash
|
|
252
|
+
# daily-balance.sh
|
|
253
|
+
|
|
254
|
+
ACCOUNTS=(
|
|
255
|
+
"account-id-1"
|
|
256
|
+
"account-id-2"
|
|
257
|
+
"account-id-3"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
echo "Daily Balance Report - $(date)"
|
|
261
|
+
echo "================================"
|
|
262
|
+
|
|
263
|
+
for account in "${ACCOUNTS[@]}"; do
|
|
264
|
+
echo
|
|
265
|
+
echo "Account: $account"
|
|
266
|
+
|
|
267
|
+
balance=$(nordigen accounts balances "$account" --json | \
|
|
268
|
+
jq -r '.balances[] | select(.balanceType == "expected") | .balanceAmount.amount')
|
|
269
|
+
|
|
270
|
+
currency=$(nordigen accounts balances "$account" --json | \
|
|
271
|
+
jq -r '.balances[] | select(.balanceType == "expected") | .balanceAmount.currency')
|
|
272
|
+
|
|
273
|
+
echo "Balance: $balance $currency"
|
|
274
|
+
done
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Weekly transaction summary
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
#!/bin/bash
|
|
281
|
+
# weekly-summary.sh
|
|
282
|
+
|
|
283
|
+
ACCOUNT_ID="your-account-id"
|
|
284
|
+
FROM_DATE=$(date -d '7 days ago' +%Y-%m-%d)
|
|
285
|
+
TO_DATE=$(date +%Y-%m-%d)
|
|
286
|
+
|
|
287
|
+
echo "Weekly Transaction Summary"
|
|
288
|
+
echo "Period: $FROM_DATE to $TO_DATE"
|
|
289
|
+
echo "================================"
|
|
290
|
+
|
|
291
|
+
# Get transactions
|
|
292
|
+
TRANSACTIONS=$(nordigen accounts transactions "$ACCOUNT_ID" \
|
|
293
|
+
--from "$FROM_DATE" \
|
|
294
|
+
--to "$TO_DATE" \
|
|
295
|
+
--json)
|
|
296
|
+
|
|
297
|
+
# Count and sum
|
|
298
|
+
total_transactions=$(echo "$TRANSACTIONS" | jq '.transactions.booked | length')
|
|
299
|
+
total_spent=$(echo "$TRANSACTIONS" | jq '.transactions.booked[] | select(.transactionAmount.amount | tonumber < 0) | .transactionAmount.amount | tonumber' | awk '{sum+=$1} END {print sum}')
|
|
300
|
+
total_income=$(echo "$TRANSACTIONS" | jq '.transactions.booked[] | select(.transactionAmount.amount | tonumber > 0) | .transactionAmount.amount | tonumber' | awk '{sum+=$1} END {print sum}')
|
|
301
|
+
|
|
302
|
+
echo "Total transactions: $total_transactions"
|
|
303
|
+
echo "Total spent: $(printf '%.2f' $total_spent)"
|
|
304
|
+
echo "Total income: $(printf '%.2f' $total_income)"
|
|
305
|
+
echo "Net: $(printf '%.2f' $(echo "$total_income + $total_spent" | bc))"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Monitor for large transactions
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
#!/bin/bash
|
|
312
|
+
# monitor-large-transactions.sh
|
|
313
|
+
|
|
314
|
+
ACCOUNT_ID="your-account-id"
|
|
315
|
+
THRESHOLD=1000 # Alert if transaction > 1000
|
|
316
|
+
|
|
317
|
+
FROM_DATE=$(date -d '1 day ago' +%Y-%m-%d)
|
|
318
|
+
TO_DATE=$(date +%Y-%m-%d)
|
|
319
|
+
|
|
320
|
+
nordigen accounts transactions "$ACCOUNT_ID" \
|
|
321
|
+
--from "$FROM_DATE" \
|
|
322
|
+
--to "$TO_DATE" \
|
|
323
|
+
--json | \
|
|
324
|
+
jq -r ".transactions.booked[] |
|
|
325
|
+
select((.transactionAmount.amount | tonumber | abs) > $THRESHOLD) |
|
|
326
|
+
\"ALERT: Large transaction on \\(.bookingDate): \\(.transactionAmount.amount) \\(.transactionAmount.currency) - \\(.remittanceInformationUnstructured)\""
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Sync all accounts to database
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
#!/bin/bash
|
|
333
|
+
# sync-to-db.sh
|
|
334
|
+
|
|
335
|
+
# Get all active requisitions
|
|
336
|
+
REQUISITIONS=$(nordigen requisitions list --json | jq -r '.results[].id')
|
|
337
|
+
|
|
338
|
+
for req_id in $REQUISITIONS; do
|
|
339
|
+
# Get accounts for this requisition
|
|
340
|
+
ACCOUNTS=$(nordigen requisitions get "$req_id" --json | jq -r '.accounts[]')
|
|
341
|
+
|
|
342
|
+
for account_id in $ACCOUNTS; do
|
|
343
|
+
echo "Syncing account: $account_id"
|
|
344
|
+
|
|
345
|
+
# Get latest transactions
|
|
346
|
+
TRANSACTIONS=$(nordigen accounts transactions "$account_id" \
|
|
347
|
+
--from $(date -d '30 days ago' +%Y-%m-%d) \
|
|
348
|
+
--json)
|
|
349
|
+
|
|
350
|
+
# Save to database (example with PostgreSQL)
|
|
351
|
+
echo "$TRANSACTIONS" | \
|
|
352
|
+
jq -r '.transactions.booked[] |
|
|
353
|
+
"INSERT INTO transactions (account_id, date, amount, currency, description) VALUES (\(env.account_id), \(.bookingDate), \(.transactionAmount.amount), \(.transactionAmount.currency), \(.remittanceInformationUnstructured));"' | \
|
|
354
|
+
psql -d mydb
|
|
355
|
+
done
|
|
356
|
+
done
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Error Handling
|
|
360
|
+
|
|
361
|
+
### Check authentication before commands
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
#!/bin/bash
|
|
365
|
+
|
|
366
|
+
# Function to ensure authentication
|
|
367
|
+
ensure_auth() {
|
|
368
|
+
if ! nordigen auth status 2>/dev/null | grep -q "Authenticated"; then
|
|
369
|
+
echo "Not authenticated. Logging in..."
|
|
370
|
+
nordigen auth login \
|
|
371
|
+
--secret-id "$NORDIGEN_SECRET_ID" \
|
|
372
|
+
--secret-key "$NORDIGEN_SECRET_KEY"
|
|
373
|
+
fi
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
# Use in scripts
|
|
377
|
+
ensure_auth
|
|
378
|
+
nordigen accounts balances abc-123-def-456
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Retry on failure
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
#!/bin/bash
|
|
385
|
+
|
|
386
|
+
# Function to retry command with backoff
|
|
387
|
+
retry_command() {
|
|
388
|
+
local max_attempts=3
|
|
389
|
+
local attempt=1
|
|
390
|
+
local delay=5
|
|
391
|
+
|
|
392
|
+
while [ $attempt -le $max_attempts ]; do
|
|
393
|
+
echo "Attempt $attempt of $max_attempts..."
|
|
394
|
+
|
|
395
|
+
if eval "$@"; then
|
|
396
|
+
return 0
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
echo "Failed. Retrying in ${delay}s..."
|
|
400
|
+
sleep $delay
|
|
401
|
+
delay=$((delay * 2))
|
|
402
|
+
attempt=$((attempt + 1))
|
|
403
|
+
done
|
|
404
|
+
|
|
405
|
+
echo "Command failed after $max_attempts attempts"
|
|
406
|
+
return 1
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
# Use it
|
|
410
|
+
retry_command nordigen accounts balances abc-123-def-456
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Handle rate limiting
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
#!/bin/bash
|
|
417
|
+
|
|
418
|
+
# Process accounts with rate limit handling
|
|
419
|
+
process_accounts() {
|
|
420
|
+
local accounts=("$@")
|
|
421
|
+
|
|
422
|
+
for account in "${accounts[@]}"; do
|
|
423
|
+
if ! nordigen accounts balances "$account" 2>/dev/null; then
|
|
424
|
+
error=$(nordigen accounts balances "$account" 2>&1 >/dev/null)
|
|
425
|
+
|
|
426
|
+
if echo "$error" | grep -q "Rate limit"; then
|
|
427
|
+
echo "Rate limited. Waiting 60 seconds..."
|
|
428
|
+
sleep 60
|
|
429
|
+
# Retry
|
|
430
|
+
nordigen accounts balances "$account"
|
|
431
|
+
else
|
|
432
|
+
echo "Error: $error"
|
|
433
|
+
fi
|
|
434
|
+
fi
|
|
435
|
+
done
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## Advanced Use Cases
|
|
440
|
+
|
|
441
|
+
### Multi-country account aggregation
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
#!/bin/bash
|
|
445
|
+
# aggregate-accounts.sh
|
|
446
|
+
|
|
447
|
+
# Countries and their institutions
|
|
448
|
+
declare -A COUNTRIES=(
|
|
449
|
+
["GB"]="BARCLAYS_BARCGB22 LLOYDS_LOYDGB21"
|
|
450
|
+
["DE"]="DEUTSCHE_DEUTDEFF COMMERZBANK_COBADEFF"
|
|
451
|
+
["FR"]="BNP_BNPAFRPP CREDIT_AGRICOLE_AGRIFRPP"
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
for country in "${!COUNTRIES[@]}"; do
|
|
455
|
+
echo "=== $country ==="
|
|
456
|
+
|
|
457
|
+
for institution in ${COUNTRIES[$country]}; do
|
|
458
|
+
echo " Institution: $institution"
|
|
459
|
+
nordigen institutions get "$institution" --json | jq '{name, bic, countries}'
|
|
460
|
+
done
|
|
461
|
+
done
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Transaction categorization
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
#!/bin/bash
|
|
468
|
+
# categorize-transactions.sh
|
|
469
|
+
|
|
470
|
+
ACCOUNT_ID="your-account-id"
|
|
471
|
+
|
|
472
|
+
# Get transactions
|
|
473
|
+
TRANSACTIONS=$(nordigen accounts transactions "$ACCOUNT_ID" \
|
|
474
|
+
--from 2024-01-01 \
|
|
475
|
+
--to 2024-12-31 \
|
|
476
|
+
--json)
|
|
477
|
+
|
|
478
|
+
# Categorize
|
|
479
|
+
echo "$TRANSACTIONS" | jq -r '.transactions.booked[] |
|
|
480
|
+
.description = .remittanceInformationUnstructured |
|
|
481
|
+
.category = (
|
|
482
|
+
if (.description | test("supermarket|tesco|sainsbury"; "i")) then "groceries"
|
|
483
|
+
elif (.description | test("restaurant|cafe|pizza"; "i")) then "dining"
|
|
484
|
+
elif (.description | test("uber|taxi|transport"; "i")) then "transport"
|
|
485
|
+
elif (.description | test("amazon|ebay|shop"; "i")) then "shopping"
|
|
486
|
+
else "other"
|
|
487
|
+
end
|
|
488
|
+
) |
|
|
489
|
+
{date: .bookingDate, amount: .transactionAmount.amount, category, description}' | \
|
|
490
|
+
jq -s 'group_by(.category) |
|
|
491
|
+
map({category: .[0].category, count: length, total: (map(.amount | tonumber) | add)})' | \
|
|
492
|
+
jq -r '.[] | "\(.category): \(.count) transactions, total: \(.total)"'
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Budget tracking
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
#!/bin/bash
|
|
499
|
+
# budget-tracker.sh
|
|
500
|
+
|
|
501
|
+
ACCOUNT_ID="your-account-id"
|
|
502
|
+
BUDGET=2000 # Monthly budget
|
|
503
|
+
|
|
504
|
+
# Get this month's transactions
|
|
505
|
+
FROM_DATE=$(date +%Y-%m-01)
|
|
506
|
+
TO_DATE=$(date +%Y-%m-%d)
|
|
507
|
+
|
|
508
|
+
SPENT=$(nordigen accounts transactions "$ACCOUNT_ID" \
|
|
509
|
+
--from "$FROM_DATE" \
|
|
510
|
+
--to "$TO_DATE" \
|
|
511
|
+
--json | \
|
|
512
|
+
jq '.transactions.booked[] |
|
|
513
|
+
select(.transactionAmount.amount | tonumber < 0) |
|
|
514
|
+
.transactionAmount.amount | tonumber' | \
|
|
515
|
+
awk '{sum+=$1} END {print sum}')
|
|
516
|
+
|
|
517
|
+
SPENT=${SPENT#-} # Remove negative sign
|
|
518
|
+
REMAINING=$(echo "$BUDGET - $SPENT" | bc)
|
|
519
|
+
PERCENTAGE=$(echo "scale=2; ($SPENT / $BUDGET) * 100" | bc)
|
|
520
|
+
|
|
521
|
+
echo "Budget Tracker"
|
|
522
|
+
echo "=============="
|
|
523
|
+
echo "Budget: $BUDGET"
|
|
524
|
+
echo "Spent: $SPENT"
|
|
525
|
+
echo "Remaining: $REMAINING"
|
|
526
|
+
echo "Used: ${PERCENTAGE}%"
|
|
527
|
+
|
|
528
|
+
if (( $(echo "$PERCENTAGE > 80" | bc -l) )); then
|
|
529
|
+
echo "WARNING: You've used more than 80% of your budget!"
|
|
530
|
+
fi
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Testing and Development
|
|
534
|
+
|
|
535
|
+
### Dry run mode
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
# Test commands without executing
|
|
539
|
+
DRY_RUN=1 ./your-script.sh
|
|
540
|
+
|
|
541
|
+
# In script:
|
|
542
|
+
if [ "$DRY_RUN" = "1" ]; then
|
|
543
|
+
echo "[DRY RUN] Would execute: nordigen accounts balances $ACCOUNT_ID"
|
|
544
|
+
else
|
|
545
|
+
nordigen accounts balances "$ACCOUNT_ID"
|
|
546
|
+
fi
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Debug mode
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
# Enable debug output
|
|
553
|
+
DEBUG=1 nordigen accounts balances abc-123-def-456
|
|
554
|
+
|
|
555
|
+
# With verbose bash
|
|
556
|
+
set -x
|
|
557
|
+
nordigen accounts balances abc-123-def-456
|
|
558
|
+
set +x
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
These examples should cover most common use cases. Combine and modify them based on your specific needs!
|