@continuumdao/continuum-node-sdk 1.3.1 → 1.3.3

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.
Files changed (50) hide show
  1. package/dist/core/mpc/mpa-billing-helpers.d.ts +39 -0
  2. package/dist/core/mpc/mpa-billing-helpers.d.ts.map +1 -0
  3. package/dist/core/mpc/mpa-billing-helpers.js +57 -0
  4. package/dist/core/mpc/mpa-billing-helpers.js.map +1 -0
  5. package/dist/core/mpc/mpa-billing-ops.d.ts +2 -11
  6. package/dist/core/mpc/mpa-billing-ops.d.ts.map +1 -1
  7. package/dist/core/mpc/mpa-billing-ops.js +28 -12
  8. package/dist/core/mpc/mpa-billing-ops.js.map +1 -1
  9. package/dist/core/mpc/mpa-fee-status.d.ts +63 -0
  10. package/dist/core/mpc/mpa-fee-status.d.ts.map +1 -0
  11. package/dist/core/mpc/mpa-fee-status.js +431 -0
  12. package/dist/core/mpc/mpa-fee-status.js.map +1 -0
  13. package/dist/core/mpc/mpa-top-up.d.ts +2 -12
  14. package/dist/core/mpc/mpa-top-up.d.ts.map +1 -1
  15. package/dist/core/mpc/mpa-top-up.js +35 -77
  16. package/dist/core/mpc/mpa-top-up.js.map +1 -1
  17. package/dist/core/mpc/schemas.d.ts +20 -0
  18. package/dist/core/mpc/schemas.d.ts.map +1 -1
  19. package/dist/core/mpc/schemas.js +20 -0
  20. package/dist/core/mpc/schemas.js.map +1 -1
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp/index.d.ts +1 -1
  26. package/dist/mcp/index.d.ts.map +1 -1
  27. package/dist/mcp/index.js +1 -1
  28. package/dist/mcp/index.js.map +1 -1
  29. package/dist/mcp/mpc.d.ts.map +1 -1
  30. package/dist/mcp/mpc.js +4 -4
  31. package/dist/mcp/mpc.js.map +1 -1
  32. package/dist/mcp/register.d.ts +2 -2
  33. package/dist/mcp/register.d.ts.map +1 -1
  34. package/dist/mcp/register.js +2 -8
  35. package/dist/mcp/register.js.map +1 -1
  36. package/dist/mcp/resources/mpc.md +8 -8
  37. package/dist/mcp/resources/overview.md +2 -1
  38. package/dist/mcp/resources/technical-indicators.md +4 -2
  39. package/dist/mcp/resources/vpn.md +3 -1
  40. package/dist/mcp/server/http-transport.d.ts +6 -3
  41. package/dist/mcp/server/http-transport.d.ts.map +1 -1
  42. package/dist/mcp/server/http-transport.js +38 -19
  43. package/dist/mcp/server/http-transport.js.map +1 -1
  44. package/dist/mcp/server/index.js +10 -1
  45. package/dist/mcp/server/index.js.map +1 -1
  46. package/dist/mcp/vpn.d.ts +3 -1
  47. package/dist/mcp/vpn.d.ts.map +1 -1
  48. package/dist/mcp/vpn.js +18 -0
  49. package/dist/mcp/vpn.js.map +1 -1
  50. package/package.json +1 -1
@@ -0,0 +1,431 @@
1
+ import { createPublicClient, defineChain, formatUnits, getAddress, http, } from 'viem';
2
+ import { buildManagementQueryPath, managementGet } from '../../api/management-api.js';
3
+ import { KEY_GEN_ADDRESS_KIND_ETHEREUM, MPA_WALLET_CONTRACT_CONFIG, MPA_WALLET_READ_ABI, } from '../../config/mpa-wallet.js';
4
+ import { fetchGlobalNonceByKeyGenId } from '../keygen.js';
5
+ import { computeVpnHostBinding } from '../vpn/vpn-host-binding.js';
6
+ import { mpcAuthEnvelopeData } from './sign-request-utils.js';
7
+ import { canPayKeyGenMonthFromCredit, canPayVpnMonthFromCredit, keyGenPayMonthDisabledReason, vpnPayMonthDisabledReason, } from './mpa-billing-helpers.js';
8
+ const ERC20_SYMBOL_DECIMALS_ABI = [
9
+ {
10
+ inputs: [],
11
+ name: 'symbol',
12
+ outputs: [{ name: '', type: 'string', internalType: 'string' }],
13
+ stateMutability: 'view',
14
+ type: 'function',
15
+ },
16
+ {
17
+ inputs: [],
18
+ name: 'decimals',
19
+ outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }],
20
+ stateMutability: 'view',
21
+ type: 'function',
22
+ },
23
+ ];
24
+ function getMpaPublicClient() {
25
+ const chain = defineChain({
26
+ id: MPA_WALLET_CONTRACT_CONFIG.chainId,
27
+ name: 'Linea Mainnet',
28
+ nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },
29
+ rpcUrls: { default: { http: [MPA_WALLET_CONTRACT_CONFIG.rpcUrl] } },
30
+ });
31
+ return createPublicClient({
32
+ chain,
33
+ transport: http(MPA_WALLET_CONTRACT_CONFIG.rpcUrl),
34
+ });
35
+ }
36
+ function billingAddressFromEth(eth) {
37
+ return getAddress(eth.startsWith('0x') ? eth : `0x${eth}`);
38
+ }
39
+ function unwrapRecord(raw) {
40
+ const data = mpcAuthEnvelopeData(raw) ?? raw;
41
+ if (data != null && typeof data === 'object' && !Array.isArray(data)) {
42
+ return data;
43
+ }
44
+ return null;
45
+ }
46
+ function parseOptionalBool(raw) {
47
+ if (typeof raw === 'boolean')
48
+ return raw;
49
+ if (raw === 'true' || raw === '1' || raw === 1)
50
+ return true;
51
+ if (raw === 'false' || raw === '0' || raw === 0)
52
+ return false;
53
+ return undefined;
54
+ }
55
+ function parseBillingMonthUtc(raw) {
56
+ if (typeof raw === 'number' && raw > 0)
57
+ return raw;
58
+ if (typeof raw === 'string' && raw.trim()) {
59
+ const n = Number(raw);
60
+ if (Number.isFinite(n) && n > 0)
61
+ return n;
62
+ }
63
+ return undefined;
64
+ }
65
+ function feeStatusToMpaWalletStatus(fee, globalNonce) {
66
+ const decimals = fee.feetokendecimals ?? 18;
67
+ const symbol = fee.feetokensymbol ?? 'TOKEN';
68
+ const depositWei = BigInt(fee.remainingdepositwei || '0');
69
+ const monthlyWei = BigInt(fee.currentmonthlyfeewei || '0');
70
+ const topUp = BigInt(fee.requireminimumtopupwei || '0');
71
+ const freeLeft = fee.freetransactionsleft;
72
+ const funded = topUp === 0n && fee.registered && (fee.remainingnonces > 0 || depositWei >= monthlyWei);
73
+ return {
74
+ registered: fee.registered,
75
+ globalNonce: fee.globalnonce ?? globalNonce ?? undefined,
76
+ remainingNonces: fee.remainingnonces,
77
+ freeTransactionsLeft: freeLeft,
78
+ remainingDepositWei: fee.remainingdepositwei,
79
+ remainingDeposit: formatUnits(depositWei, decimals),
80
+ feeTokenSymbol: symbol,
81
+ feeTokenDecimals: decimals,
82
+ requiredMinimumTopUpWei: fee.requireminimumtopupwei,
83
+ monthlyFeeWei: fee.currentmonthlyfeewei,
84
+ monthlyFee: formatUnits(monthlyWei, decimals),
85
+ overageFeePerSigWei: fee.currentoveragefeepernoncewei,
86
+ purchasedOverageSignatures: fee.purchasedoveragesignatures,
87
+ activeFreeSignaturesPerMonth: fee.activefreesignaturespermonth,
88
+ fundedForCurrentMonth: funded,
89
+ hasEverDeposited: depositWei > 0n,
90
+ };
91
+ }
92
+ function parseFeeStatusPayload(data) {
93
+ const rn = data.remainingnonces ?? data.RemainingNonces;
94
+ if (typeof rn !== 'number')
95
+ return null;
96
+ const gn = data.globalnonce ?? data.GlobalNonce;
97
+ return {
98
+ globalnonce: typeof gn === 'number' ? gn : undefined,
99
+ remainingnonces: rn,
100
+ remainingdepositwei: String(data.remainingdepositwei ?? data.RemainingDepositWei ?? '0'),
101
+ requireminimumtopupwei: String(data.requireminimumtopupwei ?? data.RequireMinimumTopUpWei ?? '0'),
102
+ currentmonthlyfeewei: String(data.currentmonthlyfeewei ?? data.CurrentMonthlyFeeWei ?? '0'),
103
+ currentoveragefeepernoncewei: String(data.currentoveragefeepernoncewei ?? data.CurrentOverageFeePerNonceWei ?? '0'),
104
+ activefreesignaturespermonth: typeof data.activefreesignaturespermonth === 'number'
105
+ ? data.activefreesignaturespermonth
106
+ : undefined,
107
+ activevpnmonthlyfeewei: typeof data.activevpnmonthlyfeewei === 'string' ? data.activevpnmonthlyfeewei : undefined,
108
+ purchasedoveragesignatures: typeof data.purchasedoveragesignatures === 'number'
109
+ ? data.purchasedoveragesignatures
110
+ : undefined,
111
+ feetokensymbol: typeof data.feetokensymbol === 'string' ? data.feetokensymbol : undefined,
112
+ feetokendecimals: typeof data.feetokendecimals === 'number' ? data.feetokendecimals : undefined,
113
+ freetransactionsleft: typeof data.freetransactionsleft === 'number' ? data.freetransactionsleft : undefined,
114
+ registered: Boolean(data.registered ?? data.Registered),
115
+ };
116
+ }
117
+ export async function fetchFeeStatusByKeyGenId(config, keyGenId) {
118
+ const path = buildManagementQueryPath('/getFeeStatusByKeyGenId', { id: keyGenId });
119
+ const raw = await managementGet(config, path);
120
+ if (!raw.ok)
121
+ return null;
122
+ const data = unwrapRecord(raw.data);
123
+ if (!data)
124
+ return null;
125
+ return parseFeeStatusPayload(data);
126
+ }
127
+ async function resolveKeyGenGlobalNonceForChain(config, keyGenAddress, keyGenId, nodeGlobalNonce, feeStatusGlobalNonce) {
128
+ if (nodeGlobalNonce != null)
129
+ return nodeGlobalNonce;
130
+ if (feeStatusGlobalNonce != null)
131
+ return feeStatusGlobalNonce;
132
+ const trimmed = keyGenAddress.trim();
133
+ if (!trimmed)
134
+ return 0;
135
+ try {
136
+ const client = getMpaPublicClient();
137
+ return await client.getTransactionCount({
138
+ address: billingAddressFromEth(trimmed),
139
+ blockTag: 'pending',
140
+ });
141
+ }
142
+ catch {
143
+ return 0;
144
+ }
145
+ }
146
+ async function fetchMpaWalletStatusFromChain(keyGenId, currentNonce) {
147
+ const client = getMpaPublicClient();
148
+ const contractAddress = MPA_WALLET_CONTRACT_CONFIG.contractAddress;
149
+ try {
150
+ const registered = await client.readContract({
151
+ address: contractAddress,
152
+ abi: MPA_WALLET_READ_ABI,
153
+ functionName: 'isKeyGenRegistered',
154
+ args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
155
+ });
156
+ if (!registered)
157
+ return { registered: false, globalNonce: currentNonce };
158
+ const sub = await client.readContract({
159
+ address: contractAddress,
160
+ abi: MPA_WALLET_READ_ABI,
161
+ functionName: 'getSubscriptionStatus',
162
+ args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
163
+ });
164
+ const [, , signatureCountAtMonthStart, keyGenCreditBalance, monthlyFee, freeSignaturesPerMonth, overageFee, fundedForCurrentMonth, purchasedOverage] = sub;
165
+ const [remainingNonces, requiredTopUp] = await Promise.all([
166
+ client.readContract({
167
+ address: contractAddress,
168
+ abi: MPA_WALLET_READ_ABI,
169
+ functionName: 'getRemainingNonces',
170
+ args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM, BigInt(currentNonce)],
171
+ }),
172
+ client.readContract({
173
+ address: contractAddress,
174
+ abi: MPA_WALLET_READ_ABI,
175
+ functionName: 'getRequiredMinimumTopUp',
176
+ args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
177
+ }),
178
+ ]);
179
+ const sigAtStart = Number(signatureCountAtMonthStart);
180
+ const freeLeft = fundedForCurrentMonth
181
+ ? Math.max(0, Number(freeSignaturesPerMonth) - Math.max(0, currentNonce - sigAtStart))
182
+ : 0;
183
+ const feeToken = await client.readContract({
184
+ address: contractAddress,
185
+ abi: MPA_WALLET_READ_ABI,
186
+ functionName: 'FEE_TOKEN',
187
+ });
188
+ let symbol = 'TOKEN';
189
+ let decimals = 18;
190
+ try {
191
+ const [sym, dec] = await Promise.all([
192
+ client.readContract({
193
+ address: feeToken,
194
+ abi: ERC20_SYMBOL_DECIMALS_ABI,
195
+ functionName: 'symbol',
196
+ }),
197
+ client.readContract({
198
+ address: feeToken,
199
+ abi: ERC20_SYMBOL_DECIMALS_ABI,
200
+ functionName: 'decimals',
201
+ }),
202
+ ]);
203
+ symbol = sym ?? symbol;
204
+ decimals = Number(dec ?? decimals);
205
+ }
206
+ catch {
207
+ // keep defaults
208
+ }
209
+ return {
210
+ registered: true,
211
+ globalNonce: currentNonce,
212
+ freeTransactionsLeft: freeLeft,
213
+ remainingNonces: Number(remainingNonces),
214
+ remainingDepositWei: keyGenCreditBalance.toString(),
215
+ remainingDeposit: formatUnits(keyGenCreditBalance, decimals),
216
+ requiredMinimumTopUpWei: requiredTopUp.toString(),
217
+ monthlyFeeWei: monthlyFee.toString(),
218
+ monthlyFee: formatUnits(monthlyFee, decimals),
219
+ overageFeePerSigWei: overageFee.toString(),
220
+ purchasedOverageSignatures: Number(purchasedOverage),
221
+ activeFreeSignaturesPerMonth: Number(freeSignaturesPerMonth),
222
+ fundedForCurrentMonth: Boolean(fundedForCurrentMonth),
223
+ feeTokenSymbol: symbol,
224
+ feeTokenDecimals: decimals,
225
+ hasEverDeposited: keyGenCreditBalance > 0n,
226
+ };
227
+ }
228
+ catch {
229
+ return null;
230
+ }
231
+ }
232
+ function enrichKeyGenWalletStatus(status) {
233
+ return {
234
+ ...status,
235
+ canPayMonthFromCredit: canPayKeyGenMonthFromCredit(status),
236
+ payMonthDisabledReason: keyGenPayMonthDisabledReason(status),
237
+ };
238
+ }
239
+ /** Node fee status with on-chain KeyGen subscription fallback. */
240
+ export async function fetchMergedMpaWalletStatus(config, keyGenId, keyGenEthAddress) {
241
+ const [feeStatus, globalNonceResult] = await Promise.all([
242
+ fetchFeeStatusByKeyGenId(config, keyGenId),
243
+ fetchGlobalNonceByKeyGenId(config, keyGenId),
244
+ ]);
245
+ const nodeGlobalNonce = globalNonceResult.ok ? globalNonceResult.data : null;
246
+ const resolvedNonce = await resolveKeyGenGlobalNonceForChain(config, keyGenEthAddress, keyGenId, nodeGlobalNonce, feeStatus?.globalnonce);
247
+ if (feeStatus) {
248
+ const status = feeStatusToMpaWalletStatus(feeStatus, resolvedNonce);
249
+ status.globalNonce = nodeGlobalNonce ?? resolvedNonce;
250
+ if (!status.registered) {
251
+ const chainStatus = await fetchMpaWalletStatusFromChain(keyGenId, resolvedNonce);
252
+ if (chainStatus?.registered) {
253
+ chainStatus.globalNonce = nodeGlobalNonce ?? resolvedNonce;
254
+ return enrichKeyGenWalletStatus(chainStatus);
255
+ }
256
+ return enrichKeyGenWalletStatus(status);
257
+ }
258
+ const chain = await fetchMpaWalletStatusFromChain(keyGenId, resolvedNonce);
259
+ if (chain?.fundedForCurrentMonth != null) {
260
+ status.fundedForCurrentMonth = chain.fundedForCurrentMonth;
261
+ }
262
+ return enrichKeyGenWalletStatus(status);
263
+ }
264
+ const chainStatus = await fetchMpaWalletStatusFromChain(keyGenId, resolvedNonce);
265
+ if (chainStatus) {
266
+ chainStatus.globalNonce = nodeGlobalNonce ?? resolvedNonce;
267
+ return enrichKeyGenWalletStatus(chainStatus);
268
+ }
269
+ return enrichKeyGenWalletStatus({
270
+ registered: false,
271
+ error: 'Failed to load MPA wallet status',
272
+ globalNonce: nodeGlobalNonce ?? resolvedNonce,
273
+ });
274
+ }
275
+ function parseVpnFeeStatusPayload(data) {
276
+ const billingMonthActive = parseOptionalBool(data.fundedforcurrentmonth ??
277
+ data.FundedForCurrentMonth ??
278
+ data.vpnBillingMonthActive ??
279
+ data.VpnBillingMonthActive);
280
+ const accountRegistered = parseOptionalBool(data.vpnBillingRegistered ??
281
+ data.VpnBillingRegistered ??
282
+ data.accountRegistered ??
283
+ data.AccountRegistered);
284
+ const legacyRegistered = parseOptionalBool(data.registered ?? data.Registered);
285
+ const poolWei = BigInt(String(data.vpncreditbalancewei ?? data.VpnCreditBalanceWei ?? '0'));
286
+ const paidThrough = parseBillingMonthUtc(data.paidthroughmonth ?? data.PaidThroughMonth);
287
+ const hasPriorBilling = poolWei > 0n || paidThrough != null;
288
+ const monthInactive = billingMonthActive === false ||
289
+ (billingMonthActive == null && legacyRegistered === false && hasPriorBilling);
290
+ const registered = accountRegistered ??
291
+ (monthInactive && hasPriorBilling ? true : (legacyRegistered ?? false));
292
+ return {
293
+ registered,
294
+ paidthroughmonth: paidThrough,
295
+ fundedforcurrentmonth: billingMonthActive ?? legacyRegistered,
296
+ vpncreditbalancewei: poolWei.toString(),
297
+ vpnmonthlyfeewei: String(data.vpnmonthlyfeewei ?? data.VpnMonthlyFeeWei ?? '0'),
298
+ requireminimumtopupwei: String(data.requireminimumtopupwei ?? data.RequireMinimumTopUpWei ?? '0'),
299
+ feetokensymbol: typeof data.feetokensymbol === 'string' ? data.feetokensymbol : undefined,
300
+ feetokendecimals: typeof data.feetokendecimals === 'number' ? data.feetokendecimals : undefined,
301
+ hostip: typeof data.hostip === 'string' ? data.hostip : undefined,
302
+ };
303
+ }
304
+ export async function fetchVpnFeeStatusByNode(config, hostIp) {
305
+ const path = buildManagementQueryPath('/getVpnFeeStatus', {
306
+ hostIp: hostIp?.trim() || undefined,
307
+ });
308
+ const raw = await managementGet(config, path);
309
+ if (!raw.ok)
310
+ return null;
311
+ const data = unwrapRecord(raw.data);
312
+ if (!data)
313
+ return null;
314
+ return parseVpnFeeStatusPayload(data);
315
+ }
316
+ export async function fetchVpnSubscriptionStatus(nodeKey, hostIpAddress) {
317
+ try {
318
+ const hostBinding = computeVpnHostBinding(nodeKey, hostIpAddress);
319
+ const client = getMpaPublicClient();
320
+ const contractAddress = MPA_WALLET_CONTRACT_CONFIG.contractAddress;
321
+ const sub = await client.readContract({
322
+ address: contractAddress,
323
+ abi: MPA_WALLET_READ_ABI,
324
+ functionName: 'getVpnSubscriptionStatus',
325
+ args: [nodeKey, hostBinding],
326
+ });
327
+ const [registered, paidThroughMonth, vpnCreditBalance, vpnMonthlyFee, fundedForCurrentMonth] = sub;
328
+ return {
329
+ registered: Boolean(registered),
330
+ paidThroughMonth: Number(paidThroughMonth),
331
+ vpnCreditBalanceWei: vpnCreditBalance.toString(),
332
+ vpnMonthlyFeeWei: vpnMonthlyFee.toString(),
333
+ fundedForCurrentMonth: Boolean(fundedForCurrentMonth),
334
+ };
335
+ }
336
+ catch {
337
+ return null;
338
+ }
339
+ }
340
+ function vpnChainHasBillingAccount(chain) {
341
+ if (chain.registered)
342
+ return true;
343
+ if (chain.paidThroughMonth > 0)
344
+ return true;
345
+ return BigInt(chain.vpnCreditBalanceWei || '0') > 0n;
346
+ }
347
+ function mergeVpnFeeStatusWithChain(node, chain) {
348
+ if (!vpnChainHasBillingAccount(chain))
349
+ return node;
350
+ if (!node.registered) {
351
+ return {
352
+ ...node,
353
+ registered: true,
354
+ paidthroughmonth: chain.paidThroughMonth,
355
+ fundedforcurrentmonth: chain.fundedForCurrentMonth,
356
+ vpncreditbalancewei: chain.vpnCreditBalanceWei,
357
+ vpnmonthlyfeewei: chain.vpnMonthlyFeeWei || node.vpnmonthlyfeewei,
358
+ };
359
+ }
360
+ const nodePool = BigInt(node.vpncreditbalancewei || '0');
361
+ const chainPool = BigInt(chain.vpnCreditBalanceWei || '0');
362
+ return {
363
+ ...node,
364
+ paidthroughmonth: chain.paidThroughMonth ?? node.paidthroughmonth,
365
+ fundedforcurrentmonth: chain.fundedForCurrentMonth,
366
+ vpncreditbalancewei: (chainPool > nodePool ? chainPool : nodePool).toString(),
367
+ vpnmonthlyfeewei: chain.vpnMonthlyFeeWei || node.vpnmonthlyfeewei,
368
+ };
369
+ }
370
+ function vpnFeeStatusToMpaVpnStatus(fee, nodeKey, hostBinding) {
371
+ const decimals = fee.feetokendecimals ?? 6;
372
+ const symbol = fee.feetokensymbol ?? 'USDC';
373
+ const poolWei = BigInt(fee.vpncreditbalancewei || '0');
374
+ const monthlyWei = BigInt(fee.vpnmonthlyfeewei || '0');
375
+ const billingRegistered = fee.registered;
376
+ const monthActive = fee.fundedforcurrentmonth;
377
+ const status = {
378
+ registered: billingRegistered,
379
+ vpnBillingRegistered: billingRegistered,
380
+ nodeKey,
381
+ hostBinding,
382
+ fundedForCurrentMonth: monthActive,
383
+ vpnBillingMonthActive: monthActive,
384
+ paidThroughMonth: fee.paidthroughmonth,
385
+ vpnCreditBalanceWei: fee.vpncreditbalancewei,
386
+ vpnCreditBalance: formatUnits(poolWei, decimals),
387
+ vpnMonthlyFeeWei: fee.vpnmonthlyfeewei,
388
+ vpnMonthlyFee: formatUnits(monthlyWei, decimals),
389
+ requireMinimumTopUpWei: fee.requireminimumtopupwei,
390
+ feeTokenSymbol: symbol,
391
+ feeTokenDecimals: decimals,
392
+ };
393
+ return {
394
+ ...status,
395
+ canPayMonthFromCredit: canPayVpnMonthFromCredit(status),
396
+ payMonthDisabledReason: vpnPayMonthDisabledReason(status),
397
+ };
398
+ }
399
+ /** Node VPN fee status with on-chain subscription fallback. */
400
+ export async function fetchMergedMpaVpnStatus(config, nodeKey, hostIpAddress) {
401
+ const trimmedKey = nodeKey.trim();
402
+ const trimmedHost = hostIpAddress.trim();
403
+ const hostBinding = computeVpnHostBinding(trimmedKey, trimmedHost);
404
+ const [nodeStatus, chainStatus] = await Promise.all([
405
+ fetchVpnFeeStatusByNode(config, trimmedHost),
406
+ trimmedKey && trimmedHost
407
+ ? fetchVpnSubscriptionStatus(trimmedKey, trimmedHost)
408
+ : Promise.resolve(null),
409
+ ]);
410
+ let merged = null;
411
+ if (nodeStatus && chainStatus) {
412
+ merged = mergeVpnFeeStatusWithChain(nodeStatus, chainStatus);
413
+ }
414
+ else if (nodeStatus) {
415
+ merged = nodeStatus;
416
+ }
417
+ else if (chainStatus && vpnChainHasBillingAccount(chainStatus)) {
418
+ merged = {
419
+ registered: true,
420
+ paidthroughmonth: chainStatus.paidThroughMonth,
421
+ fundedforcurrentmonth: chainStatus.fundedForCurrentMonth,
422
+ vpncreditbalancewei: chainStatus.vpnCreditBalanceWei,
423
+ vpnmonthlyfeewei: chainStatus.vpnMonthlyFeeWei,
424
+ requireminimumtopupwei: '0',
425
+ };
426
+ }
427
+ if (!merged)
428
+ return null;
429
+ return vpnFeeStatusToMpaVpnStatus(merged, trimmedKey, hostBinding);
430
+ }
431
+ //# sourceMappingURL=mpa-fee-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpa-fee-status.js","sourceRoot":"","sources":["../../../src/core/mpc/mpa-fee-status.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,7 @@
1
1
  import type { NodeSdkConfig } from '../../config/schema.js';
2
2
  import type { SdkResult } from '../result.js';
3
- export declare function getMpaWalletStatus(config: NodeSdkConfig, input: unknown): Promise<SdkResult<{
4
- registered: boolean;
5
- freeTransactionsLeft?: number;
6
- hasEverDeposited?: boolean;
7
- remainingDeposit?: string;
8
- feeTokenSymbol?: string;
9
- remainingNonces?: number;
10
- globalNonce?: number;
11
- requiredMinimumTopUpWei?: string;
12
- monthlyFee?: string;
13
- error?: string;
14
- }>>;
3
+ import { type MpaWalletStatusData } from './mpa-fee-status.js';
4
+ export declare function getMpaWalletStatus(config: NodeSdkConfig, input: unknown): Promise<SdkResult<MpaWalletStatusData>>;
15
5
  export declare function createMpaTopUpMultiSignRequest(config: NodeSdkConfig, input: unknown): Promise<SdkResult<{
16
6
  requestId: string;
17
7
  }>>;
@@ -1 +1 @@
1
- {"version":3,"file":"mpa-top-up.d.ts","sourceRoot":"","sources":["../../../src/core/mpc/mpa-top-up.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAQ1D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAqC5C,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,GACZ,OAAO,CACT,SAAS,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CACF,CA+GA;AAED,wBAAsB,8BAA8B,CACnD,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CA2GzC"}
1
+ {"version":3,"file":"mpa-top-up.d.ts","sourceRoot":"","sources":["../../../src/core/mpc/mpa-top-up.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAQ1D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,OAAO,EAA6B,KAAK,mBAAmB,EAAC,MAAM,qBAAqB,CAAC;AAiCzF,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CA4BzC;AAcD,wBAAsB,8BAA8B,CACnD,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CAoIzC"}
@@ -5,6 +5,8 @@ import { fetchGlobalNonceByKeyGenId, fetchKeyGenResult } from '../keygen.js';
5
5
  import { buildMultiSignProposal } from '../../evm/proposal-builder.js';
6
6
  import { signAndSubmitMultiSignRequest } from './sign-request-body.js';
7
7
  import { assertExecutorNativeSufficientForProposal } from './gas-preflight.js';
8
+ import { fetchMergedMpaWalletStatus } from './mpa-fee-status.js';
9
+ import { shouldSyncKeyGenMonthAfterDeposit } from './mpa-billing-helpers.js';
8
10
  const ERC20_SYMBOL_DECIMALS_ABI = [
9
11
  {
10
12
  inputs: [],
@@ -48,81 +50,9 @@ export async function getMpaWalletStatus(config, input) {
48
50
  if (!eth) {
49
51
  return { ok: false, reason: 'KeyGen has no ethereum address.' };
50
52
  }
51
- const globalNonceResult = await fetchGlobalNonceByKeyGenId(config, parsed.data.keyGenId);
52
- const globalNonce = globalNonceResult.ok ? globalNonceResult.data : undefined;
53
- const client = getMpaPublicClient();
54
- const billingAddress = getAddress(eth.startsWith('0x') ? eth : `0x${eth}`);
55
- const contractAddress = MPA_WALLET_CONTRACT_CONFIG.contractAddress;
56
- const keyGenId = parsed.data.keyGenId;
57
53
  try {
58
- const registered = await client.readContract({
59
- address: contractAddress,
60
- abi: MPA_WALLET_READ_ABI,
61
- functionName: 'isKeyGenRegistered',
62
- args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
63
- });
64
- if (!registered) {
65
- return { ok: true, data: { registered: false, globalNonce } };
66
- }
67
- const sub = await client.readContract({
68
- address: contractAddress,
69
- abi: MPA_WALLET_READ_ABI,
70
- functionName: 'getSubscriptionStatus',
71
- args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
72
- });
73
- const [, , signatureCountAtMonthStart, nodeCreditBalance, monthlyFee, freeSignaturesPerMonth, , fundedForCurrentMonth] = sub;
74
- const currentNonce = globalNonce ??
75
- (await client.getTransactionCount({ address: billingAddress, blockTag: 'pending' }));
76
- const [remainingNonces, requiredTopUp] = await Promise.all([
77
- client.readContract({
78
- address: contractAddress,
79
- abi: MPA_WALLET_READ_ABI,
80
- functionName: 'getRemainingNonces',
81
- args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM, BigInt(currentNonce)],
82
- }),
83
- client.readContract({
84
- address: contractAddress,
85
- abi: MPA_WALLET_READ_ABI,
86
- functionName: 'getRequiredMinimumTopUp',
87
- args: [keyGenId, KEY_GEN_ADDRESS_KIND_ETHEREUM],
88
- }),
89
- ]);
90
- const feeToken = await client.readContract({
91
- address: contractAddress,
92
- abi: MPA_WALLET_READ_ABI,
93
- functionName: 'FEE_TOKEN',
94
- });
95
- const [symbol, decimals] = await Promise.all([
96
- client.readContract({
97
- address: feeToken,
98
- abi: ERC20_SYMBOL_DECIMALS_ABI,
99
- functionName: 'symbol',
100
- }),
101
- client.readContract({
102
- address: feeToken,
103
- abi: ERC20_SYMBOL_DECIMALS_ABI,
104
- functionName: 'decimals',
105
- }),
106
- ]);
107
- const d = Number(decimals ?? 18);
108
- const usedThisMonth = Math.max(0, currentNonce - Number(signatureCountAtMonthStart));
109
- const freeLeft = fundedForCurrentMonth
110
- ? Math.max(0, Number(freeSignaturesPerMonth) - usedThisMonth)
111
- : 0;
112
- return {
113
- ok: true,
114
- data: {
115
- registered: true,
116
- freeTransactionsLeft: freeLeft,
117
- remainingDeposit: formatUnits(nodeCreditBalance, d),
118
- feeTokenSymbol: symbol ?? 'TOKEN',
119
- remainingNonces: Number(remainingNonces),
120
- globalNonce: currentNonce,
121
- requiredMinimumTopUpWei: requiredTopUp.toString(),
122
- monthlyFee: formatUnits(monthlyFee, d),
123
- hasEverDeposited: nodeCreditBalance > 0n,
124
- },
125
- };
54
+ const data = await fetchMergedMpaWalletStatus(config, parsed.data.keyGenId, eth);
55
+ return { ok: true, data };
126
56
  }
127
57
  catch (e) {
128
58
  return {
@@ -130,11 +60,18 @@ export async function getMpaWalletStatus(config, input) {
130
60
  data: {
131
61
  registered: false,
132
62
  error: e instanceof Error ? e.message : 'Failed to load MPA wallet status',
133
- globalNonce,
134
63
  },
135
64
  };
136
65
  }
137
66
  }
67
+ async function resolveGlobalNonceForSync(config, keyGenId, billingAddress) {
68
+ const fromNode = await fetchGlobalNonceByKeyGenId(config, keyGenId);
69
+ if (fromNode.ok)
70
+ return fromNode;
71
+ const client = getMpaPublicClient();
72
+ const nonce = await client.getTransactionCount({ address: billingAddress, blockTag: 'pending' });
73
+ return { ok: true, data: nonce };
74
+ }
138
75
  export async function createMpaTopUpMultiSignRequest(config, input) {
139
76
  const parsed = MpaTopUpInputSchema.safeParse(input);
140
77
  if (!parsed.success) {
@@ -151,6 +88,8 @@ export async function createMpaTopUpMultiSignRequest(config, input) {
151
88
  const billingAddress = getAddress(eth.startsWith('0x') ? eth : `0x${eth}`);
152
89
  const mpa = MPA_WALLET_CONTRACT_CONFIG.contractAddress;
153
90
  const keyGenId = parsed.data.keyGenId;
91
+ const amountWei = BigInt(parsed.data.amountWei);
92
+ const walletStatus = await fetchMergedMpaWalletStatus(config, keyGenId, eth);
154
93
  const sub = await client.readContract({
155
94
  address: mpa,
156
95
  abi: MPA_WALLET_READ_ABI,
@@ -174,7 +113,6 @@ export async function createMpaTopUpMultiSignRequest(config, input) {
174
113
  abi: ERC20_SYMBOL_DECIMALS_ABI,
175
114
  functionName: 'decimals',
176
115
  });
177
- const amountWei = BigInt(parsed.data.amountWei);
178
116
  const minWei = requiredTopUp > 0n ? requiredTopUp : monthlyFee;
179
117
  if (amountWei < minWei) {
180
118
  return {
@@ -210,10 +148,30 @@ export async function createMpaTopUpMultiSignRequest(config, input) {
210
148
  { name: 'globalNonceAtActivation', type: 'uint256', value: globalNonceAtActivation },
211
149
  ],
212
150
  });
151
+ const syncAfterDeposit = parsed.data.activateBillingMonthAfterDeposit === true &&
152
+ shouldSyncKeyGenMonthAfterDeposit(walletStatus, amountWei);
153
+ if (syncAfterDeposit) {
154
+ const globalNonce = await resolveGlobalNonceForSync(config, keyGenId, billingAddress);
155
+ if (!globalNonce.ok)
156
+ return globalNonce;
157
+ actions.push({
158
+ signature: 'syncBilling(string,string,uint256)',
159
+ contractAddress: mpa,
160
+ args: [
161
+ { name: 'keyGenId', type: 'string', value: keyGenId },
162
+ { name: 'addressKind', type: 'string', value: KEY_GEN_ADDRESS_KIND_ETHEREUM },
163
+ { name: 'globalNonceAtActivation', type: 'uint256', value: String(globalNonce.data) },
164
+ ],
165
+ });
166
+ }
167
+ const purpose = parsed.data.purpose ??
168
+ (syncAfterDeposit
169
+ ? 'Top up MPA signing credits and activate billing month'
170
+ : 'Top up MPA signing credits');
213
171
  const built = await buildMultiSignProposal(config, {
214
172
  keyGenResult: kg.data,
215
173
  chainId: MPA_WALLET_CONTRACT_CONFIG.chainId,
216
- purpose: parsed.data.purpose ?? 'Top up MPA signing credits',
174
+ purpose,
217
175
  useCustomGas: parsed.data.useCustomGas,
218
176
  startingNonce: parsed.data.startingNonce,
219
177
  actions,