paisa-mcp 0.4.2 → 0.4.4
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 +179 -166
- package/dist/index.js.map +23 -22
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -53113,6 +53113,9 @@ function retryAfterMs(err) {
|
|
|
53113
53113
|
const ms = Number.isFinite(secs) ? secs * 1000 : Date.parse(raw) - Date.now();
|
|
53114
53114
|
return Number.isFinite(ms) && ms >= 0 ? Math.min(ms, 1e4) : undefined;
|
|
53115
53115
|
}
|
|
53116
|
+
function apiPath(strings, ...values) {
|
|
53117
|
+
return strings.reduce((out, s, i) => out + s + (i < values.length ? encodeURIComponent(String(values[i])) : ""), "");
|
|
53118
|
+
}
|
|
53116
53119
|
|
|
53117
53120
|
class PaisaApiClient {
|
|
53118
53121
|
retryBaseMs;
|
|
@@ -53256,25 +53259,8 @@ async function decryptFields(input2, paths, { decrypt, isCiphertext }) {
|
|
|
53256
53259
|
return { data, undecrypted };
|
|
53257
53260
|
}
|
|
53258
53261
|
|
|
53259
|
-
// src/
|
|
53262
|
+
// ../crypto/src/index.ts
|
|
53260
53263
|
var import_hash_wasm = __toESM(require_index_umd(), 1);
|
|
53261
|
-
var ENCRYPTED_TXN_FIELDS = ["description", "referenceNumber", "notes"];
|
|
53262
|
-
var ENCRYPTED_MERCHANT_FIELDS = ["cleanName", "rawId", "notes"];
|
|
53263
|
-
async function hmacWithKey(value, key) {
|
|
53264
|
-
const rawKey = await crypto.subtle.exportKey("raw", key);
|
|
53265
|
-
const hmacKey = await crypto.subtle.importKey("raw", rawKey, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
53266
|
-
const sig = await crypto.subtle.sign("HMAC", hmacKey, new TextEncoder().encode(value));
|
|
53267
|
-
return btoa(String.fromCharCode(...new Uint8Array(sig)));
|
|
53268
|
-
}
|
|
53269
|
-
async function encryptPersonCipher(fields, key) {
|
|
53270
|
-
const cipher = await encryptField(JSON.stringify(fields), key);
|
|
53271
|
-
const searchHash = await hmacWithKey(fields.name.toLowerCase().trim().replace(/\s+/g, " "), key);
|
|
53272
|
-
return { cipher, searchHash };
|
|
53273
|
-
}
|
|
53274
|
-
async function decryptPersonCipher(cipher, key) {
|
|
53275
|
-
const json2 = await decryptField(cipher, key);
|
|
53276
|
-
return JSON.parse(json2);
|
|
53277
|
-
}
|
|
53278
53264
|
async function deriveKey(userId, pin, salt) {
|
|
53279
53265
|
const enc = new TextEncoder;
|
|
53280
53266
|
const baseKey = await crypto.subtle.importKey("raw", enc.encode(userId + pin), "PBKDF2", false, [
|
|
@@ -53318,6 +53304,34 @@ async function decryptField(encrypted, key) {
|
|
|
53318
53304
|
const plaintext = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
|
|
53319
53305
|
return new TextDecoder().decode(plaintext);
|
|
53320
53306
|
}
|
|
53307
|
+
var VERIFIER_PLAINTEXT = "paisa-verify-v1";
|
|
53308
|
+
async function checkVerifier(key, encryptedVerifier) {
|
|
53309
|
+
try {
|
|
53310
|
+
const decrypted = await decryptField(encryptedVerifier, key);
|
|
53311
|
+
return decrypted === VERIFIER_PLAINTEXT;
|
|
53312
|
+
} catch {
|
|
53313
|
+
return false;
|
|
53314
|
+
}
|
|
53315
|
+
}
|
|
53316
|
+
|
|
53317
|
+
// src/crypto.ts
|
|
53318
|
+
var ENCRYPTED_TXN_FIELDS = ["description", "referenceNumber", "notes"];
|
|
53319
|
+
var ENCRYPTED_MERCHANT_FIELDS = ["cleanName", "rawId", "notes"];
|
|
53320
|
+
async function hmacWithKey(value, key) {
|
|
53321
|
+
const rawKey = await crypto.subtle.exportKey("raw", key);
|
|
53322
|
+
const hmacKey = await crypto.subtle.importKey("raw", rawKey, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
53323
|
+
const sig = await crypto.subtle.sign("HMAC", hmacKey, new TextEncoder().encode(value));
|
|
53324
|
+
return btoa(String.fromCharCode(...new Uint8Array(sig)));
|
|
53325
|
+
}
|
|
53326
|
+
async function encryptPersonCipher(fields, key) {
|
|
53327
|
+
const cipher = await encryptField(JSON.stringify(fields), key);
|
|
53328
|
+
const searchHash = await hmacWithKey(fields.name.toLowerCase().trim().replace(/\s+/g, " "), key);
|
|
53329
|
+
return { cipher, searchHash };
|
|
53330
|
+
}
|
|
53331
|
+
async function decryptPersonCipher(cipher, key) {
|
|
53332
|
+
const json2 = await decryptField(cipher, key);
|
|
53333
|
+
return JSON.parse(json2);
|
|
53334
|
+
}
|
|
53321
53335
|
async function encryptObjectFields(obj, fields, key) {
|
|
53322
53336
|
for (const field of fields) {
|
|
53323
53337
|
const val = obj[field];
|
|
@@ -53375,15 +53389,6 @@ async function decryptPersonCiphers(input2, key) {
|
|
|
53375
53389
|
merge3(data);
|
|
53376
53390
|
return { data, undecrypted };
|
|
53377
53391
|
}
|
|
53378
|
-
var VERIFIER_PLAINTEXT = "paisa-verify-v1";
|
|
53379
|
-
async function checkVerifier(key, encryptedVerifier) {
|
|
53380
|
-
try {
|
|
53381
|
-
const decrypted = await decryptField(encryptedVerifier, key);
|
|
53382
|
-
return decrypted === VERIFIER_PLAINTEXT;
|
|
53383
|
-
} catch {
|
|
53384
|
-
return false;
|
|
53385
|
-
}
|
|
53386
|
-
}
|
|
53387
53392
|
|
|
53388
53393
|
// src/lib/crypto-init.ts
|
|
53389
53394
|
async function initCrypto(client, pin, userId) {
|
|
@@ -54357,7 +54362,7 @@ function alertRuleVariants(client) {
|
|
|
54357
54362
|
type: exports_external.string().describe("Rule type (e.g. budget_threshold, spending_spike)"),
|
|
54358
54363
|
enabled: exports_external.boolean().optional(),
|
|
54359
54364
|
threshold: exports_external.string().regex(/^\d{1,4}(\.\d{1,2})?$/).optional().nullable().describe('Decimal string, e.g. "80.50"')
|
|
54360
|
-
}), ({ type, enabled, threshold }) => client.patch(`/api/alerts/rules/${type}`, {
|
|
54365
|
+
}), ({ type, enabled, threshold }) => client.patch(apiPath`/api/alerts/rules/${type}`, {
|
|
54361
54366
|
...enabled !== undefined ? { enabled } : {},
|
|
54362
54367
|
...threshold !== undefined ? { threshold } : {}
|
|
54363
54368
|
}))
|
|
@@ -54378,14 +54383,14 @@ function alertTools(client) {
|
|
|
54378
54383
|
key: "action",
|
|
54379
54384
|
describe: { id: "Alert UUID", all: "", type: "" },
|
|
54380
54385
|
variants: {
|
|
54381
|
-
dismiss: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.patch(`/api/alerts/${id}/dismiss`)),
|
|
54386
|
+
dismiss: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.patch(apiPath`/api/alerts/${id}/dismiss`)),
|
|
54382
54387
|
read: variant(exports_external.object({
|
|
54383
54388
|
id: exports_external.string().uuid().optional(),
|
|
54384
54389
|
all: exports_external.boolean().optional().describe("read: mark every alert read")
|
|
54385
54390
|
}), async ({ id, all: all2 }) => {
|
|
54386
54391
|
if (!all2 && !id)
|
|
54387
54392
|
throw new Error("Provide an alert id, or all:true");
|
|
54388
|
-
const data = all2 ? await client.post("/api/alerts/read-all") : await client.patch(`/api/alerts/${id}/read`);
|
|
54393
|
+
const data = all2 ? await client.post("/api/alerts/read-all") : await client.patch(apiPath`/api/alerts/${id}/read`);
|
|
54389
54394
|
return data;
|
|
54390
54395
|
}),
|
|
54391
54396
|
list_rules: rules.list,
|
|
@@ -54573,7 +54578,7 @@ async function decryptAnalytics(data, key) {
|
|
|
54573
54578
|
], key);
|
|
54574
54579
|
return undecrypted.length ? { ...decrypted, undecrypted } : decrypted;
|
|
54575
54580
|
}
|
|
54576
|
-
function analyticsTools(client,
|
|
54581
|
+
function analyticsTools(client, crypto4) {
|
|
54577
54582
|
return [
|
|
54578
54583
|
defineTool({
|
|
54579
54584
|
name: "get_analytics",
|
|
@@ -54598,8 +54603,8 @@ function analyticsTools(client, crypto3) {
|
|
|
54598
54603
|
data = await client.get(`/api/analytics/merchants/${params.id}`, params.months ? { months: params.months } : undefined);
|
|
54599
54604
|
break;
|
|
54600
54605
|
}
|
|
54601
|
-
if (
|
|
54602
|
-
data = await decryptAnalytics(data,
|
|
54606
|
+
if (crypto4)
|
|
54607
|
+
data = await decryptAnalytics(data, crypto4.key);
|
|
54603
54608
|
return data;
|
|
54604
54609
|
}
|
|
54605
54610
|
})
|
|
@@ -54657,7 +54662,7 @@ function budgetTools(client) {
|
|
|
54657
54662
|
}
|
|
54658
54663
|
|
|
54659
54664
|
// src/tools/dashboard.ts
|
|
54660
|
-
function dashboardTools(client,
|
|
54665
|
+
function dashboardTools(client, crypto4) {
|
|
54661
54666
|
return [
|
|
54662
54667
|
defineTool({
|
|
54663
54668
|
name: "get_dashboard",
|
|
@@ -54666,8 +54671,8 @@ function dashboardTools(client, crypto3) {
|
|
|
54666
54671
|
output: dashboardOutputSchema,
|
|
54667
54672
|
handler: async (params) => {
|
|
54668
54673
|
const data = await client.get("/api/dashboard", params.months ? { months: params.months } : undefined);
|
|
54669
|
-
if (
|
|
54670
|
-
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.recentTransactions,
|
|
54674
|
+
if (crypto4 && Array.isArray(data?.recentTransactions)) {
|
|
54675
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.recentTransactions, crypto4.key);
|
|
54671
54676
|
data.recentTransactions = decrypted;
|
|
54672
54677
|
if (undecrypted.length)
|
|
54673
54678
|
return { ...data, undecrypted };
|
|
@@ -54682,7 +54687,7 @@ function dashboardTools(client, crypto3) {
|
|
|
54682
54687
|
function debtVariants(client) {
|
|
54683
54688
|
return {
|
|
54684
54689
|
list: variant(exports_external.object({}), () => client.get("/api/debts")),
|
|
54685
|
-
delete: variant(exports_external.object({ id: exports_external.string().uuid() }), ({ id }) => client.delete(`/api/debts/${id}`))
|
|
54690
|
+
delete: variant(exports_external.object({ id: exports_external.string().uuid() }), ({ id }) => client.delete(apiPath`/api/debts/${id}`))
|
|
54686
54691
|
};
|
|
54687
54692
|
}
|
|
54688
54693
|
function debtTools(client) {
|
|
@@ -54713,7 +54718,7 @@ function debtTools(client) {
|
|
|
54713
54718
|
id: exports_external.string(),
|
|
54714
54719
|
settledAmount: exports_external.string().optional().describe("settle: actual amount, if not 0")
|
|
54715
54720
|
}), async ({ id, settledAmount }) => {
|
|
54716
|
-
const data = await client.patch(`/api/debts/${id}`, {
|
|
54721
|
+
const data = await client.patch(apiPath`/api/debts/${id}`, {
|
|
54717
54722
|
isActive: false,
|
|
54718
54723
|
outstandingBalance: settledAmount ?? "0"
|
|
54719
54724
|
});
|
|
@@ -54740,7 +54745,7 @@ function accountVariants(client) {
|
|
|
54740
54745
|
billingDay: exports_external.number().optional(),
|
|
54741
54746
|
color: exports_external.string().optional()
|
|
54742
54747
|
}), async ({ id, ...rest }) => {
|
|
54743
|
-
const data = id ? await client.patch(`/api/accounts/${id}`, rest) : await client.post("/api/accounts", rest);
|
|
54748
|
+
const data = id ? await client.patch(apiPath`/api/accounts/${id}`, rest) : await client.post("/api/accounts", rest);
|
|
54744
54749
|
return data;
|
|
54745
54750
|
})
|
|
54746
54751
|
};
|
|
@@ -54759,10 +54764,10 @@ function categoryVariants(client) {
|
|
|
54759
54764
|
icon: exports_external.string().optional(),
|
|
54760
54765
|
color: exports_external.string().optional()
|
|
54761
54766
|
}), async ({ id, ...rest }) => {
|
|
54762
|
-
const data = id ? await client.patch(`/api/categories/${id}`, rest) : await client.post("/api/categories", rest);
|
|
54767
|
+
const data = id ? await client.patch(apiPath`/api/categories/${id}`, rest) : await client.post("/api/categories", rest);
|
|
54763
54768
|
return data;
|
|
54764
54769
|
}),
|
|
54765
|
-
delete: variant(exports_external.object({ id: exports_external.string().describe("Category UUID") }), ({ id }) => client.delete(`/api/categories/${id}`))
|
|
54770
|
+
delete: variant(exports_external.object({ id: exports_external.string().describe("Category UUID") }), ({ id }) => client.delete(apiPath`/api/categories/${id}`))
|
|
54766
54771
|
};
|
|
54767
54772
|
}
|
|
54768
54773
|
|
|
@@ -54786,13 +54791,13 @@ function goalVariants(client) {
|
|
|
54786
54791
|
isActive: exports_external.boolean().optional(),
|
|
54787
54792
|
notes: exports_external.string().optional()
|
|
54788
54793
|
}), async ({ id, ...body }) => {
|
|
54789
|
-
const data = id ? await client.patch(`/api/goals/insurance/${id}`, body) : await client.post("/api/goals/insurance", body);
|
|
54794
|
+
const data = id ? await client.patch(apiPath`/api/goals/insurance/${id}`, body) : await client.post("/api/goals/insurance", body);
|
|
54790
54795
|
return data;
|
|
54791
54796
|
}),
|
|
54792
|
-
deleteGoal: variant(byId, ({ id }) => client.delete(`/api/goals/${id}`)),
|
|
54793
|
-
deleteEmi: variant(byId, ({ id }) => client.delete(`/api/goals/emis/${id}`)),
|
|
54794
|
-
deleteInsurance: variant(byId, ({ id }) => client.delete(`/api/goals/insurance/${id}`)),
|
|
54795
|
-
deleteSinkingFund: variant(byId, ({ id }) => client.delete(`/api/goals/sinking-funds/${id}`))
|
|
54797
|
+
deleteGoal: variant(byId, ({ id }) => client.delete(apiPath`/api/goals/${id}`)),
|
|
54798
|
+
deleteEmi: variant(byId, ({ id }) => client.delete(apiPath`/api/goals/emis/${id}`)),
|
|
54799
|
+
deleteInsurance: variant(byId, ({ id }) => client.delete(apiPath`/api/goals/insurance/${id}`)),
|
|
54800
|
+
deleteSinkingFund: variant(byId, ({ id }) => client.delete(apiPath`/api/goals/sinking-funds/${id}`))
|
|
54796
54801
|
};
|
|
54797
54802
|
}
|
|
54798
54803
|
function goalListVariants(client) {
|
|
@@ -54806,7 +54811,7 @@ function goalListVariants(client) {
|
|
|
54806
54811
|
emis: collection("emis"),
|
|
54807
54812
|
sinking_funds: collection("sinking_funds"),
|
|
54808
54813
|
insurance: collection("insurance"),
|
|
54809
|
-
goal_contributions: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.get(`/api/goals/${id}/contributions`))
|
|
54814
|
+
goal_contributions: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.get(apiPath`/api/goals/${id}/contributions`))
|
|
54810
54815
|
};
|
|
54811
54816
|
}
|
|
54812
54817
|
function goalTools(client) {
|
|
@@ -54882,7 +54887,7 @@ function goalTools(client) {
|
|
|
54882
54887
|
};
|
|
54883
54888
|
if (!id2)
|
|
54884
54889
|
require2(["name", "targetAmount", "goalType"]);
|
|
54885
|
-
const data2 = id2 ? await client.patch(`/api/goals/${id2}`, body2) : await client.post("/api/goals", body2);
|
|
54890
|
+
const data2 = id2 ? await client.patch(apiPath`/api/goals/${id2}`, body2) : await client.post("/api/goals", body2);
|
|
54886
54891
|
return data2;
|
|
54887
54892
|
}
|
|
54888
54893
|
if (type === "emi") {
|
|
@@ -54924,7 +54929,7 @@ function goalTools(client) {
|
|
|
54924
54929
|
owner,
|
|
54925
54930
|
status
|
|
54926
54931
|
};
|
|
54927
|
-
const data2 = id2 ? await client.patch(`/api/goals/emis/${id2}`, body2) : await client.post("/api/goals/emis", body2);
|
|
54932
|
+
const data2 = id2 ? await client.patch(apiPath`/api/goals/emis/${id2}`, body2) : await client.post("/api/goals/emis", body2);
|
|
54928
54933
|
return data2;
|
|
54929
54934
|
}
|
|
54930
54935
|
const { id, name, targetAmount, targetDate, monthlyContribution, currentAmount } = fields;
|
|
@@ -54937,7 +54942,7 @@ function goalTools(client) {
|
|
|
54937
54942
|
monthlySetAside: monthlyContribution,
|
|
54938
54943
|
currentAmount
|
|
54939
54944
|
};
|
|
54940
|
-
const data = id ? await client.patch(`/api/goals/sinking-funds/${id}`, body) : await client.post("/api/goals/sinking-funds", body);
|
|
54945
|
+
const data = id ? await client.patch(apiPath`/api/goals/sinking-funds/${id}`, body) : await client.post("/api/goals/sinking-funds", body);
|
|
54941
54946
|
return data;
|
|
54942
54947
|
}
|
|
54943
54948
|
}),
|
|
@@ -54950,7 +54955,7 @@ function goalTools(client) {
|
|
|
54950
54955
|
date: exports_external.string().optional().describe("YYYY-MM-DD (default today)"),
|
|
54951
54956
|
notes: exports_external.string().optional()
|
|
54952
54957
|
}),
|
|
54953
|
-
handler: ({ id, ...body }) => client.post(`/api/goals/${id}/contribute`, body)
|
|
54958
|
+
handler: ({ id, ...body }) => client.post(apiPath`/api/goals/${id}/contribute`, body)
|
|
54954
54959
|
})
|
|
54955
54960
|
];
|
|
54956
54961
|
}
|
|
@@ -55061,7 +55066,7 @@ function householdVariants(client) {
|
|
|
55061
55066
|
}), (body) => client.patch("/api/households", body)),
|
|
55062
55067
|
listInvites: variant(exports_external.object({}), () => client.get("/api/households/invites")),
|
|
55063
55068
|
createInvite: variant(exports_external.object({ email: exports_external.string().email() }), ({ email: email3 }) => client.post("/api/households/invites", { email: email3 })),
|
|
55064
|
-
revokeInvite: variant(exports_external.object({ id: exports_external.string().describe("Invite UUID") }), ({ id }) => client.delete(`/api/households/invites/${id}`))
|
|
55069
|
+
revokeInvite: variant(exports_external.object({ id: exports_external.string().describe("Invite UUID") }), ({ id }) => client.delete(apiPath`/api/households/invites/${id}`))
|
|
55065
55070
|
};
|
|
55066
55071
|
}
|
|
55067
55072
|
|
|
@@ -55069,8 +55074,8 @@ function householdVariants(client) {
|
|
|
55069
55074
|
function investmentVariants(client) {
|
|
55070
55075
|
const byId = exports_external.object({ id: exports_external.string().describe("SIP or FD UUID") });
|
|
55071
55076
|
return {
|
|
55072
|
-
deleteSip: variant(byId, ({ id }) => client.delete(`/api/investments/sips/${id}`)),
|
|
55073
|
-
deleteFd: variant(byId, ({ id }) => client.delete(`/api/investments/fds/${id}`))
|
|
55077
|
+
deleteSip: variant(byId, ({ id }) => client.delete(apiPath`/api/investments/sips/${id}`)),
|
|
55078
|
+
deleteFd: variant(byId, ({ id }) => client.delete(apiPath`/api/investments/fds/${id}`))
|
|
55074
55079
|
};
|
|
55075
55080
|
}
|
|
55076
55081
|
function investmentListVariants(client) {
|
|
@@ -55078,7 +55083,7 @@ function investmentListVariants(client) {
|
|
|
55078
55083
|
holdings: variant(exports_external.object({}), () => client.get("/api/investments")),
|
|
55079
55084
|
sips: variant(exports_external.object({}), () => client.get("/api/investments/sips")),
|
|
55080
55085
|
fixed_deposits: variant(exports_external.object({}), () => client.get("/api/investments/fds")),
|
|
55081
|
-
investment_transactions: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.get(`/api/investments/${id}/transactions`))
|
|
55086
|
+
investment_transactions: variant(exports_external.object({ id: exports_external.string() }), ({ id }) => client.get(apiPath`/api/investments/${id}/transactions`))
|
|
55082
55087
|
};
|
|
55083
55088
|
}
|
|
55084
55089
|
function investmentTools(client) {
|
|
@@ -55175,7 +55180,7 @@ function investmentTools(client) {
|
|
|
55175
55180
|
endDate,
|
|
55176
55181
|
platform: id2 ? platform : platform ?? "manual"
|
|
55177
55182
|
};
|
|
55178
|
-
const data2 = id2 ? await client.patch(`/api/investments/sips/${id2}`, sipFields) : await client.post("/api/investments/sips", sipFields);
|
|
55183
|
+
const data2 = id2 ? await client.patch(apiPath`/api/investments/sips/${id2}`, sipFields) : await client.post("/api/investments/sips", sipFields);
|
|
55179
55184
|
return data2;
|
|
55180
55185
|
}
|
|
55181
55186
|
const { id, bankName, amount, interestRate, startDate, maturityDate, owner, notes } = fields;
|
|
@@ -55201,7 +55206,7 @@ function investmentTools(client) {
|
|
|
55201
55206
|
owner,
|
|
55202
55207
|
notes
|
|
55203
55208
|
};
|
|
55204
|
-
const data = id ? await client.patch(`/api/investments/fds/${id}`, fdBody) : await client.post("/api/investments/fds", fdBody);
|
|
55209
|
+
const data = id ? await client.patch(apiPath`/api/investments/fds/${id}`, fdBody) : await client.post("/api/investments/fds", fdBody);
|
|
55205
55210
|
return data;
|
|
55206
55211
|
}
|
|
55207
55212
|
}),
|
|
@@ -55231,13 +55236,13 @@ async function categorySlugToId(client) {
|
|
|
55231
55236
|
}
|
|
55232
55237
|
return map2;
|
|
55233
55238
|
}
|
|
55234
|
-
function merchantVariants(client,
|
|
55239
|
+
function merchantVariants(client, crypto4) {
|
|
55235
55240
|
return {
|
|
55236
55241
|
list: variant(exports_external.object({ rawId: exports_external.string().optional().describe("merchants: find one by UPI ID or name") }), async ({ rawId }) => {
|
|
55237
55242
|
const data = await client.get("/api/merchants");
|
|
55238
55243
|
let undecrypted = [];
|
|
55239
|
-
if (
|
|
55240
|
-
const dec = await decryptMerchantFields(data.data,
|
|
55244
|
+
if (crypto4 && data.data) {
|
|
55245
|
+
const dec = await decryptMerchantFields(data.data, crypto4.key);
|
|
55241
55246
|
data.data = dec.data;
|
|
55242
55247
|
undecrypted = dec.undecrypted;
|
|
55243
55248
|
}
|
|
@@ -55265,7 +55270,7 @@ function merchantVariants(client, crypto3) {
|
|
|
55265
55270
|
}
|
|
55266
55271
|
payload.categoryId = categoryId;
|
|
55267
55272
|
}
|
|
55268
|
-
const data = id ? await client.patch(`/api/merchants/${id}`, payload) : await client.post("/api/merchants", payload);
|
|
55273
|
+
const data = id ? await client.patch(apiPath`/api/merchants/${id}`, payload) : await client.post("/api/merchants", payload);
|
|
55269
55274
|
return data;
|
|
55270
55275
|
}),
|
|
55271
55276
|
delete: variant(exports_external.object({
|
|
@@ -55275,7 +55280,7 @@ function merchantVariants(client, crypto3) {
|
|
|
55275
55280
|
if (!id && (!ids || ids.length === 0)) {
|
|
55276
55281
|
throw new Error("Provide either id or ids");
|
|
55277
55282
|
}
|
|
55278
|
-
const data = ids ? await client.post("/api/merchants/bulk-delete", { ids }) : await client.delete(`/api/merchants/${id}`);
|
|
55283
|
+
const data = ids ? await client.post("/api/merchants/bulk-delete", { ids }) : await client.delete(apiPath`/api/merchants/${id}`);
|
|
55279
55284
|
return data;
|
|
55280
55285
|
})
|
|
55281
55286
|
};
|
|
@@ -55295,7 +55300,7 @@ function merchantTools(client) {
|
|
|
55295
55300
|
}
|
|
55296
55301
|
|
|
55297
55302
|
// src/tools/persons.ts
|
|
55298
|
-
function personVariants(client,
|
|
55303
|
+
function personVariants(client, crypto4) {
|
|
55299
55304
|
return {
|
|
55300
55305
|
upsert: variant(exports_external.object({
|
|
55301
55306
|
id: exports_external.string().optional().describe("Person UUID — pass to update, omit to create"),
|
|
@@ -55305,13 +55310,13 @@ function personVariants(client, crypto3) {
|
|
|
55305
55310
|
relationship: exports_external.string().optional(),
|
|
55306
55311
|
notes: exports_external.string().optional()
|
|
55307
55312
|
}), async ({ id, ...updates }) => {
|
|
55308
|
-
if (
|
|
55313
|
+
if (crypto4) {
|
|
55309
55314
|
if (id) {
|
|
55310
|
-
const existing = await client.get(`/api/persons/${id}`);
|
|
55315
|
+
const existing = await client.get(apiPath`/api/persons/${id}`);
|
|
55311
55316
|
const personData = existing.data;
|
|
55312
55317
|
let current;
|
|
55313
55318
|
if (personData.cipher) {
|
|
55314
|
-
current = await decryptPersonCipher(personData.cipher,
|
|
55319
|
+
current = await decryptPersonCipher(personData.cipher, crypto4.key);
|
|
55315
55320
|
} else {
|
|
55316
55321
|
current = {
|
|
55317
55322
|
name: personData.name,
|
|
@@ -55328,8 +55333,8 @@ function personVariants(client, crypto3) {
|
|
|
55328
55333
|
relationship: updates.relationship ?? current.relationship ?? null,
|
|
55329
55334
|
notes: updates.notes ?? current.notes ?? null
|
|
55330
55335
|
};
|
|
55331
|
-
const payload2 = await encryptPersonCipher(merged,
|
|
55332
|
-
const data3 = await client.patch(`/api/persons/${id}`, payload2);
|
|
55336
|
+
const payload2 = await encryptPersonCipher(merged, crypto4.key);
|
|
55337
|
+
const data3 = await client.patch(apiPath`/api/persons/${id}`, payload2);
|
|
55333
55338
|
return data3;
|
|
55334
55339
|
}
|
|
55335
55340
|
if (!updates.name)
|
|
@@ -55341,20 +55346,20 @@ function personVariants(client, crypto3) {
|
|
|
55341
55346
|
relationship: updates.relationship ?? null,
|
|
55342
55347
|
notes: updates.notes ?? null
|
|
55343
55348
|
};
|
|
55344
|
-
const payload = await encryptPersonCipher(fields,
|
|
55349
|
+
const payload = await encryptPersonCipher(fields, crypto4.key);
|
|
55345
55350
|
const data2 = await client.post("/api/persons", payload);
|
|
55346
55351
|
return data2;
|
|
55347
55352
|
}
|
|
55348
|
-
const data = id ? await client.patch(`/api/persons/${id}`, updates) : await client.post("/api/persons", updates);
|
|
55353
|
+
const data = id ? await client.patch(apiPath`/api/persons/${id}`, updates) : await client.post("/api/persons", updates);
|
|
55349
55354
|
return data;
|
|
55350
55355
|
}),
|
|
55351
55356
|
list: variant(exports_external.object({
|
|
55352
55357
|
id: exports_external.string().optional().describe("persons: one person's UUID; omit to list all")
|
|
55353
55358
|
}), async ({ id }) => {
|
|
55354
55359
|
if (id) {
|
|
55355
|
-
const data2 = await client.get(`/api/persons/${id}`);
|
|
55356
|
-
if (
|
|
55357
|
-
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data2.data,
|
|
55360
|
+
const data2 = await client.get(apiPath`/api/persons/${id}`);
|
|
55361
|
+
if (crypto4 && data2.data.cipher) {
|
|
55362
|
+
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data2.data, crypto4.key);
|
|
55358
55363
|
data2.data = decrypted;
|
|
55359
55364
|
if (undecrypted.length)
|
|
55360
55365
|
return { ...data2, undecrypted };
|
|
@@ -55362,15 +55367,15 @@ function personVariants(client, crypto3) {
|
|
|
55362
55367
|
return data2;
|
|
55363
55368
|
}
|
|
55364
55369
|
const data = await client.get("/api/persons");
|
|
55365
|
-
if (
|
|
55366
|
-
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data.data,
|
|
55370
|
+
if (crypto4 && data.data) {
|
|
55371
|
+
const { data: decrypted, undecrypted } = await decryptPersonCiphers(data.data, crypto4.key);
|
|
55367
55372
|
data.data = decrypted;
|
|
55368
55373
|
if (undecrypted.length)
|
|
55369
55374
|
return { ...data, undecrypted };
|
|
55370
55375
|
}
|
|
55371
55376
|
return data;
|
|
55372
55377
|
}),
|
|
55373
|
-
delete: variant(exports_external.object({ id: exports_external.string().describe("Person UUID") }), ({ id }) => client.delete(`/api/persons/${id}`))
|
|
55378
|
+
delete: variant(exports_external.object({ id: exports_external.string().describe("Person UUID") }), ({ id }) => client.delete(apiPath`/api/persons/${id}`))
|
|
55374
55379
|
};
|
|
55375
55380
|
}
|
|
55376
55381
|
|
|
@@ -55501,11 +55506,11 @@ function reportTools(client) {
|
|
|
55501
55506
|
}
|
|
55502
55507
|
|
|
55503
55508
|
// src/tools/entities.ts
|
|
55504
|
-
function entityTools(client,
|
|
55509
|
+
function entityTools(client, crypto4) {
|
|
55505
55510
|
const category = categoryVariants(client);
|
|
55506
55511
|
const account = accountVariants(client);
|
|
55507
|
-
const person = personVariants(client,
|
|
55508
|
-
const merchant = merchantVariants(client,
|
|
55512
|
+
const person = personVariants(client, crypto4);
|
|
55513
|
+
const merchant = merchantVariants(client, crypto4);
|
|
55509
55514
|
const debt = debtVariants(client);
|
|
55510
55515
|
const household = householdVariants(client);
|
|
55511
55516
|
const goal = goalVariants(client);
|
|
@@ -59154,10 +59159,10 @@ function toTxnRow(r2) {
|
|
|
59154
59159
|
isDuplicate: !!r2.isDuplicate
|
|
59155
59160
|
};
|
|
59156
59161
|
}
|
|
59157
|
-
async function fetchAllRows(client,
|
|
59158
|
-
return (await fetchAllRowsPaged(client,
|
|
59162
|
+
async function fetchAllRows(client, crypto4, params = {}, maxPages = 100) {
|
|
59163
|
+
return (await fetchAllRowsPaged(client, crypto4, params, maxPages)).rows;
|
|
59159
59164
|
}
|
|
59160
|
-
async function fetchAllRowsPaged(client,
|
|
59165
|
+
async function fetchAllRowsPaged(client, crypto4, params = {}, maxPages = 100) {
|
|
59161
59166
|
const out = [];
|
|
59162
59167
|
let cursor;
|
|
59163
59168
|
let truncated = false;
|
|
@@ -59167,7 +59172,7 @@ async function fetchAllRowsPaged(client, crypto3, params = {}, maxPages = 100) {
|
|
|
59167
59172
|
q2.cursor = cursor;
|
|
59168
59173
|
const res = await client.get("/api/transactions", q2);
|
|
59169
59174
|
const batch0 = res.data ?? [];
|
|
59170
|
-
const batch =
|
|
59175
|
+
const batch = crypto4 ? (await decryptTransactionFields(batch0, crypto4.key)).data : batch0;
|
|
59171
59176
|
out.push(...batch.map(toTxnRow));
|
|
59172
59177
|
if (!res.hasMore || !res.nextCursor || batch.length === 0 || res.nextCursor === cursor)
|
|
59173
59178
|
break;
|
|
@@ -59216,14 +59221,14 @@ function normalizePersonName(name) {
|
|
|
59216
59221
|
function normalizeUpiHandle(handle) {
|
|
59217
59222
|
return handle.toLowerCase().trim().split("@")[0];
|
|
59218
59223
|
}
|
|
59219
|
-
async function loadDecryptedPersons(client,
|
|
59224
|
+
async function loadDecryptedPersons(client, crypto4) {
|
|
59220
59225
|
const res = await client.get("/api/persons");
|
|
59221
59226
|
const persons = [];
|
|
59222
59227
|
for (const p2 of res.data ?? []) {
|
|
59223
59228
|
let name = p2.name ?? "";
|
|
59224
|
-
if (
|
|
59229
|
+
if (crypto4 && p2.cipher) {
|
|
59225
59230
|
try {
|
|
59226
|
-
name = (await decryptPersonCipher(p2.cipher,
|
|
59231
|
+
name = (await decryptPersonCipher(p2.cipher, crypto4.key)).name;
|
|
59227
59232
|
} catch {}
|
|
59228
59233
|
}
|
|
59229
59234
|
if (name)
|
|
@@ -59264,8 +59269,8 @@ function isPersonLikeNarration(description) {
|
|
|
59264
59269
|
const { name, paymentMethod } = parseNarration(description);
|
|
59265
59270
|
return classifyEntity({ paymentMethod, extractedName: name }) !== "merchant";
|
|
59266
59271
|
}
|
|
59267
|
-
async function backfillPersons(client,
|
|
59268
|
-
const existing = await loadDecryptedPersons(client,
|
|
59272
|
+
async function backfillPersons(client, crypto4, opts = {}) {
|
|
59273
|
+
const existing = await loadDecryptedPersons(client, crypto4);
|
|
59269
59274
|
const personIdByNorm = new Map;
|
|
59270
59275
|
const personIdByHandle = new Map;
|
|
59271
59276
|
for (const p2 of existing) {
|
|
@@ -59273,7 +59278,7 @@ async function backfillPersons(client, crypto3, opts = {}) {
|
|
|
59273
59278
|
for (const h2 of p2.upiHandles)
|
|
59274
59279
|
personIdByHandle.set(normalizeUpiHandle(h2), p2.id);
|
|
59275
59280
|
}
|
|
59276
|
-
const { rows, truncated } = await fetchAllRowsPaged(client,
|
|
59281
|
+
const { rows, truncated } = await fetchAllRowsPaged(client, crypto4, { unresolved: "true" });
|
|
59277
59282
|
const candidates = rows.filter((r2) => !r2.merchantId && !r2.personId && !r2.isTransfer && !r2.isIgnored);
|
|
59278
59283
|
const directLinks = [];
|
|
59279
59284
|
const groups = new Map;
|
|
@@ -59365,7 +59370,7 @@ async function backfillPersons(client, crypto3, opts = {}) {
|
|
|
59365
59370
|
relationship: null,
|
|
59366
59371
|
notes: null
|
|
59367
59372
|
};
|
|
59368
|
-
return
|
|
59373
|
+
return crypto4 ? await encryptPersonCipher(fields, crypto4.key) : { name: displayName, upiHandles, phoneNumbers: [], relationship: null, notes: null };
|
|
59369
59374
|
}));
|
|
59370
59375
|
const res = await client.post("/api/persons/bulk", {
|
|
59371
59376
|
persons: bodies
|
|
@@ -59500,20 +59505,20 @@ function groupRows(rows) {
|
|
|
59500
59505
|
function isCategorizable(r2) {
|
|
59501
59506
|
return !r2.categoryId && !r2.isTransfer && !r2.isIgnored && !r2.isDuplicate;
|
|
59502
59507
|
}
|
|
59503
|
-
async function fetchUncategorized(client,
|
|
59508
|
+
async function fetchUncategorized(client, crypto4, range = {}) {
|
|
59504
59509
|
const params = { uncategorized: "true" };
|
|
59505
59510
|
if (range.startDate)
|
|
59506
59511
|
params.startDate = range.startDate;
|
|
59507
59512
|
if (range.endDate)
|
|
59508
59513
|
params.endDate = range.endDate;
|
|
59509
|
-
return (await fetchAllRows(client,
|
|
59514
|
+
return (await fetchAllRows(client, crypto4, params)).filter(isCategorizable);
|
|
59510
59515
|
}
|
|
59511
59516
|
var MERCHANT_CREATE_CONCURRENCY = 5;
|
|
59512
59517
|
var titleCase = (s2) => s2.replace(/\b[a-z]/g, (c2) => c2.toUpperCase());
|
|
59513
|
-
async function applyGroupAssignments(client,
|
|
59518
|
+
async function applyGroupAssignments(client, crypto4, assignments, opts = {}) {
|
|
59514
59519
|
const catIndex = await loadCategoryIndex(client);
|
|
59515
59520
|
const resolved = assignments.map((a2) => ({ a: a2, cat: requireCategory(catIndex, a2.categorySlug) }));
|
|
59516
|
-
const groups = groupRows(await fetchUncategorized(client,
|
|
59521
|
+
const groups = groupRows(await fetchUncategorized(client, crypto4, opts));
|
|
59517
59522
|
const result = { applied: [], notFound: [], rulesSaved: 0, unlearnable: [] };
|
|
59518
59523
|
const plan = [];
|
|
59519
59524
|
const claimed = new Set;
|
|
@@ -59568,7 +59573,7 @@ async function applyGroupAssignments(client, crypto3, assignments, opts = {}) {
|
|
|
59568
59573
|
const { group, learn, confirmMerchant } = p2;
|
|
59569
59574
|
if (!learn || group.pattern === UNPARSED) {
|
|
59570
59575
|
directPlans.push({ p: p2, reason: learn ? UNPARSED : undefined });
|
|
59571
|
-
} else if (
|
|
59576
|
+
} else if (crypto4 && !confirmMerchant && group.rows.some((r2) => isPersonLikeNarration(r2.description))) {
|
|
59572
59577
|
directPlans.push({ p: p2, reason: `${group.pattern} (private mode: person-like)` });
|
|
59573
59578
|
} else if (taught.has(group.pattern) && taught.get(group.pattern) !== p2.categoryId) {
|
|
59574
59579
|
directPlans.push({ p: p2, reason: `${group.pattern} (conflicting category for same pattern)` });
|
|
@@ -59666,12 +59671,12 @@ function flagBatchDuplicates(txns) {
|
|
|
59666
59671
|
return false;
|
|
59667
59672
|
});
|
|
59668
59673
|
}
|
|
59669
|
-
async function importTransactions(client,
|
|
59674
|
+
async function importTransactions(client, crypto4, opts) {
|
|
59670
59675
|
let txns = opts.txns;
|
|
59671
59676
|
let duplicatesSkipped = 0;
|
|
59672
59677
|
if (txns.length > 0) {
|
|
59673
59678
|
const dates = txns.map((t2) => t2.date).sort();
|
|
59674
|
-
const existing = await fetchAllRows(client,
|
|
59679
|
+
const existing = await fetchAllRows(client, crypto4, {
|
|
59675
59680
|
startDate: dates[0],
|
|
59676
59681
|
endDate: dates[dates.length - 1]
|
|
59677
59682
|
});
|
|
@@ -59687,8 +59692,8 @@ async function importTransactions(client, crypto3, opts) {
|
|
|
59687
59692
|
const base = { ...t2, isDuplicate: dupFlags[i2] };
|
|
59688
59693
|
return enrichedData ? { ...base, enrichedData } : base;
|
|
59689
59694
|
});
|
|
59690
|
-
if (
|
|
59691
|
-
await encryptTransactionFields(rows,
|
|
59695
|
+
if (crypto4)
|
|
59696
|
+
await encryptTransactionFields(rows, crypto4.key);
|
|
59692
59697
|
const CHUNK = 200;
|
|
59693
59698
|
let imported = 0;
|
|
59694
59699
|
for (let i2 = 0;i2 < rows.length; i2 += CHUNK) {
|
|
@@ -59703,19 +59708,19 @@ async function importTransactions(client, crypto3, opts) {
|
|
|
59703
59708
|
}
|
|
59704
59709
|
return { imported, duplicatesSkipped, duplicatesFlagged };
|
|
59705
59710
|
}
|
|
59706
|
-
async function runRescan(client,
|
|
59711
|
+
async function runRescan(client, crypto4) {
|
|
59707
59712
|
let bag = structuredClone(EMPTY_BAG);
|
|
59708
59713
|
try {
|
|
59709
59714
|
bag = (await loadBag(client)).bag;
|
|
59710
59715
|
} catch {}
|
|
59711
59716
|
const merchantsRes = await client.get("/api/merchants");
|
|
59712
59717
|
const allMerchants0 = merchantsRes.data ?? [];
|
|
59713
|
-
const allMerchants =
|
|
59718
|
+
const allMerchants = crypto4 ? (await decryptMerchantFields(allMerchants0, crypto4.key)).data : allMerchants0;
|
|
59714
59719
|
const globalMerchants = allMerchants.filter((m2) => !m2.householdId && m2.cleanName).map((m2) => ({ id: m2.id, name: m2.cleanName }));
|
|
59715
59720
|
const localMerchants = allMerchants.filter((m2) => m2.householdId && m2.cleanName).map((m2) => ({ id: m2.id, name: m2.cleanName }));
|
|
59716
59721
|
const merchantCategoryById = new Map(allMerchants.filter((m2) => m2.categoryId).map((m2) => [m2.id, m2.categoryId]));
|
|
59717
|
-
const persons = await loadDecryptedPersons(client,
|
|
59718
|
-
const allRows = await fetchAllRows(client,
|
|
59722
|
+
const persons = await loadDecryptedPersons(client, crypto4);
|
|
59723
|
+
const allRows = await fetchAllRows(client, crypto4, { unresolved: "true" });
|
|
59719
59724
|
const categoryByTxn = new Map(allRows.map((r2) => [r2.id, r2.categoryId]));
|
|
59720
59725
|
const plan = autoCategorizeFromDescriptions({
|
|
59721
59726
|
rows: allRows,
|
|
@@ -59724,8 +59729,17 @@ async function runRescan(client, crypto3) {
|
|
|
59724
59729
|
localMerchants,
|
|
59725
59730
|
persons
|
|
59726
59731
|
});
|
|
59732
|
+
const knownMerchants = new Set([
|
|
59733
|
+
...allMerchants.map((m2) => m2.id),
|
|
59734
|
+
...allRows.flatMap((r2) => r2.merchantId ? [r2.merchantId] : [])
|
|
59735
|
+
]);
|
|
59736
|
+
const knownPersons = new Set([
|
|
59737
|
+
...persons.map((p2) => p2.id),
|
|
59738
|
+
...allRows.flatMap((r2) => r2.personId ? [r2.personId] : [])
|
|
59739
|
+
]);
|
|
59740
|
+
const live = plan.suggestions.filter((s2) => s2.entity.type === "merchant" ? knownMerchants.has(s2.entity.merchantId) : knownPersons.has(s2.entity.personId));
|
|
59727
59741
|
let categorized = 0;
|
|
59728
|
-
const links =
|
|
59742
|
+
const links = live.flatMap((s2) => {
|
|
59729
59743
|
const categoryId = s2.categoryId ?? (s2.entity.type === "merchant" ? merchantCategoryById.get(s2.entity.merchantId) ?? null : null);
|
|
59730
59744
|
return s2.transactionIds.map((txId) => {
|
|
59731
59745
|
const applyCategory = categoryId && !categoryByTxn.get(txId);
|
|
@@ -59745,7 +59759,7 @@ var TRUNCATED_WARNING = "TRUNCATED: the API capped this result, so it is INCOMPL
|
|
|
59745
59759
|
function withTruncationWarning(data) {
|
|
59746
59760
|
return data.truncated ? { warning: TRUNCATED_WARNING, ...data } : data;
|
|
59747
59761
|
}
|
|
59748
|
-
function transactionTools(client,
|
|
59762
|
+
function transactionTools(client, crypto4) {
|
|
59749
59763
|
return [
|
|
59750
59764
|
defineTool({
|
|
59751
59765
|
name: "get_transactions",
|
|
@@ -59792,7 +59806,7 @@ function transactionTools(client, crypto3) {
|
|
|
59792
59806
|
apiParams.categoryId = requireCategory(await loadCategoryIndex(client), categorySlug).id;
|
|
59793
59807
|
}
|
|
59794
59808
|
if (personName && !apiParams.personId) {
|
|
59795
|
-
const persons = await loadDecryptedPersons(client,
|
|
59809
|
+
const persons = await loadDecryptedPersons(client, crypto4);
|
|
59796
59810
|
const match = resolvePersonByName(persons, personName);
|
|
59797
59811
|
const err = (error62) => ({ error: error62 });
|
|
59798
59812
|
if (!match) {
|
|
@@ -59809,14 +59823,14 @@ function transactionTools(client, crypto3) {
|
|
|
59809
59823
|
const data = await client.get("/api/transactions", Object.fromEntries(Object.entries(apiParams).filter(([, v2]) => v2 !== undefined).map(([k2, v2]) => [k2, String(v2)])));
|
|
59810
59824
|
let rows = data.data ?? [];
|
|
59811
59825
|
let undecrypted = [];
|
|
59812
|
-
if (
|
|
59813
|
-
const dec = await decryptTransactionFields(rows,
|
|
59826
|
+
if (crypto4) {
|
|
59827
|
+
const dec = await decryptTransactionFields(rows, crypto4.key);
|
|
59814
59828
|
rows = dec.data;
|
|
59815
59829
|
undecrypted = dec.undecrypted;
|
|
59816
59830
|
}
|
|
59817
59831
|
const personNames = new Map;
|
|
59818
59832
|
if (rows.some((r2) => r2.personId)) {
|
|
59819
|
-
for (const p2 of await loadDecryptedPersons(client,
|
|
59833
|
+
for (const p2 of await loadDecryptedPersons(client, crypto4))
|
|
59820
59834
|
personNames.set(p2.id, p2.name);
|
|
59821
59835
|
}
|
|
59822
59836
|
if (full) {
|
|
@@ -59847,7 +59861,7 @@ function transactionTools(client, crypto3) {
|
|
|
59847
59861
|
limit: exports_external.number().optional().describe("Max groups (default 40, max 100)")
|
|
59848
59862
|
}),
|
|
59849
59863
|
handler: async ({ startDate, endDate, minTotal, limit }) => {
|
|
59850
|
-
const rows = await fetchUncategorized(client,
|
|
59864
|
+
const rows = await fetchUncategorized(client, crypto4, { startDate, endDate });
|
|
59851
59865
|
const all2 = groupRows(rows);
|
|
59852
59866
|
const shown = all2.filter((g2) => g2.total >= (minTotal ?? 0)).slice(0, Math.min(Math.max(limit ?? 40, 1), 100));
|
|
59853
59867
|
const shownRows = shown.reduce((n2, g2) => n2 + g2.rows.length, 0);
|
|
@@ -59884,7 +59898,7 @@ function transactionTools(client, crypto3) {
|
|
|
59884
59898
|
handler: (args, ctx) => {
|
|
59885
59899
|
const { assignments, startDate, endDate, dryRun } = args;
|
|
59886
59900
|
const { expectedPlanHash } = args;
|
|
59887
|
-
return applyGroupAssignments(client,
|
|
59901
|
+
return applyGroupAssignments(client, crypto4, assignments, {
|
|
59888
59902
|
dryRun,
|
|
59889
59903
|
startDate,
|
|
59890
59904
|
endDate,
|
|
@@ -59897,7 +59911,7 @@ function transactionTools(client, crypto3) {
|
|
|
59897
59911
|
name: "backfill_persons",
|
|
59898
59912
|
description: "Create persons from UPI/IMPS counterparties in unlinked transactions (deduped by name) and link those transactions to them. Idempotent. dryRun previews.",
|
|
59899
59913
|
input: exports_external.object({ dryRun: exports_external.boolean().optional() }),
|
|
59900
|
-
handler: (args, ctx) => backfillPersons(client,
|
|
59914
|
+
handler: (args, ctx) => backfillPersons(client, crypto4, {
|
|
59901
59915
|
onProgress: progressFor(ctx),
|
|
59902
59916
|
dryRun: args.dryRun,
|
|
59903
59917
|
expectedPlanHash: args.expectedPlanHash
|
|
@@ -59919,15 +59933,15 @@ function transactionTools(client, crypto3) {
|
|
|
59919
59933
|
}),
|
|
59920
59934
|
handler: async ({ id, ...updates }) => {
|
|
59921
59935
|
const body = { ...updates };
|
|
59922
|
-
if (
|
|
59923
|
-
body.notes = await encryptField(body.notes,
|
|
59936
|
+
if (crypto4 && body.notes)
|
|
59937
|
+
body.notes = await encryptField(body.notes, crypto4.key);
|
|
59924
59938
|
if (body.categorySlug) {
|
|
59925
59939
|
const cat = requireCategory(await loadCategoryIndex(client), body.categorySlug);
|
|
59926
59940
|
body.categoryId = cat.id;
|
|
59927
59941
|
body.categoryType = cat.type;
|
|
59928
59942
|
delete body.categorySlug;
|
|
59929
59943
|
}
|
|
59930
|
-
const data = await client.patch(`/api/transactions/${id}`, body);
|
|
59944
|
+
const data = await client.patch(apiPath`/api/transactions/${id}`, body);
|
|
59931
59945
|
return data;
|
|
59932
59946
|
}
|
|
59933
59947
|
}),
|
|
@@ -59961,7 +59975,7 @@ function transactionTools(client, crypto3) {
|
|
|
59961
59975
|
throw new Error("ids and resolution are required for action 'resolve'");
|
|
59962
59976
|
}
|
|
59963
59977
|
if (action === "flag") {
|
|
59964
|
-
const data2 = await client.patch(`/api/transactions/${transactionId}`, {
|
|
59978
|
+
const data2 = await client.patch(apiPath`/api/transactions/${transactionId}`, {
|
|
59965
59979
|
isDuplicate: true,
|
|
59966
59980
|
isIgnored: true
|
|
59967
59981
|
});
|
|
@@ -59969,8 +59983,8 @@ function transactionTools(client, crypto3) {
|
|
|
59969
59983
|
}
|
|
59970
59984
|
if (action === "list") {
|
|
59971
59985
|
const data2 = await client.get("/api/transactions/duplicates");
|
|
59972
|
-
if (
|
|
59973
|
-
const { data: decrypted, undecrypted } = await decryptTransactionFields(data2.data,
|
|
59986
|
+
if (crypto4 && data2.data) {
|
|
59987
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data2.data, crypto4.key);
|
|
59974
59988
|
data2.data = decrypted;
|
|
59975
59989
|
return withTruncationWarning(undecrypted.length ? { ...data2, undecrypted } : data2);
|
|
59976
59990
|
}
|
|
@@ -59993,8 +60007,8 @@ function transactionTools(client, crypto3) {
|
|
|
59993
60007
|
}),
|
|
59994
60008
|
handler: async ({ accountId, startDate, endDate }) => {
|
|
59995
60009
|
const data = await client.get("/api/transactions/reconciliation-context", { accountId, startDate, endDate });
|
|
59996
|
-
if (
|
|
59997
|
-
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data,
|
|
60010
|
+
if (crypto4 && data.data) {
|
|
60011
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data, crypto4.key);
|
|
59998
60012
|
data.data = decrypted;
|
|
59999
60013
|
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
60000
60014
|
}
|
|
@@ -60069,7 +60083,7 @@ function transactionTools(client, crypto3) {
|
|
|
60069
60083
|
throw new Error("filters is empty (matches every transaction) — refusing; set confirmDeleteAll only after explicit user confirmation");
|
|
60070
60084
|
}
|
|
60071
60085
|
if (id) {
|
|
60072
|
-
const data2 = await client.delete(`/api/transactions/${id}`);
|
|
60086
|
+
const data2 = await client.delete(apiPath`/api/transactions/${id}`);
|
|
60073
60087
|
return data2;
|
|
60074
60088
|
}
|
|
60075
60089
|
const body = ids ? { ids } : { filters, ...confirmDeleteAll ? { confirmDeleteAll } : {} };
|
|
@@ -60081,7 +60095,7 @@ function transactionTools(client, crypto3) {
|
|
|
60081
60095
|
name: "rescan_transactions",
|
|
60082
60096
|
description: "Apply saved learning rules (merchant aliases, category rules) to uncategorized transactions, like the web app's auto-categorize.",
|
|
60083
60097
|
input: exports_external.object({}),
|
|
60084
|
-
handler: () => runRescan(client,
|
|
60098
|
+
handler: () => runRescan(client, crypto4)
|
|
60085
60099
|
}),
|
|
60086
60100
|
defineTool({
|
|
60087
60101
|
name: "get_settlement_candidates",
|
|
@@ -60089,8 +60103,8 @@ function transactionTools(client, crypto3) {
|
|
|
60089
60103
|
input: exports_external.object({ ccAccountId: exports_external.string().uuid() }),
|
|
60090
60104
|
handler: async ({ ccAccountId }) => {
|
|
60091
60105
|
const data = await client.get("/api/transactions/settlement-candidates", { ccAccountId });
|
|
60092
|
-
if (
|
|
60093
|
-
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data,
|
|
60106
|
+
if (crypto4 && data.data) {
|
|
60107
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.data, crypto4.key);
|
|
60094
60108
|
data.data = decrypted;
|
|
60095
60109
|
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
60096
60110
|
}
|
|
@@ -60107,8 +60121,8 @@ function transactionTools(client, crypto3) {
|
|
|
60107
60121
|
if (!row)
|
|
60108
60122
|
return res;
|
|
60109
60123
|
let undecrypted = [];
|
|
60110
|
-
if (
|
|
60111
|
-
const dec = await decryptTransactionFields([row],
|
|
60124
|
+
if (crypto4) {
|
|
60125
|
+
const dec = await decryptTransactionFields([row], crypto4.key);
|
|
60112
60126
|
row = dec.data[0];
|
|
60113
60127
|
undecrypted = dec.undecrypted;
|
|
60114
60128
|
}
|
|
@@ -60134,7 +60148,7 @@ function transactionTools(client, crypto3) {
|
|
|
60134
60148
|
}
|
|
60135
60149
|
|
|
60136
60150
|
// src/tools/export.ts
|
|
60137
|
-
function exportTools(client,
|
|
60151
|
+
function exportTools(client, crypto4) {
|
|
60138
60152
|
return [
|
|
60139
60153
|
defineTool({
|
|
60140
60154
|
name: "export_transactions",
|
|
@@ -60151,8 +60165,8 @@ function exportTools(client, crypto3) {
|
|
|
60151
60165
|
...Object.fromEntries(Object.entries(params).filter(([, v2]) => v2 !== undefined)),
|
|
60152
60166
|
format: "json"
|
|
60153
60167
|
});
|
|
60154
|
-
if (
|
|
60155
|
-
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.transactions,
|
|
60168
|
+
if (crypto4 && Array.isArray(data?.transactions)) {
|
|
60169
|
+
const { data: decrypted, undecrypted } = await decryptTransactionFields(data.transactions, crypto4.key);
|
|
60156
60170
|
data.transactions = decrypted;
|
|
60157
60171
|
return withTruncationWarning(undecrypted.length ? { ...data, undecrypted } : data);
|
|
60158
60172
|
}
|
|
@@ -60394,28 +60408,28 @@ var DEFAULT_MIN_CONFIDENCE = 0.95;
|
|
|
60394
60408
|
var TIMEOUT_MS = 8000;
|
|
60395
60409
|
var CONCURRENCY = 8;
|
|
60396
60410
|
var MIN_LEARN_PATTERN_LEN = 5;
|
|
60397
|
-
function assertPrivateModeAllowed(
|
|
60398
|
-
if (
|
|
60411
|
+
function assertPrivateModeAllowed(crypto4, env2 = process.env) {
|
|
60412
|
+
if (crypto4 && env2.JEV_ALLOW_PRIVATE_MODE !== "1") {
|
|
60399
60413
|
throw new Error("Jev categorization is disabled in private mode: it would send transaction text to a third party. " + "To opt in for your own account, set JEV_ALLOW_PRIVATE_MODE=1 in the MCP's environment. " + "Otherwise use get_uncategorized_groups + categorize_groups.");
|
|
60400
60414
|
}
|
|
60401
60415
|
}
|
|
60402
|
-
function assertJevAllowed(
|
|
60403
|
-
assertPrivateModeAllowed(
|
|
60416
|
+
function assertJevAllowed(crypto4, env2 = process.env) {
|
|
60417
|
+
assertPrivateModeAllowed(crypto4, env2);
|
|
60404
60418
|
const key = env2.JEV_API_KEY;
|
|
60405
60419
|
if (!key)
|
|
60406
60420
|
throw new Error("JEV_API_KEY is not set — Jev categorization is off.");
|
|
60407
60421
|
return key;
|
|
60408
60422
|
}
|
|
60409
|
-
function jevAllowSensitive(
|
|
60410
|
-
return
|
|
60423
|
+
function jevAllowSensitive(crypto4, env2) {
|
|
60424
|
+
return crypto4 === undefined || env2.JEV_ALLOW_PRIVATE_MODE === "1";
|
|
60411
60425
|
}
|
|
60412
|
-
function makeJev(apiKey,
|
|
60426
|
+
function makeJev(apiKey, crypto4, env2 = process.env, fetchImpl) {
|
|
60413
60427
|
return createJev({
|
|
60414
60428
|
apiKey,
|
|
60415
60429
|
model: JEV_MODEL,
|
|
60416
60430
|
minConfidence: DEFAULT_MIN_CONFIDENCE,
|
|
60417
60431
|
timeoutMs: TIMEOUT_MS,
|
|
60418
|
-
allowSensitive: jevAllowSensitive(
|
|
60432
|
+
allowSensitive: jevAllowSensitive(crypto4, env2),
|
|
60419
60433
|
...fetchImpl ? { fetch: fetchImpl } : {}
|
|
60420
60434
|
});
|
|
60421
60435
|
}
|
|
@@ -60435,10 +60449,10 @@ function groupState(type, sample) {
|
|
|
60435
60449
|
const dir = type === "credit" ? "Money received" : "Money paid out";
|
|
60436
60450
|
return `${dir}. Bank narration: "${sample.slice(0, 80)}"`;
|
|
60437
60451
|
}
|
|
60438
|
-
async function jevCategorize(client,
|
|
60439
|
-
assertPrivateModeAllowed(
|
|
60452
|
+
async function jevCategorize(client, crypto4, jev, opts = {}) {
|
|
60453
|
+
assertPrivateModeAllowed(crypto4, opts.env);
|
|
60440
60454
|
const index = await loadCategoryIndex(client);
|
|
60441
|
-
const rows = await fetchUncategorized(client,
|
|
60455
|
+
const rows = await fetchUncategorized(client, crypto4, opts);
|
|
60442
60456
|
const groups = groupRows(rows);
|
|
60443
60457
|
const unparsed = groups.filter((g2) => g2.pattern === UNPARSED).length;
|
|
60444
60458
|
const candidates = groups.filter((g2) => g2.pattern !== UNPARSED);
|
|
@@ -60446,7 +60460,7 @@ async function jevCategorize(client, crypto3, jev, opts = {}) {
|
|
|
60446
60460
|
const suggestions = await mapLimit(candidates, CONCURRENCY, async (g2) => {
|
|
60447
60461
|
const options = optionsFor(g2.type, index);
|
|
60448
60462
|
const sample = g2.rows[0].description;
|
|
60449
|
-
const text =
|
|
60463
|
+
const text = crypto4 ? g2.pattern : sample;
|
|
60450
60464
|
const d2 = await jev.choice({
|
|
60451
60465
|
question: "Which spending category best fits this bank transaction?",
|
|
60452
60466
|
options,
|
|
@@ -60488,7 +60502,7 @@ async function jevCategorize(client, crypto3, jev, opts = {}) {
|
|
|
60488
60502
|
}
|
|
60489
60503
|
}
|
|
60490
60504
|
review.sort((a2, b2) => b2.total - a2.total);
|
|
60491
|
-
const applied = await applyGroupAssignments(client,
|
|
60505
|
+
const applied = await applyGroupAssignments(client, crypto4, accepted.map(({ confidence: _c, ...a2 }) => a2), { dryRun: opts.dryRun, startDate: opts.startDate, endDate: opts.endDate });
|
|
60492
60506
|
const conf = new Map(accepted.map((a2) => [`${a2.pattern}|${a2.type}`, a2.confidence]));
|
|
60493
60507
|
return {
|
|
60494
60508
|
dryRun: !!opts.dryRun,
|
|
@@ -60505,7 +60519,7 @@ async function jevCategorize(client, crypto3, jev, opts = {}) {
|
|
|
60505
60519
|
}
|
|
60506
60520
|
|
|
60507
60521
|
// src/tools/jev.ts
|
|
60508
|
-
function jevTools(client,
|
|
60522
|
+
function jevTools(client, crypto4) {
|
|
60509
60523
|
return [
|
|
60510
60524
|
defineTool({
|
|
60511
60525
|
name: "auto_categorize_jev",
|
|
@@ -60517,9 +60531,9 @@ function jevTools(client, crypto3) {
|
|
|
60517
60531
|
dryRun: exports_external.boolean().optional()
|
|
60518
60532
|
}),
|
|
60519
60533
|
handler: async ({ startDate, endDate, minConfidence, dryRun }) => {
|
|
60520
|
-
const key = assertJevAllowed(
|
|
60521
|
-
const jev = makeJev(key,
|
|
60522
|
-
const result = await jevCategorize(client,
|
|
60534
|
+
const key = assertJevAllowed(crypto4);
|
|
60535
|
+
const jev = makeJev(key, crypto4);
|
|
60536
|
+
const result = await jevCategorize(client, crypto4, jev, {
|
|
60523
60537
|
startDate,
|
|
60524
60538
|
endDate,
|
|
60525
60539
|
minConfidence,
|
|
@@ -60543,12 +60557,12 @@ function profileVariants(client) {
|
|
|
60543
60557
|
function settingsTools(client) {
|
|
60544
60558
|
const profile = profileVariants(client);
|
|
60545
60559
|
const household = householdVariants(client);
|
|
60546
|
-
const
|
|
60560
|
+
const crypto4 = authCryptoVariants(client);
|
|
60547
60561
|
const get = unionTool({
|
|
60548
60562
|
name: "get_settings",
|
|
60549
60563
|
description: "Read settings. profile: your name, email, owner. household: name, currency, locale, owner labels, members. encryption: mode (standard/private) and whether a PIN verifier / recovery key is set.",
|
|
60550
60564
|
key: "section",
|
|
60551
|
-
variants: { profile: profile.get, household: household.get, encryption:
|
|
60565
|
+
variants: { profile: profile.get, household: household.get, encryption: crypto4.status }
|
|
60552
60566
|
});
|
|
60553
60567
|
const update = unionTool({
|
|
60554
60568
|
name: "update_settings",
|
|
@@ -60630,7 +60644,7 @@ async function fetchReconciliationContext(client, accountId, start, end, budget
|
|
|
60630
60644
|
}
|
|
60631
60645
|
var sum2 = (rows) => Math.round(rows.reduce((n2, r2) => n2 + r2.amount, 0));
|
|
60632
60646
|
async function runStatementImport(deps, args) {
|
|
60633
|
-
const { client, crypto:
|
|
60647
|
+
const { client, crypto: crypto4 } = deps;
|
|
60634
60648
|
const accounts = (await client.get("/api/accounts")).data ?? [];
|
|
60635
60649
|
const account = resolveAccount(accounts, args.account);
|
|
60636
60650
|
const format = pickFormat(account, args.format);
|
|
@@ -60649,7 +60663,7 @@ async function runStatementImport(deps, args) {
|
|
|
60649
60663
|
}
|
|
60650
60664
|
const dates = txns.map((t2) => t2.date).sort();
|
|
60651
60665
|
const existing0 = await fetchReconciliationContext(client, account.id, dates[0], dates[dates.length - 1]);
|
|
60652
|
-
const existing =
|
|
60666
|
+
const existing = crypto4 ? (await decryptTransactionFields(existing0, crypto4.key)).data : existing0;
|
|
60653
60667
|
const present = existing.map((r2) => ({ ...r2, isDuplicate: false, isIgnored: false }));
|
|
60654
60668
|
const result = reconcile(present, { ...statement, transactions: txns });
|
|
60655
60669
|
const fresh = result.unmatched;
|
|
@@ -60690,7 +60704,7 @@ async function runStatementImport(deps, args) {
|
|
|
60690
60704
|
if (fresh.length === 0)
|
|
60691
60705
|
return { ...summary, dryRun: false, imported: 0 };
|
|
60692
60706
|
const savings = account.type !== "credit_card";
|
|
60693
|
-
const imported = await importTransactions(client,
|
|
60707
|
+
const imported = await importTransactions(client, crypto4, {
|
|
60694
60708
|
onProgress: deps.onProgress,
|
|
60695
60709
|
accountId: account.id,
|
|
60696
60710
|
source: savings ? "bank_statement" : "cc_statement",
|
|
@@ -60703,7 +60717,7 @@ async function runStatementImport(deps, args) {
|
|
|
60703
60717
|
referenceNumber: t2.referenceNumber ?? undefined
|
|
60704
60718
|
}))
|
|
60705
60719
|
});
|
|
60706
|
-
const rescan = await runRescan(client,
|
|
60720
|
+
const rescan = await runRescan(client, crypto4);
|
|
60707
60721
|
return { ...summary, dryRun: false, ...imported, rescan };
|
|
60708
60722
|
}
|
|
60709
60723
|
|
|
@@ -60739,16 +60753,16 @@ var statementSource = exports_external.enum([
|
|
|
60739
60753
|
"ai_import"
|
|
60740
60754
|
]);
|
|
60741
60755
|
var granularity = exports_external.number().int().min(1).max(5).describe("1=bank, 2=CC, 3=manual, 4=app export, 5=telegram/AI");
|
|
60742
|
-
function statementImportTools(client,
|
|
60756
|
+
function statementImportTools(client, crypto4) {
|
|
60743
60757
|
const pdf = (confirm2) => variant(pdfInput, (args, ctx) => runStatementImport({
|
|
60744
60758
|
client,
|
|
60745
|
-
crypto:
|
|
60759
|
+
crypto: crypto4,
|
|
60746
60760
|
readFile: readFileAsArrayBuffer,
|
|
60747
60761
|
parsers: realParsers,
|
|
60748
60762
|
onProgress: progressFor(ctx)
|
|
60749
60763
|
}, confirm2 ? { ...args, confirm: true } : args));
|
|
60750
60764
|
const csvParse = variant(exports_external.object({ filePath: exports_external.string() }), async ({ filePath }) => {
|
|
60751
|
-
if (
|
|
60765
|
+
if (crypto4)
|
|
60752
60766
|
return CSV_PRIVATE_MODE_ERROR;
|
|
60753
60767
|
const buf = await readFile2(filePath);
|
|
60754
60768
|
const form = new FormData;
|
|
@@ -60783,7 +60797,7 @@ function statementImportTools(client, crypto3) {
|
|
|
60783
60797
|
skipDuplicates: exports_external.boolean().optional(),
|
|
60784
60798
|
force: exports_external.boolean().optional()
|
|
60785
60799
|
}), async ({ filePath, mapping, accountId, owner, skipDuplicates, force }) => {
|
|
60786
|
-
if (
|
|
60800
|
+
if (crypto4)
|
|
60787
60801
|
return CSV_PRIVATE_MODE_ERROR;
|
|
60788
60802
|
const csvText = await readFile2(filePath, "utf8");
|
|
60789
60803
|
const data = await client.post("/api/transactions/import/confirm", {
|
|
@@ -60808,14 +60822,14 @@ function statementImportTools(client, crypto3) {
|
|
|
60808
60822
|
referenceNumber: exports_external.string().optional()
|
|
60809
60823
|
}))
|
|
60810
60824
|
}), async ({ accountId, source, granularity: granularity2, transactions: txns }, ctx) => {
|
|
60811
|
-
const data = await importTransactions(client,
|
|
60825
|
+
const data = await importTransactions(client, crypto4, {
|
|
60812
60826
|
onProgress: progressFor(ctx),
|
|
60813
60827
|
accountId,
|
|
60814
60828
|
source,
|
|
60815
60829
|
granularity: granularity2,
|
|
60816
60830
|
txns
|
|
60817
60831
|
});
|
|
60818
|
-
const rescan = await runRescan(client,
|
|
60832
|
+
const rescan = await runRescan(client, crypto4);
|
|
60819
60833
|
return { import: data, rescan };
|
|
60820
60834
|
}),
|
|
60821
60835
|
json_file: variant(exports_external.object({
|
|
@@ -60839,14 +60853,14 @@ function statementImportTools(client, crypto3) {
|
|
|
60839
60853
|
} catch (e2) {
|
|
60840
60854
|
throw new Error(`Failed to read/parse ${filePath}: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
60841
60855
|
}
|
|
60842
|
-
const data = await importTransactions(client,
|
|
60856
|
+
const data = await importTransactions(client, crypto4, {
|
|
60843
60857
|
onProgress: progressFor(ctx),
|
|
60844
60858
|
accountId,
|
|
60845
60859
|
source,
|
|
60846
60860
|
granularity: granularity2,
|
|
60847
60861
|
txns
|
|
60848
60862
|
});
|
|
60849
|
-
const rescan = await runRescan(client,
|
|
60863
|
+
const rescan = await runRescan(client, crypto4);
|
|
60850
60864
|
return { import: data, count: txns.length, rescan };
|
|
60851
60865
|
})
|
|
60852
60866
|
}
|
|
@@ -61003,7 +61017,7 @@ function registerResources2(server2, tools) {
|
|
|
61003
61017
|
// package.json
|
|
61004
61018
|
var package_default = {
|
|
61005
61019
|
name: "paisa-mcp",
|
|
61006
|
-
version: "0.4.
|
|
61020
|
+
version: "0.4.4",
|
|
61007
61021
|
repository: {
|
|
61008
61022
|
type: "git",
|
|
61009
61023
|
url: "git+https://github.com/nimit9/paisa.git",
|
|
@@ -61033,13 +61047,12 @@ var package_default = {
|
|
|
61033
61047
|
"@nimit9/signet-ai": "^0.1.11",
|
|
61034
61048
|
"@nimit9/signet-lib": "^0.1.15",
|
|
61035
61049
|
"@nimit9/signet-server": "^0.2.7",
|
|
61050
|
+
"@paisa/crypto": "workspace:*",
|
|
61036
61051
|
"@paisa/parsers": "workspace:*",
|
|
61037
61052
|
"@paisa/reconciliation": "workspace:*",
|
|
61038
61053
|
"@paisa/types": "workspace:*",
|
|
61039
|
-
"@scure/bip39": "^2.2.0",
|
|
61040
61054
|
"@types/bun": "^1.3.14",
|
|
61041
61055
|
axios: "^1.16.1",
|
|
61042
|
-
"hash-wasm": "^4.12.0",
|
|
61043
61056
|
typescript: "^7.0.2",
|
|
61044
61057
|
zod: "^4.6.5"
|
|
61045
61058
|
},
|
|
@@ -61059,8 +61072,8 @@ function paisaErrorResult(err) {
|
|
|
61059
61072
|
});
|
|
61060
61073
|
}
|
|
61061
61074
|
var CONFIRM_KEY2 = randomBytes(32);
|
|
61062
|
-
function buildServer(client,
|
|
61063
|
-
const tools = applyAnnotations(REGISTRATIONS.flatMap((group) => group.tools(client,
|
|
61075
|
+
function buildServer(client, crypto4) {
|
|
61076
|
+
const tools = applyAnnotations(REGISTRATIONS.flatMap((group) => group.tools(client, crypto4)).map((t2) => {
|
|
61064
61077
|
const describe3 = CONFIRMED_TOOLS[t2.name];
|
|
61065
61078
|
if (describe3)
|
|
61066
61079
|
return withConfirmation(t2, describe3);
|
|
@@ -61103,5 +61116,5 @@ main().catch((err) => {
|
|
|
61103
61116
|
process.exit(1);
|
|
61104
61117
|
});
|
|
61105
61118
|
|
|
61106
|
-
//# debugId=
|
|
61119
|
+
//# debugId=0BCBA1F2C8CA2E2E64756E2164756E21
|
|
61107
61120
|
//# sourceMappingURL=index.js.map
|