paisa-mcp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +211 -101
- package/dist/index.js.map +14 -13
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -53145,6 +53145,90 @@ class PaisaApiClient {
|
|
|
53145
53145
|
}
|
|
53146
53146
|
}
|
|
53147
53147
|
|
|
53148
|
+
// ../../node_modules/.bun/@nimit9+signet-lib@0.1.15+d40099021b198cb0/node_modules/@nimit9/signet-lib/dist/crypto/index.js
|
|
53149
|
+
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
53150
|
+
async function decryptFields(input2, paths, { decrypt, isCiphertext }) {
|
|
53151
|
+
const undecrypted = [];
|
|
53152
|
+
const pending = [];
|
|
53153
|
+
const looksEncrypted = (value, path) => {
|
|
53154
|
+
if (!isCiphertext)
|
|
53155
|
+
return true;
|
|
53156
|
+
try {
|
|
53157
|
+
return isCiphertext(value, path) !== false;
|
|
53158
|
+
} catch {
|
|
53159
|
+
return true;
|
|
53160
|
+
}
|
|
53161
|
+
};
|
|
53162
|
+
const decryptInto = (target, key, value, path) => {
|
|
53163
|
+
pending.push((async () => {
|
|
53164
|
+
try {
|
|
53165
|
+
const plain = await decrypt(value, path);
|
|
53166
|
+
if (typeof plain !== "string")
|
|
53167
|
+
throw new TypeError("decrypt returned a non-string");
|
|
53168
|
+
target[key] = plain;
|
|
53169
|
+
} catch {
|
|
53170
|
+
target[key] = null;
|
|
53171
|
+
undecrypted.push(path);
|
|
53172
|
+
}
|
|
53173
|
+
})());
|
|
53174
|
+
};
|
|
53175
|
+
const copies = new Map;
|
|
53176
|
+
const mine = new WeakSet;
|
|
53177
|
+
const copyOf = (v) => {
|
|
53178
|
+
if (mine.has(v))
|
|
53179
|
+
return v;
|
|
53180
|
+
let c = copies.get(v);
|
|
53181
|
+
if (!c) {
|
|
53182
|
+
c = Array.isArray(v) ? [...v] : { ...v };
|
|
53183
|
+
copies.set(v, c);
|
|
53184
|
+
mine.add(c);
|
|
53185
|
+
}
|
|
53186
|
+
return c;
|
|
53187
|
+
};
|
|
53188
|
+
const walk = (node2, keys, at, set2) => {
|
|
53189
|
+
if (Array.isArray(node2)) {
|
|
53190
|
+
const arr = copyOf(node2);
|
|
53191
|
+
set2(arr);
|
|
53192
|
+
arr.forEach((item, i) => {
|
|
53193
|
+
walk(item, keys, at ? `${at}.${i}` : String(i), (v) => {
|
|
53194
|
+
arr[i] = v;
|
|
53195
|
+
});
|
|
53196
|
+
});
|
|
53197
|
+
return;
|
|
53198
|
+
}
|
|
53199
|
+
if (!isObj(node2) || keys.length === 0)
|
|
53200
|
+
return;
|
|
53201
|
+
const [key, ...rest] = keys;
|
|
53202
|
+
if (!Object.hasOwn(node2, key))
|
|
53203
|
+
return;
|
|
53204
|
+
const obj = copyOf(node2);
|
|
53205
|
+
set2(obj);
|
|
53206
|
+
const path = at ? `${at}.${key}` : key;
|
|
53207
|
+
const value = obj[key];
|
|
53208
|
+
if (rest.length > 0) {
|
|
53209
|
+
walk(value, rest, path, (v) => {
|
|
53210
|
+
obj[key] = v;
|
|
53211
|
+
});
|
|
53212
|
+
return;
|
|
53213
|
+
}
|
|
53214
|
+
if (typeof value === "string" && value !== "" && looksEncrypted(value, path)) {
|
|
53215
|
+
decryptInto(obj, key, value, path);
|
|
53216
|
+
}
|
|
53217
|
+
};
|
|
53218
|
+
let data = input2;
|
|
53219
|
+
for (const p of paths) {
|
|
53220
|
+
const keys = p.split(".").filter(Boolean);
|
|
53221
|
+
if (keys.length === 0)
|
|
53222
|
+
continue;
|
|
53223
|
+
walk(data, keys, "", (v) => {
|
|
53224
|
+
data = v;
|
|
53225
|
+
});
|
|
53226
|
+
}
|
|
53227
|
+
await Promise.all(pending);
|
|
53228
|
+
undecrypted.sort();
|
|
53229
|
+
return { data, undecrypted };
|
|
53230
|
+
}
|
|
53231
|
+
|
|
53148
53232
|
// src/crypto.ts
|
|
53149
53233
|
var import_hash_wasm = __toESM(require_index_umd(), 1);
|
|
53150
53234
|
var ENCRYPTED_TXN_FIELDS = ["description", "referenceNumber", "notes"];
|
|
@@ -53207,16 +53291,6 @@ async function decryptField(encrypted, key) {
|
|
|
53207
53291
|
const plaintext = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
|
|
53208
53292
|
return new TextDecoder().decode(plaintext);
|
|
53209
53293
|
}
|
|
53210
|
-
async function decryptObjectFields(obj, fields, key) {
|
|
53211
|
-
for (const field of fields) {
|
|
53212
|
-
const val = obj[field];
|
|
53213
|
-
if (typeof val !== "string" || !val)
|
|
53214
|
-
continue;
|
|
53215
|
-
try {
|
|
53216
|
-
obj[field] = await decryptField(val, key);
|
|
53217
|
-
} catch {}
|
|
53218
|
-
}
|
|
53219
|
-
}
|
|
53220
53294
|
async function encryptObjectFields(obj, fields, key) {
|
|
53221
53295
|
for (const field of fields) {
|
|
53222
53296
|
const val = obj[field];
|
|
@@ -53225,25 +53299,55 @@ async function encryptObjectFields(obj, fields, key) {
|
|
|
53225
53299
|
obj[field] = await encryptField(val, key);
|
|
53226
53300
|
}
|
|
53227
53301
|
}
|
|
53302
|
+
var CIPHERTEXT_CHARSET_RE = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
53303
|
+
var MIN_CIPHERTEXT_B64_LEN = 40;
|
|
53304
|
+
function looksLikeCiphertext(value) {
|
|
53305
|
+
return value.length >= MIN_CIPHERTEXT_B64_LEN && CIPHERTEXT_CHARSET_RE.test(value);
|
|
53306
|
+
}
|
|
53307
|
+
async function decryptFieldsFailClosed(input2, paths, key) {
|
|
53308
|
+
return decryptFields(input2, paths, {
|
|
53309
|
+
decrypt: (ciphertext) => decryptField(ciphertext, key),
|
|
53310
|
+
isCiphertext: (value) => looksLikeCiphertext(value)
|
|
53311
|
+
});
|
|
53312
|
+
}
|
|
53313
|
+
var TXN_DECRYPT_PATHS = [
|
|
53314
|
+
...ENCRYPTED_TXN_FIELDS,
|
|
53315
|
+
...ENCRYPTED_MERCHANT_FIELDS.map((f) => `merchant.${f}`)
|
|
53316
|
+
];
|
|
53228
53317
|
async function decryptTransactionFields(items, key) {
|
|
53229
|
-
|
|
53230
|
-
await decryptObjectFields(item, ENCRYPTED_TXN_FIELDS, key);
|
|
53231
|
-
const merchant = item.merchant;
|
|
53232
|
-
if (merchant && typeof merchant === "object") {
|
|
53233
|
-
await decryptObjectFields(merchant, ENCRYPTED_MERCHANT_FIELDS, key);
|
|
53234
|
-
}
|
|
53235
|
-
}
|
|
53318
|
+
return decryptFieldsFailClosed(items, TXN_DECRYPT_PATHS, key);
|
|
53236
53319
|
}
|
|
53237
53320
|
async function decryptMerchantFields(items, key) {
|
|
53238
|
-
|
|
53239
|
-
await decryptObjectFields(item, ENCRYPTED_MERCHANT_FIELDS, key);
|
|
53240
|
-
}
|
|
53321
|
+
return decryptFieldsFailClosed(items, ENCRYPTED_MERCHANT_FIELDS, key);
|
|
53241
53322
|
}
|
|
53242
53323
|
async function encryptTransactionFields(items, key) {
|
|
53243
53324
|
for (const item of items) {
|
|
53244
53325
|
await encryptObjectFields(item, ENCRYPTED_TXN_FIELDS, key);
|
|
53245
53326
|
}
|
|
53246
53327
|
}
|
|
53328
|
+
async function decryptPersonCiphers(input2, key) {
|
|
53329
|
+
const { data, undecrypted } = await decryptFields(input2, ["cipher"], {
|
|
53330
|
+
decrypt: async (ciphertext) => {
|
|
53331
|
+
const json2 = await decryptField(ciphertext, key);
|
|
53332
|
+
JSON.parse(json2);
|
|
53333
|
+
return json2;
|
|
53334
|
+
}
|
|
53335
|
+
});
|
|
53336
|
+
const merge3 = (row) => {
|
|
53337
|
+
if (!row || typeof row !== "object")
|
|
53338
|
+
return;
|
|
53339
|
+
const r = row;
|
|
53340
|
+
if (typeof r.cipher !== "string")
|
|
53341
|
+
return;
|
|
53342
|
+
const fields = JSON.parse(r.cipher);
|
|
53343
|
+
Object.assign(r, fields, { cipher: null });
|
|
53344
|
+
};
|
|
53345
|
+
if (Array.isArray(data))
|
|
53346
|
+
data.forEach(merge3);
|
|
53347
|
+
else
|
|
53348
|
+
merge3(data);
|
|
53349
|
+
return { data, undecrypted };
|
|
53350
|
+
}
|
|
53247
53351
|
var VERIFIER_PLAINTEXT = "paisa-verify-v1";
|
|
53248
53352
|
async function checkVerifier(key, encryptedVerifier) {
|
|
53249
53353
|
try {
|
|
@@ -53862,7 +53966,8 @@ var dashboardOutputSchema = exports_external.object({
|
|
|
53862
53966
|
recentTransactions: exports_external.array(exports_external.record(exports_external.string(), exports_external.unknown())),
|
|
53863
53967
|
netWorth: exports_external.record(exports_external.string(), exports_external.unknown()).nullable(),
|
|
53864
53968
|
debtSummary: exports_external.object({ totalOutstanding: exports_external.number(), totalEmi: exports_external.number(), count: exports_external.number() }).nullable(),
|
|
53865
|
-
budgetVsActual: exports_external.array(budgetVsActualEntrySchema)
|
|
53969
|
+
budgetVsActual: exports_external.array(budgetVsActualEntrySchema),
|
|
53970
|
+
undecrypted: exports_external.array(exports_external.string()).optional()
|
|
53866
53971
|
});
|
|
53867
53972
|
var spendingTrendsSchema = exports_external.object({
|
|
53868
53973
|
success: exports_external.literal(true),
|
|
@@ -53897,7 +54002,8 @@ var spendingTrendsSchema = exports_external.object({
|
|
|
53897
54002
|
total: exports_external.number(),
|
|
53898
54003
|
count: exports_external.number()
|
|
53899
54004
|
})),
|
|
53900
|
-
budgetVsActual: exports_external.array(budgetVsActualEntrySchema)
|
|
54005
|
+
budgetVsActual: exports_external.array(budgetVsActualEntrySchema),
|
|
54006
|
+
undecrypted: exports_external.array(exports_external.string()).optional()
|
|
53901
54007
|
});
|
|
53902
54008
|
var categoryAnalyticsSchema = exports_external.object({
|
|
53903
54009
|
success: exports_external.literal(true),
|
|
@@ -53912,7 +54018,7 @@ var categoryAnalyticsSchema = exports_external.object({
|
|
|
53912
54018
|
recentTransactions: exports_external.array(exports_external.object({
|
|
53913
54019
|
id: exports_external.string(),
|
|
53914
54020
|
date: exports_external.string(),
|
|
53915
|
-
description: exports_external.string(),
|
|
54021
|
+
description: exports_external.string().nullable(),
|
|
53916
54022
|
amount: exports_external.number(),
|
|
53917
54023
|
type: exports_external.string(),
|
|
53918
54024
|
owner: exports_external.string(),
|
|
@@ -53926,7 +54032,8 @@ var categoryAnalyticsSchema = exports_external.object({
|
|
|
53926
54032
|
total: exports_external.number(),
|
|
53927
54033
|
count: exports_external.number()
|
|
53928
54034
|
})),
|
|
53929
|
-
stats: exports_external.object({ total: exports_external.number(), avgMonthly: exports_external.number(), count: exports_external.number() })
|
|
54035
|
+
stats: exports_external.object({ total: exports_external.number(), avgMonthly: exports_external.number(), count: exports_external.number() }),
|
|
54036
|
+
undecrypted: exports_external.array(exports_external.string()).optional()
|
|
53930
54037
|
});
|
|
53931
54038
|
var merchantAnalyticsSchema = exports_external.object({
|
|
53932
54039
|
success: exports_external.literal(true),
|
|
@@ -53941,7 +54048,7 @@ var merchantAnalyticsSchema = exports_external.object({
|
|
|
53941
54048
|
recentTransactions: exports_external.array(exports_external.object({
|
|
53942
54049
|
id: exports_external.string(),
|
|
53943
54050
|
date: exports_external.string(),
|
|
53944
|
-
description: exports_external.string(),
|
|
54051
|
+
description: exports_external.string().nullable(),
|
|
53945
54052
|
amount: exports_external.number(),
|
|
53946
54053
|
type: exports_external.string(),
|
|
53947
54054
|
owner: exports_external.string(),
|
|
@@ -53956,7 +54063,8 @@ var merchantAnalyticsSchema = exports_external.object({
|
|
|
53956
54063
|
total: exports_external.number(),
|
|
53957
54064
|
count: exports_external.number()
|
|
53958
54065
|
})),
|
|
53959
|
-
stats: exports_external.object({ total: exports_external.number(), avgMonthly: exports_external.number(), count: exports_external.number() })
|
|
54066
|
+
stats: exports_external.object({ total: exports_external.number(), avgMonthly: exports_external.number(), count: exports_external.number() }),
|
|
54067
|
+
undecrypted: exports_external.array(exports_external.string()).optional()
|
|
53960
54068
|
});
|
|
53961
54069
|
var analyticsOutputSchema = exports_external.union([
|
|
53962
54070
|
spendingTrendsSchema,
|
|
@@ -53965,37 +54073,17 @@ var analyticsOutputSchema = exports_external.union([
|
|
|
53965
54073
|
]);
|
|
53966
54074
|
|
|
53967
54075
|
// src/tools/analytics.ts
|
|
53968
|
-
async function dec(value, key) {
|
|
53969
|
-
if (typeof value !== "string" || !value)
|
|
53970
|
-
return value;
|
|
53971
|
-
try {
|
|
53972
|
-
return await decryptField(value, key);
|
|
53973
|
-
} catch {
|
|
53974
|
-
return value;
|
|
53975
|
-
}
|
|
53976
|
-
}
|
|
53977
54076
|
async function decryptAnalytics(data, key) {
|
|
53978
54077
|
if (!data || typeof data !== "object")
|
|
53979
|
-
return;
|
|
53980
|
-
const
|
|
53981
|
-
|
|
53982
|
-
|
|
53983
|
-
|
|
53984
|
-
|
|
53985
|
-
|
|
53986
|
-
|
|
53987
|
-
|
|
53988
|
-
for (const t of recent) {
|
|
53989
|
-
t.description = await dec(t.description, key);
|
|
53990
|
-
if ("merchantName" in t)
|
|
53991
|
-
t.merchantName = await dec(t.merchantName, key);
|
|
53992
|
-
}
|
|
53993
|
-
}
|
|
53994
|
-
const merchant = d.merchant;
|
|
53995
|
-
if (merchant && typeof merchant === "object") {
|
|
53996
|
-
merchant.cleanName = await dec(merchant.cleanName, key);
|
|
53997
|
-
merchant.rawId = await dec(merchant.rawId, key);
|
|
53998
|
-
}
|
|
54078
|
+
return data;
|
|
54079
|
+
const { data: decrypted, undecrypted } = await decryptFieldsFailClosed(data, [
|
|
54080
|
+
"topMerchants.name",
|
|
54081
|
+
"recentTransactions.description",
|
|
54082
|
+
"recentTransactions.merchantName",
|
|
54083
|
+
"merchant.cleanName",
|
|
54084
|
+
"merchant.rawId"
|
|
54085
|
+
], key);
|
|
54086
|
+
return undecrypted.length ? { ...decrypted, undecrypted } : decrypted;
|
|
53999
54087
|
}
|
|
54000
54088
|
function analyticsTools(client, crypto3) {
|
|
54001
54089
|
return [
|
|
@@ -54023,7 +54111,7 @@ function analyticsTools(client, crypto3) {
|
|
|
54023
54111
|
break;
|
|
54024
54112
|
}
|
|
54025
54113
|
if (crypto3)
|
|
54026
|
-
await decryptAnalytics(data, crypto3.key);
|
|
54114
|
+
data = await decryptAnalytics(data, crypto3.key);
|
|
54027
54115
|
return data;
|
|
54028
54116
|
}
|
|
54029
54117
|
})
|
|
@@ -54091,7 +54179,10 @@ function dashboardTools(client, crypto3) {
|
|
|
54091
54179
|
handler: async (params) => {
|
|
54092
54180
|
const data = await client.get("/api/dashboard", params.months ? { months: params.months } : undefined);
|
|
54093
54181
|
if (crypto3 && Array.isArray(data?.recentTransactions)) {
|
|
54094
|
-
await decryptTransactionFields(data.recentTransactions, crypto3.key);
|
|
54182
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.recentTransactions, crypto3.key);
|
|
54183
|
+
data.recentTransactions = decrypted;
|
|
54184
|
+
if (undecrypted.length)
|
|
54185
|
+
return { ...data, undecrypted };
|
|
54095
54186
|
}
|
|
54096
54187
|
return data;
|
|
54097
54188
|
}
|
|
@@ -54643,13 +54734,17 @@ function merchantVariants(client, crypto3) {
|
|
|
54643
54734
|
return {
|
|
54644
54735
|
list: variant(exports_external.object({ rawId: exports_external.string().optional().describe("merchants: find one by UPI ID or name") }), async ({ rawId }) => {
|
|
54645
54736
|
const data = await client.get("/api/merchants");
|
|
54646
|
-
|
|
54647
|
-
|
|
54737
|
+
let undecrypted = [];
|
|
54738
|
+
if (crypto3 && data.data) {
|
|
54739
|
+
const dec = await decryptMerchantFields(data.data, crypto3.key);
|
|
54740
|
+
data.data = dec.data;
|
|
54741
|
+
undecrypted = dec.undecrypted;
|
|
54742
|
+
}
|
|
54648
54743
|
if (!rawId)
|
|
54649
|
-
return data;
|
|
54744
|
+
return undecrypted.length ? { ...data, undecrypted } : data;
|
|
54650
54745
|
const needle = rawId.toLowerCase();
|
|
54651
54746
|
const merchants = (data.data ?? []).filter((m) => String(m.rawId ?? "").toLowerCase() === needle || String(m.cleanName ?? "").toLowerCase().includes(needle));
|
|
54652
|
-
return { ...data, data: merchants };
|
|
54747
|
+
return { ...data, data: merchants, ...undecrypted.length ? { undecrypted } : {} };
|
|
54653
54748
|
}),
|
|
54654
54749
|
upsert: variant(exports_external.object({
|
|
54655
54750
|
id: exports_external.string().optional().describe("Merchant UUID — pass to update, omit to create"),
|
|
@@ -54758,22 +54853,19 @@ function personVariants(client, crypto3) {
|
|
|
54758
54853
|
if (id) {
|
|
54759
54854
|
const data2 = await client.get(`/api/persons/${id}`);
|
|
54760
54855
|
if (crypto3 && data2.data.cipher) {
|
|
54761
|
-
const
|
|
54762
|
-
|
|
54856
|
+
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data2.data, crypto3.key);
|
|
54857
|
+
data2.data = decrypted;
|
|
54858
|
+
if (undecrypted.length)
|
|
54859
|
+
return { ...data2, undecrypted };
|
|
54763
54860
|
}
|
|
54764
54861
|
return data2;
|
|
54765
54862
|
}
|
|
54766
54863
|
const data = await client.get("/api/persons");
|
|
54767
54864
|
if (crypto3 && data.data) {
|
|
54768
|
-
|
|
54769
|
-
|
|
54770
|
-
|
|
54771
|
-
|
|
54772
|
-
const fields = await decryptPersonCipher(cipher, crypto3.key);
|
|
54773
|
-
Object.assign(person, fields, { cipher: null });
|
|
54774
|
-
} catch {}
|
|
54775
|
-
}
|
|
54776
|
-
}
|
|
54865
|
+
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data.data, crypto3.key);
|
|
54866
|
+
data.data = decrypted;
|
|
54867
|
+
if (undecrypted.length)
|
|
54868
|
+
return { ...data, undecrypted };
|
|
54777
54869
|
}
|
|
54778
54870
|
return data;
|
|
54779
54871
|
}),
|
|
@@ -58567,9 +58659,8 @@ async function fetchAllRowsPaged(client, crypto3, params = {}, maxPages = 100) {
|
|
|
58567
58659
|
if (cursor)
|
|
58568
58660
|
q2.cursor = cursor;
|
|
58569
58661
|
const res = await client.get("/api/transactions", q2);
|
|
58570
|
-
const
|
|
58571
|
-
|
|
58572
|
-
await decryptTransactionFields(batch, crypto3.key);
|
|
58662
|
+
const batch0 = res.data ?? [];
|
|
58663
|
+
const batch = crypto3 ? (await decryptTransactionFields(batch0, crypto3.key)).data : batch0;
|
|
58573
58664
|
out.push(...batch.map(toTxnRow));
|
|
58574
58665
|
if (!res.hasMore || !res.nextCursor || batch.length === 0 || res.nextCursor === cursor)
|
|
58575
58666
|
break;
|
|
@@ -59034,9 +59125,8 @@ async function runRescan(client, crypto3) {
|
|
|
59034
59125
|
bag = (await loadBag(client)).bag;
|
|
59035
59126
|
} catch {}
|
|
59036
59127
|
const merchantsRes = await client.get("/api/merchants");
|
|
59037
|
-
const
|
|
59038
|
-
|
|
59039
|
-
await decryptMerchantFields(allMerchants, crypto3.key);
|
|
59128
|
+
const allMerchants0 = merchantsRes.data ?? [];
|
|
59129
|
+
const allMerchants = crypto3 ? (await decryptMerchantFields(allMerchants0, crypto3.key)).data : allMerchants0;
|
|
59040
59130
|
const globalMerchants = allMerchants.filter((m2) => !m2.householdId && m2.cleanName).map((m2) => ({ id: m2.id, name: m2.cleanName }));
|
|
59041
59131
|
const localMerchants = allMerchants.filter((m2) => m2.householdId && m2.cleanName).map((m2) => ({ id: m2.id, name: m2.cleanName }));
|
|
59042
59132
|
const merchantCategoryById = new Map(allMerchants.filter((m2) => m2.categoryId).map((m2) => [m2.id, m2.categoryId]));
|
|
@@ -59133,9 +59223,13 @@ function transactionTools(client, crypto3) {
|
|
|
59133
59223
|
if (!full)
|
|
59134
59224
|
apiParams.view = "lean";
|
|
59135
59225
|
const data = await client.get("/api/transactions", Object.fromEntries(Object.entries(apiParams).filter(([, v2]) => v2 !== undefined).map(([k2, v2]) => [k2, String(v2)])));
|
|
59136
|
-
|
|
59137
|
-
|
|
59138
|
-
|
|
59226
|
+
let rows = data.data ?? [];
|
|
59227
|
+
let undecrypted = [];
|
|
59228
|
+
if (crypto3) {
|
|
59229
|
+
const dec = await decryptTransactionFields(rows, crypto3.key);
|
|
59230
|
+
rows = dec.data;
|
|
59231
|
+
undecrypted = dec.undecrypted;
|
|
59232
|
+
}
|
|
59139
59233
|
const personNames = new Map;
|
|
59140
59234
|
if (rows.some((r2) => r2.personId)) {
|
|
59141
59235
|
for (const p2 of await loadDecryptedPersons(client, crypto3))
|
|
@@ -59147,12 +59241,14 @@ function transactionTools(client, crypto3) {
|
|
|
59147
59241
|
if (person && personNames.has(person.id))
|
|
59148
59242
|
person.name = personNames.get(person.id) ?? "";
|
|
59149
59243
|
}
|
|
59150
|
-
|
|
59244
|
+
data.data = rows;
|
|
59245
|
+
return undecrypted.length ? { ...data, undecrypted } : data;
|
|
59151
59246
|
}
|
|
59152
59247
|
const out = {
|
|
59153
59248
|
rows: rows.map((r2) => toLeanRow(r2, personNames)),
|
|
59154
59249
|
...data.hasMore ? { more: true, cursor: data.nextCursor } : {},
|
|
59155
|
-
...data.summary ? { spent: data.summary.spent, income: data.summary.income } : {}
|
|
59250
|
+
...data.summary ? { spent: data.summary.spent, income: data.summary.income } : {},
|
|
59251
|
+
...undecrypted.length ? { undecrypted } : {}
|
|
59156
59252
|
};
|
|
59157
59253
|
return out;
|
|
59158
59254
|
}
|
|
@@ -59278,8 +59374,11 @@ function transactionTools(client, crypto3) {
|
|
|
59278
59374
|
}
|
|
59279
59375
|
if (action === "list") {
|
|
59280
59376
|
const data2 = await client.get("/api/transactions/duplicates");
|
|
59281
|
-
if (crypto3 && data2.data)
|
|
59282
|
-
await decryptTransactionFields(data2.data, crypto3.key);
|
|
59377
|
+
if (crypto3 && data2.data) {
|
|
59378
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data2.data, crypto3.key);
|
|
59379
|
+
data2.data = decrypted;
|
|
59380
|
+
return withTruncationWarning(undecrypted.length ? { ...data2, undecrypted } : data2);
|
|
59381
|
+
}
|
|
59283
59382
|
return withTruncationWarning(data2);
|
|
59284
59383
|
}
|
|
59285
59384
|
const data = await client.post("/api/transactions/duplicates/resolve", {
|
|
@@ -59299,8 +59398,11 @@ function transactionTools(client, crypto3) {
|
|
|
59299
59398
|
}),
|
|
59300
59399
|
handler: async ({ accountId, startDate, endDate }) => {
|
|
59301
59400
|
const data = await client.get("/api/transactions/reconciliation-context", { accountId, startDate, endDate });
|
|
59302
|
-
if (crypto3 && data.data)
|
|
59303
|
-
await decryptTransactionFields(data.data, crypto3.key);
|
|
59401
|
+
if (crypto3 && data.data) {
|
|
59402
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data, crypto3.key);
|
|
59403
|
+
data.data = decrypted;
|
|
59404
|
+
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
59405
|
+
}
|
|
59304
59406
|
return withTruncationWarning(data);
|
|
59305
59407
|
}
|
|
59306
59408
|
}),
|
|
@@ -59392,8 +59494,11 @@ function transactionTools(client, crypto3) {
|
|
|
59392
59494
|
input: exports_external.object({ ccAccountId: exports_external.string().uuid() }),
|
|
59393
59495
|
handler: async ({ ccAccountId }) => {
|
|
59394
59496
|
const data = await client.get("/api/transactions/settlement-candidates", { ccAccountId });
|
|
59395
|
-
if (crypto3 && data.data)
|
|
59396
|
-
await decryptTransactionFields(data.data, crypto3.key);
|
|
59497
|
+
if (crypto3 && data.data) {
|
|
59498
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data, crypto3.key);
|
|
59499
|
+
data.data = decrypted;
|
|
59500
|
+
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
59501
|
+
}
|
|
59397
59502
|
return withTruncationWarning(data);
|
|
59398
59503
|
}
|
|
59399
59504
|
}),
|
|
@@ -59403,11 +59508,15 @@ function transactionTools(client, crypto3) {
|
|
|
59403
59508
|
input: exports_external.object({ id: exports_external.string().uuid() }),
|
|
59404
59509
|
handler: async ({ id }) => {
|
|
59405
59510
|
const res = await client.get(`/api/transactions/${id}`);
|
|
59406
|
-
|
|
59511
|
+
let row = res.data;
|
|
59407
59512
|
if (!row)
|
|
59408
59513
|
return res;
|
|
59409
|
-
|
|
59410
|
-
|
|
59514
|
+
let undecrypted = [];
|
|
59515
|
+
if (crypto3) {
|
|
59516
|
+
const dec = await decryptTransactionFields([row], crypto3.key);
|
|
59517
|
+
row = dec.data[0];
|
|
59518
|
+
undecrypted = dec.undecrypted;
|
|
59519
|
+
}
|
|
59411
59520
|
const lean = Object.fromEntries([
|
|
59412
59521
|
"id",
|
|
59413
59522
|
"date",
|
|
@@ -59423,7 +59532,7 @@ function transactionTools(client, crypto3) {
|
|
|
59423
59532
|
"isDuplicate",
|
|
59424
59533
|
"source"
|
|
59425
59534
|
].filter((k2) => row[k2] !== undefined).map((k2) => [k2, row[k2]]));
|
|
59426
|
-
return lean;
|
|
59535
|
+
return undecrypted.length ? { ...lean, undecrypted } : lean;
|
|
59427
59536
|
}
|
|
59428
59537
|
})
|
|
59429
59538
|
];
|
|
@@ -59448,7 +59557,9 @@ function exportTools(client, crypto3) {
|
|
|
59448
59557
|
format: "json"
|
|
59449
59558
|
});
|
|
59450
59559
|
if (crypto3 && Array.isArray(data?.transactions)) {
|
|
59451
|
-
await decryptTransactionFields(data.transactions, crypto3.key);
|
|
59560
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.transactions, crypto3.key);
|
|
59561
|
+
data.transactions = decrypted;
|
|
59562
|
+
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
59452
59563
|
}
|
|
59453
59564
|
return withTruncationWarning(data);
|
|
59454
59565
|
}
|
|
@@ -59456,7 +59567,7 @@ function exportTools(client, crypto3) {
|
|
|
59456
59567
|
];
|
|
59457
59568
|
}
|
|
59458
59569
|
|
|
59459
|
-
// ../../node_modules/.bun/@nimit9+signet-ai@0.1.11+
|
|
59570
|
+
// ../../node_modules/.bun/@nimit9+signet-ai@0.1.11+53d0ad1559459462/node_modules/@nimit9/signet-ai/dist/jev.js
|
|
59460
59571
|
var JEV_DEFAULT_MODEL = "jev-1.13.0";
|
|
59461
59572
|
var JEV_DEFAULT_MIN_CONFIDENCE = 0.95;
|
|
59462
59573
|
var JEV_DEFAULT_TIMEOUT_MS = 8000;
|
|
@@ -59942,9 +60053,8 @@ async function runStatementImport(deps, args) {
|
|
|
59942
60053
|
throw new Error(`${basename(args.filePath)} parsed to 0 transactions (format ${format}). If it is a statement with real activity, the layout may not be supported.`);
|
|
59943
60054
|
}
|
|
59944
60055
|
const dates = txns.map((t2) => t2.date).sort();
|
|
59945
|
-
const
|
|
59946
|
-
|
|
59947
|
-
await decryptTransactionFields(existing, crypto3.key);
|
|
60056
|
+
const existing0 = await fetchReconciliationContext(client, account.id, dates[0], dates[dates.length - 1]);
|
|
60057
|
+
const existing = crypto3 ? (await decryptTransactionFields(existing0, crypto3.key)).data : existing0;
|
|
59948
60058
|
const present = existing.map((r2) => ({ ...r2, isDuplicate: false, isIgnored: false }));
|
|
59949
60059
|
const result = reconcile(present, { ...statement, transactions: txns });
|
|
59950
60060
|
const fresh = result.unmatched;
|
|
@@ -60282,7 +60392,7 @@ function registerResources(server, tools) {
|
|
|
60282
60392
|
// package.json
|
|
60283
60393
|
var package_default = {
|
|
60284
60394
|
name: "paisa-mcp",
|
|
60285
|
-
version: "0.3.
|
|
60395
|
+
version: "0.3.1",
|
|
60286
60396
|
repository: {
|
|
60287
60397
|
type: "git",
|
|
60288
60398
|
url: "git+https://github.com/nimit9/paisa.git",
|
|
@@ -60310,7 +60420,7 @@ var package_default = {
|
|
|
60310
60420
|
"@modelcontextprotocol/client": "^2.1.0",
|
|
60311
60421
|
"@modelcontextprotocol/server": "^2.1.0",
|
|
60312
60422
|
"@nimit9/signet-ai": "^0.1.11",
|
|
60313
|
-
"@nimit9/signet-lib": "^0.1.
|
|
60423
|
+
"@nimit9/signet-lib": "^0.1.15",
|
|
60314
60424
|
"@nimit9/signet-server": "^0.2.2",
|
|
60315
60425
|
"@paisa/parsers": "workspace:*",
|
|
60316
60426
|
"@paisa/reconciliation": "workspace:*",
|
|
@@ -60374,5 +60484,5 @@ main().catch((err) => {
|
|
|
60374
60484
|
process.exit(1);
|
|
60375
60485
|
});
|
|
60376
60486
|
|
|
60377
|
-
//# debugId=
|
|
60487
|
+
//# debugId=E169545C1C52BE7864756E2164756E21
|
|
60378
60488
|
//# sourceMappingURL=index.js.map
|