@seedhape/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/__tests__/acp.test.d.ts +2 -0
  2. package/dist/__tests__/acp.test.d.ts.map +1 -0
  3. package/dist/__tests__/acp.test.js +16 -0
  4. package/dist/__tests__/acp.test.js.map +1 -0
  5. package/dist/__tests__/ap2-official.test.d.ts +2 -0
  6. package/dist/__tests__/ap2-official.test.d.ts.map +1 -0
  7. package/dist/__tests__/ap2-official.test.js +49 -0
  8. package/dist/__tests__/ap2-official.test.js.map +1 -0
  9. package/dist/__tests__/mpp.test.d.ts +2 -0
  10. package/dist/__tests__/mpp.test.d.ts.map +1 -0
  11. package/dist/__tests__/mpp.test.js +42 -0
  12. package/dist/__tests__/mpp.test.js.map +1 -0
  13. package/dist/__tests__/outbound.test.d.ts +2 -0
  14. package/dist/__tests__/outbound.test.d.ts.map +1 -0
  15. package/dist/__tests__/outbound.test.js +23 -0
  16. package/dist/__tests__/outbound.test.js.map +1 -0
  17. package/dist/__tests__/protocols.test.d.ts +2 -0
  18. package/dist/__tests__/protocols.test.d.ts.map +1 -0
  19. package/dist/__tests__/protocols.test.js +16 -0
  20. package/dist/__tests__/protocols.test.js.map +1 -0
  21. package/dist/__tests__/providers.test.d.ts +2 -0
  22. package/dist/__tests__/providers.test.d.ts.map +1 -0
  23. package/dist/__tests__/providers.test.js +41 -0
  24. package/dist/__tests__/providers.test.js.map +1 -0
  25. package/dist/__tests__/reconciliation.test.d.ts +2 -0
  26. package/dist/__tests__/reconciliation.test.d.ts.map +1 -0
  27. package/dist/__tests__/reconciliation.test.js +35 -0
  28. package/dist/__tests__/reconciliation.test.js.map +1 -0
  29. package/dist/__tests__/spending-controls.test.d.ts +2 -0
  30. package/dist/__tests__/spending-controls.test.d.ts.map +1 -0
  31. package/dist/__tests__/spending-controls.test.js +47 -0
  32. package/dist/__tests__/spending-controls.test.js.map +1 -0
  33. package/dist/__tests__/tax-and-policy.test.d.ts +7 -0
  34. package/dist/__tests__/tax-and-policy.test.d.ts.map +1 -0
  35. package/dist/__tests__/tax-and-policy.test.js +389 -0
  36. package/dist/__tests__/tax-and-policy.test.js.map +1 -0
  37. package/dist/__tests__/web-bot-auth.test.d.ts +2 -0
  38. package/dist/__tests__/web-bot-auth.test.d.ts.map +1 -0
  39. package/dist/__tests__/web-bot-auth.test.js +33 -0
  40. package/dist/__tests__/web-bot-auth.test.js.map +1 -0
  41. package/dist/__tests__/x402-solana.test.d.ts +2 -0
  42. package/dist/__tests__/x402-solana.test.d.ts.map +1 -0
  43. package/dist/__tests__/x402-solana.test.js +155 -0
  44. package/dist/__tests__/x402-solana.test.js.map +1 -0
  45. package/dist/acp.d.ts +28 -0
  46. package/dist/acp.d.ts.map +1 -0
  47. package/dist/acp.js +49 -0
  48. package/dist/acp.js.map +1 -0
  49. package/dist/ap2/mandates.d.ts +319 -0
  50. package/dist/ap2/mandates.d.ts.map +1 -0
  51. package/dist/ap2/mandates.js +214 -0
  52. package/dist/ap2/mandates.js.map +1 -0
  53. package/dist/ap2/official.d.ts +156 -0
  54. package/dist/ap2/official.d.ts.map +1 -0
  55. package/dist/ap2/official.js +222 -0
  56. package/dist/ap2/official.js.map +1 -0
  57. package/dist/ap2/policy.d.ts +93 -0
  58. package/dist/ap2/policy.d.ts.map +1 -0
  59. package/dist/ap2/policy.js +216 -0
  60. package/dist/ap2/policy.js.map +1 -0
  61. package/dist/index.d.ts +22 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +22 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/india/fx.d.ts +59 -0
  66. package/dist/india/fx.d.ts.map +1 -0
  67. package/dist/india/fx.js +93 -0
  68. package/dist/india/fx.js.map +1 -0
  69. package/dist/india/vda-tax.d.ts +151 -0
  70. package/dist/india/vda-tax.d.ts.map +1 -0
  71. package/dist/india/vda-tax.js +226 -0
  72. package/dist/india/vda-tax.js.map +1 -0
  73. package/dist/mandate-builder.d.ts +102 -0
  74. package/dist/mandate-builder.d.ts.map +1 -0
  75. package/dist/mandate-builder.js +99 -0
  76. package/dist/mandate-builder.js.map +1 -0
  77. package/dist/mpp.d.ts +53 -0
  78. package/dist/mpp.d.ts.map +1 -0
  79. package/dist/mpp.js +164 -0
  80. package/dist/mpp.js.map +1 -0
  81. package/dist/orchestrator.d.ts +115 -0
  82. package/dist/orchestrator.d.ts.map +1 -0
  83. package/dist/orchestrator.js +351 -0
  84. package/dist/orchestrator.js.map +1 -0
  85. package/dist/postgres-store.d.ts +60 -0
  86. package/dist/postgres-store.d.ts.map +1 -0
  87. package/dist/postgres-store.js +441 -0
  88. package/dist/postgres-store.js.map +1 -0
  89. package/dist/protocols.d.ts +18 -0
  90. package/dist/protocols.d.ts.map +1 -0
  91. package/dist/protocols.js +24 -0
  92. package/dist/protocols.js.map +1 -0
  93. package/dist/reconciliation.d.ts +27 -0
  94. package/dist/reconciliation.d.ts.map +1 -0
  95. package/dist/reconciliation.js +38 -0
  96. package/dist/reconciliation.js.map +1 -0
  97. package/dist/store.d.ts +110 -0
  98. package/dist/store.d.ts.map +1 -0
  99. package/dist/store.js +369 -0
  100. package/dist/store.js.map +1 -0
  101. package/dist/types.d.ts +195 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +30 -0
  104. package/dist/types.js.map +1 -0
  105. package/dist/util/canonical.d.ts +9 -0
  106. package/dist/util/canonical.d.ts.map +1 -0
  107. package/dist/util/canonical.js +35 -0
  108. package/dist/util/canonical.js.map +1 -0
  109. package/dist/wallet/provider.d.ts +118 -0
  110. package/dist/wallet/provider.d.ts.map +1 -0
  111. package/dist/wallet/provider.js +160 -0
  112. package/dist/wallet/provider.js.map +1 -0
  113. package/dist/wallet/providers.d.ts +107 -0
  114. package/dist/wallet/providers.d.ts.map +1 -0
  115. package/dist/wallet/providers.js +188 -0
  116. package/dist/wallet/providers.js.map +1 -0
  117. package/dist/web-bot-auth.d.ts +54 -0
  118. package/dist/web-bot-auth.d.ts.map +1 -0
  119. package/dist/web-bot-auth.js +112 -0
  120. package/dist/web-bot-auth.js.map +1 -0
  121. package/dist/x402/client.d.ts +101 -0
  122. package/dist/x402/client.d.ts.map +1 -0
  123. package/dist/x402/client.js +291 -0
  124. package/dist/x402/client.js.map +1 -0
  125. package/dist/x402/outbound.d.ts +15 -0
  126. package/dist/x402/outbound.d.ts.map +1 -0
  127. package/dist/x402/outbound.js +59 -0
  128. package/dist/x402/outbound.js.map +1 -0
  129. package/dist/x402/types.d.ts +80 -0
  130. package/dist/x402/types.d.ts.map +1 -0
  131. package/dist/x402/types.js +2 -0
  132. package/dist/x402/types.js.map +1 -0
  133. package/package.json +29 -0
@@ -0,0 +1,27 @@
1
+ import type { Hex, SpendRecord } from "./types.js";
2
+ import type { Store } from "./store.js";
3
+ export type ReconciliationOutcome = {
4
+ status: "settled";
5
+ txHash?: Hex;
6
+ } | {
7
+ status: "failed";
8
+ reason?: string;
9
+ } | {
10
+ status: "pending";
11
+ };
12
+ export type ReconciliationSummary = {
13
+ inspected: number;
14
+ settled: number;
15
+ failed: number;
16
+ pending: number;
17
+ errors: number;
18
+ };
19
+ /**
20
+ * Resolve ambiguous spends without creating a second payment attempt.
21
+ *
22
+ * The resolver is deliberately injected: x402 facilitators, MPP providers,
23
+ * and future rails have different lookup APIs, but all of them must converge
24
+ * on this same reservation transition boundary.
25
+ */
26
+ export declare function reconcilePendingSpends(store: Store, userId: string, resolve: (spend: SpendRecord) => Promise<ReconciliationOutcome>, sinceUnix?: number, now?: number): Promise<ReconciliationSummary>;
27
+ //# sourceMappingURL=reconciliation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation.d.ts","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,qBAAqB,GAC7B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,qBAAqB,CAAC,EAC/D,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,SAAgC,GAClC,OAAO,CAAC,qBAAqB,CAAC,CAmBhC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Resolve ambiguous spends without creating a second payment attempt.
3
+ *
4
+ * The resolver is deliberately injected: x402 facilitators, MPP providers,
5
+ * and future rails have different lookup APIs, but all of them must converge
6
+ * on this same reservation transition boundary.
7
+ */
8
+ export async function reconcilePendingSpends(store, userId, resolve, sinceUnix, now = Math.floor(Date.now() / 1000)) {
9
+ const summary = { inspected: 0, settled: 0, failed: 0, pending: 0, errors: 0 };
10
+ const spends = (await store.listSpends(userId, sinceUnix)).filter((spend) => spend.status === "pending");
11
+ for (const spend of spends) {
12
+ summary.inspected += 1;
13
+ let outcome;
14
+ try {
15
+ outcome = await resolve(spend);
16
+ }
17
+ catch {
18
+ summary.errors += 1;
19
+ continue;
20
+ }
21
+ if (outcome.status === "pending") {
22
+ summary.pending += 1;
23
+ continue;
24
+ }
25
+ if (outcome.status === "settled") {
26
+ await store.updateSpend(spend.id, { status: "settled", txHash: outcome.txHash, settledAt: now, blockReason: undefined });
27
+ await store.commitSpendReservation(spend.id);
28
+ summary.settled += 1;
29
+ }
30
+ else {
31
+ await store.updateSpend(spend.id, { status: "failed", blockReason: outcome.reason?.slice(0, 500), settledAt: undefined });
32
+ await store.releaseSpendReservation(spend.id);
33
+ summary.failed += 1;
34
+ }
35
+ }
36
+ return summary;
37
+ }
38
+ //# sourceMappingURL=reconciliation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation.js","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAY,EACZ,MAAc,EACd,OAA+D,EAC/D,SAAkB,EAClB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAEnC,MAAM,OAAO,GAA0B,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACtG,MAAM,MAAM,GAAG,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACzG,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;QACvB,IAAI,OAA8B,CAAC;QACnC,IAAI,CAAC;YAAC,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAChF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACrE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;YACzH,MAAM,KAAK,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAC1H,MAAM,KAAK,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Persistence.
3
+ *
4
+ * Kept behind an interface because the storage requirements differ sharply by
5
+ * deployment: a locally-run MCP server wants SQLite in the user's home
6
+ * directory, a hosted multi-tenant deployment wants Postgres with row-level
7
+ * security. The SQLite implementation below is complete and is what the local
8
+ * server uses.
9
+ *
10
+ * bigints are stored as TEXT. SQLite INTEGER is 64-bit signed, which is enough
11
+ * for USDC base units today but not something to bet a ledger on.
12
+ */
13
+ import type { MandateHash, OnrampLot, CommerceEvent, SignedIntentMandate, SpendRecord } from "./types.js";
14
+ export interface AccountBudget {
15
+ amount: bigint;
16
+ currency: string;
17
+ periodSeconds: number;
18
+ periodStart: number;
19
+ }
20
+ export interface Store {
21
+ isSpendingPaused(userId: string): Promise<boolean>;
22
+ setSpendingPaused(userId: string, paused: boolean, at?: number): Promise<void>;
23
+ getAccountBudget(userId: string): Promise<AccountBudget | null>;
24
+ setAccountBudget(userId: string, budget: AccountBudget, at?: number): Promise<void>;
25
+ getAccountBudgetUsage(userId: string, periodStart: number): Promise<{
26
+ spent: bigint;
27
+ reserved: bigint;
28
+ }>;
29
+ reserveSpend(userId: string, reservationId: string, amount: bigint, periodStart: number, periodLimit: bigint, at?: number): Promise<boolean>;
30
+ releaseSpendReservation(reservationId: string): Promise<void>;
31
+ commitSpendReservation(reservationId: string): Promise<void>;
32
+ createMcpChallenge(address: string, message: string, expiresAt: number): Promise<void>;
33
+ consumeMcpChallenge(address: string, message: string): Promise<{
34
+ expiresAt: number;
35
+ } | null>;
36
+ createMcpToken(userId: string, label: string, expiresAt?: number): Promise<{
37
+ token: string;
38
+ expiresAt: number;
39
+ }>;
40
+ resolveMcpToken(token: string): Promise<{
41
+ userId: string;
42
+ scopes: string[];
43
+ } | null>;
44
+ revokeMcpToken(token: string): Promise<void>;
45
+ putIntent(userId: string, m: SignedIntentMandate): Promise<void>;
46
+ getIntent(hash: MandateHash): Promise<SignedIntentMandate | null>;
47
+ listIntents(userId: string, includeExpired?: boolean): Promise<SignedIntentMandate[]>;
48
+ revokeIntent(hash: MandateHash, at: number): Promise<void>;
49
+ putSpend(s: SpendRecord): Promise<void>;
50
+ updateSpend(id: string, patch: Partial<SpendRecord>): Promise<void>;
51
+ listSpends(userId: string, sinceUnix?: number): Promise<SpendRecord[]>;
52
+ spendsForIntent(hash: MandateHash, sinceUnix: number): Promise<SpendRecord[]>;
53
+ medianPriceForResource(userId: string, resource: string): Promise<bigint | undefined>;
54
+ medianPriceOverall(userId: string): Promise<bigint | undefined>;
55
+ knownHosts(userId: string): Promise<Set<string>>;
56
+ putLot(l: OnrampLot): Promise<void>;
57
+ listLots(userId: string): Promise<OnrampLot[]>;
58
+ updateLotRemaining(id: string, remaining: bigint): Promise<void>;
59
+ latestLot(userId: string): Promise<OnrampLot | null>;
60
+ putCommerceEvent(event: CommerceEvent): Promise<void>;
61
+ listCommerceEvents(limit?: number): Promise<CommerceEvent[]>;
62
+ close(): void;
63
+ }
64
+ export declare class SqliteStore implements Store {
65
+ private db;
66
+ constructor(path: string);
67
+ isSpendingPaused(userId: string): Promise<boolean>;
68
+ setSpendingPaused(userId: string, paused: boolean, at?: number): Promise<void>;
69
+ getAccountBudget(userId: string): Promise<AccountBudget | null>;
70
+ setAccountBudget(userId: string, budget: AccountBudget, at?: number): Promise<void>;
71
+ getAccountBudgetUsage(userId: string, periodStart: number): Promise<{
72
+ spent: bigint;
73
+ reserved: bigint;
74
+ }>;
75
+ reserveSpend(userId: string, reservationId: string, amount: bigint, periodStart: number, periodLimit: bigint, at?: number): Promise<boolean>;
76
+ releaseSpendReservation(reservationId: string): Promise<void>;
77
+ commitSpendReservation(reservationId: string): Promise<void>;
78
+ createMcpToken(userId: string, label: string, expiresAt?: number): Promise<{
79
+ token: string;
80
+ expiresAt: number;
81
+ }>;
82
+ createMcpChallenge(address: string, message: string, expiresAt: number): Promise<void>;
83
+ consumeMcpChallenge(address: string, message: string): Promise<{
84
+ expiresAt: number;
85
+ } | null>;
86
+ resolveMcpToken(token: string): Promise<{
87
+ userId: string;
88
+ scopes: string[];
89
+ } | null>;
90
+ revokeMcpToken(token: string): Promise<void>;
91
+ putIntent(userId: string, m: SignedIntentMandate): Promise<void>;
92
+ getIntent(hash: MandateHash): Promise<SignedIntentMandate | null>;
93
+ listIntents(userId: string, includeExpired?: boolean): Promise<SignedIntentMandate[]>;
94
+ revokeIntent(hash: MandateHash, at: number): Promise<void>;
95
+ putSpend(s: SpendRecord): Promise<void>;
96
+ updateSpend(id: string, patch: Partial<SpendRecord>): Promise<void>;
97
+ listSpends(userId: string, sinceUnix?: number): Promise<SpendRecord[]>;
98
+ spendsForIntent(hash: MandateHash, sinceUnix: number): Promise<SpendRecord[]>;
99
+ medianPriceForResource(userId: string, resource: string): Promise<bigint | undefined>;
100
+ medianPriceOverall(userId: string): Promise<bigint | undefined>;
101
+ knownHosts(userId: string): Promise<Set<string>>;
102
+ putLot(l: OnrampLot): Promise<void>;
103
+ listLots(userId: string): Promise<OnrampLot[]>;
104
+ updateLotRemaining(id: string, remaining: bigint): Promise<void>;
105
+ latestLot(userId: string): Promise<OnrampLot | null>;
106
+ putCommerceEvent(event: CommerceEvent): Promise<void>;
107
+ listCommerceEvents(limit?: number): Promise<CommerceEvent[]>;
108
+ close(): void;
109
+ }
110
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js ADDED
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Persistence.
3
+ *
4
+ * Kept behind an interface because the storage requirements differ sharply by
5
+ * deployment: a locally-run MCP server wants SQLite in the user's home
6
+ * directory, a hosted multi-tenant deployment wants Postgres with row-level
7
+ * security. The SQLite implementation below is complete and is what the local
8
+ * server uses.
9
+ *
10
+ * bigints are stored as TEXT. SQLite INTEGER is 64-bit signed, which is enough
11
+ * for USDC base units today but not something to bet a ledger on.
12
+ */
13
+ import { DatabaseSync } from "node:sqlite";
14
+ import { createHash, randomBytes } from "node:crypto";
15
+ const SCHEMA = `
16
+ CREATE TABLE IF NOT EXISTS spending_controls (
17
+ user_id TEXT PRIMARY KEY,
18
+ paused INTEGER NOT NULL DEFAULT 0,
19
+ updated_at INTEGER NOT NULL
20
+ );
21
+ CREATE TABLE IF NOT EXISTS account_budgets (
22
+ user_id TEXT PRIMARY KEY,
23
+ amount TEXT NOT NULL,
24
+ currency TEXT NOT NULL,
25
+ period_seconds INTEGER NOT NULL,
26
+ period_start INTEGER NOT NULL,
27
+ updated_at INTEGER NOT NULL
28
+ );
29
+ CREATE TABLE IF NOT EXISTS spend_reservations (
30
+ id TEXT PRIMARY KEY,
31
+ user_id TEXT NOT NULL,
32
+ amount TEXT NOT NULL,
33
+ period_start INTEGER NOT NULL,
34
+ period_limit TEXT NOT NULL,
35
+ status TEXT NOT NULL,
36
+ created_at INTEGER NOT NULL
37
+ );
38
+ CREATE INDEX IF NOT EXISTS idx_spend_reservations_user ON spend_reservations(user_id, created_at, status);
39
+
40
+ CREATE TABLE IF NOT EXISTS mcp_tokens (
41
+ token_hash TEXT PRIMARY KEY,
42
+ user_id TEXT NOT NULL,
43
+ label TEXT NOT NULL,
44
+ scopes_json TEXT NOT NULL,
45
+ expires_at INTEGER,
46
+ revoked_at INTEGER,
47
+ created_at INTEGER NOT NULL
48
+ );
49
+ CREATE INDEX IF NOT EXISTS idx_mcp_tokens_user ON mcp_tokens(user_id);
50
+ CREATE TABLE IF NOT EXISTS mcp_challenges (
51
+ address TEXT NOT NULL,
52
+ message TEXT PRIMARY KEY,
53
+ expires_at INTEGER NOT NULL,
54
+ created_at INTEGER NOT NULL
55
+ );
56
+
57
+ CREATE TABLE IF NOT EXISTS intents (
58
+ hash TEXT PRIMARY KEY,
59
+ user_id TEXT NOT NULL,
60
+ json TEXT NOT NULL,
61
+ expiry INTEGER NOT NULL,
62
+ revoked_at INTEGER
63
+ );
64
+ CREATE INDEX IF NOT EXISTS idx_intents_user ON intents(user_id);
65
+
66
+ CREATE TABLE IF NOT EXISTS spends (
67
+ id TEXT PRIMARY KEY,
68
+ user_id TEXT NOT NULL,
69
+ intent_hash TEXT NOT NULL,
70
+ cart_hash TEXT,
71
+ payment_hash TEXT,
72
+ resource TEXT NOT NULL,
73
+ host TEXT NOT NULL,
74
+ pay_to TEXT NOT NULL,
75
+ amount TEXT NOT NULL,
76
+ asset_json TEXT NOT NULL,
77
+ inr_paise TEXT NOT NULL,
78
+ fx_rate_scaled TEXT NOT NULL,
79
+ status TEXT NOT NULL,
80
+ tx_hash TEXT,
81
+ created_at INTEGER NOT NULL,
82
+ settled_at INTEGER,
83
+ block_reason TEXT
84
+ );
85
+ CREATE INDEX IF NOT EXISTS idx_spends_user_time ON spends(user_id, created_at);
86
+ CREATE INDEX IF NOT EXISTS idx_spends_intent ON spends(intent_hash, created_at);
87
+ CREATE INDEX IF NOT EXISTS idx_spends_resource ON spends(user_id, resource);
88
+
89
+ CREATE TABLE IF NOT EXISTS lots (
90
+ id TEXT PRIMARY KEY,
91
+ user_id TEXT NOT NULL,
92
+ quantity TEXT NOT NULL,
93
+ remaining TEXT NOT NULL,
94
+ cost_inr_paise TEXT NOT NULL,
95
+ acquired_at INTEGER NOT NULL,
96
+ provider_tx_id TEXT NOT NULL,
97
+ provider TEXT NOT NULL
98
+ );
99
+ CREATE INDEX IF NOT EXISTS idx_lots_user_time ON lots(user_id, acquired_at);
100
+
101
+ CREATE TABLE IF NOT EXISTS commerce_events (
102
+ id TEXT PRIMARY KEY,
103
+ side TEXT NOT NULL,
104
+ status TEXT NOT NULL,
105
+ product_id TEXT NOT NULL,
106
+ amount TEXT,
107
+ payer TEXT,
108
+ transaction_id TEXT,
109
+ at INTEGER NOT NULL
110
+ );
111
+ CREATE INDEX IF NOT EXISTS idx_commerce_events_at ON commerce_events(at);
112
+ `;
113
+ export class SqliteStore {
114
+ db;
115
+ constructor(path) {
116
+ this.db = new DatabaseSync(path);
117
+ this.db.exec("PRAGMA journal_mode = WAL;");
118
+ this.db.exec("PRAGMA foreign_keys = ON;");
119
+ this.db.exec(SCHEMA);
120
+ }
121
+ async isSpendingPaused(userId) {
122
+ const row = this.db.prepare(`SELECT paused FROM spending_controls WHERE user_id = ?`).get(userId);
123
+ return row?.paused === 1;
124
+ }
125
+ async setSpendingPaused(userId, paused, at = Math.floor(Date.now() / 1000)) {
126
+ this.db.prepare(`INSERT INTO spending_controls (user_id, paused, updated_at) VALUES (?, ?, ?) ON CONFLICT(user_id) DO UPDATE SET paused = excluded.paused, updated_at = excluded.updated_at`).run(userId, paused ? 1 : 0, at);
127
+ }
128
+ async getAccountBudget(userId) {
129
+ const row = this.db.prepare(`SELECT amount, currency, period_seconds, period_start FROM account_budgets WHERE user_id = ?`).get(userId);
130
+ return row ? { amount: BigInt(row.amount), currency: row.currency, periodSeconds: row.period_seconds, periodStart: row.period_start } : null;
131
+ }
132
+ async setAccountBudget(userId, budget, at = Math.floor(Date.now() / 1000)) {
133
+ this.db.prepare(`INSERT INTO account_budgets (user_id, amount, currency, period_seconds, period_start, updated_at) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(user_id) DO UPDATE SET amount = excluded.amount, currency = excluded.currency, period_seconds = excluded.period_seconds, period_start = excluded.period_start, updated_at = excluded.updated_at`).run(userId, budget.amount.toString(), budget.currency, budget.periodSeconds, budget.periodStart, at);
134
+ }
135
+ async getAccountBudgetUsage(userId, periodStart) {
136
+ const spent = this.db.prepare(`SELECT COALESCE(SUM(CAST(amount AS INTEGER)), 0) AS total FROM spends WHERE user_id = ? AND created_at >= ? AND status = 'settled'`).get(userId, periodStart);
137
+ const reserved = this.db.prepare(`SELECT COALESCE(SUM(CAST(amount AS INTEGER)), 0) AS total FROM spend_reservations WHERE user_id = ? AND created_at >= ? AND status = 'reserved'`).get(userId, periodStart);
138
+ return { spent: BigInt(spent.total), reserved: BigInt(reserved.total) };
139
+ }
140
+ async reserveSpend(userId, reservationId, amount, periodStart, periodLimit, at = Math.floor(Date.now() / 1000)) {
141
+ this.db.exec("BEGIN IMMEDIATE");
142
+ try {
143
+ const existing = this.db.prepare(`SELECT status FROM spend_reservations WHERE id = ?`).get(reservationId);
144
+ if (existing) {
145
+ this.db.exec("COMMIT");
146
+ return existing.status === "reserved" || existing.status === "committed";
147
+ }
148
+ const spent = this.db.prepare(`SELECT COALESCE(SUM(CAST(amount AS INTEGER)), 0) AS total FROM spends WHERE user_id = ? AND created_at >= ? AND status IN ('pending','settled')`).get(userId, periodStart);
149
+ const reserved = this.db.prepare(`SELECT COALESCE(SUM(CAST(amount AS INTEGER)), 0) AS total FROM spend_reservations WHERE user_id = ? AND created_at >= ? AND status = 'reserved'`).get(userId, periodStart);
150
+ const total = BigInt(spent.total) + BigInt(reserved.total);
151
+ if (total + amount > periodLimit) {
152
+ this.db.exec("COMMIT");
153
+ return false;
154
+ }
155
+ this.db.prepare(`INSERT INTO spend_reservations (id,user_id,amount,period_start,period_limit,status,created_at) VALUES (?,?,?,?,?,'reserved',?)`).run(reservationId, userId, amount.toString(), periodStart, periodLimit.toString(), at);
156
+ this.db.exec("COMMIT");
157
+ return true;
158
+ }
159
+ catch (error) {
160
+ this.db.exec("ROLLBACK");
161
+ throw error;
162
+ }
163
+ }
164
+ async releaseSpendReservation(reservationId) { this.db.prepare(`UPDATE spend_reservations SET status = 'released' WHERE id = ? AND status = 'reserved'`).run(reservationId); }
165
+ async commitSpendReservation(reservationId) { this.db.prepare(`UPDATE spend_reservations SET status = 'committed' WHERE id = ? AND status = 'reserved'`).run(reservationId); }
166
+ async createMcpToken(userId, label, expiresAt = Math.floor(Date.now() / 1000) + 90 * 86_400) {
167
+ const token = `shp_${randomBytes(32).toString("base64url")}`;
168
+ this.db.prepare(`INSERT INTO mcp_tokens (token_hash, user_id, label, scopes_json, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?)`).run(hashMcpToken(token), userId, label, JSON.stringify(["mcp"]), expiresAt, Math.floor(Date.now() / 1000));
169
+ return { token, expiresAt };
170
+ }
171
+ async createMcpChallenge(address, message, expiresAt) {
172
+ this.db.prepare(`INSERT INTO mcp_challenges (address, message, expires_at, created_at) VALUES (?, ?, ?, ?)`).run(address.toLowerCase(), message, expiresAt, Math.floor(Date.now() / 1000));
173
+ }
174
+ async consumeMcpChallenge(address, message) {
175
+ const row = this.db.prepare(`SELECT expires_at FROM mcp_challenges WHERE address = ? AND message = ?`).get(address.toLowerCase(), message);
176
+ if (!row || row.expires_at <= Math.floor(Date.now() / 1000))
177
+ return null;
178
+ this.db.prepare(`DELETE FROM mcp_challenges WHERE address = ? AND message = ?`).run(address.toLowerCase(), message);
179
+ return { expiresAt: row.expires_at };
180
+ }
181
+ async resolveMcpToken(token) {
182
+ const row = this.db.prepare(`SELECT user_id, scopes_json, expires_at, revoked_at FROM mcp_tokens WHERE token_hash = ?`).get(hashMcpToken(token));
183
+ if (!row || row.revoked_at !== null || (row.expires_at !== null && row.expires_at <= Math.floor(Date.now() / 1000)))
184
+ return null;
185
+ return { userId: row.user_id, scopes: JSON.parse(row.scopes_json) };
186
+ }
187
+ async revokeMcpToken(token) {
188
+ this.db.prepare(`UPDATE mcp_tokens SET revoked_at = ? WHERE token_hash = ?`).run(Math.floor(Date.now() / 1000), hashMcpToken(token));
189
+ }
190
+ // --- intents ---
191
+ async putIntent(userId, m) {
192
+ this.db
193
+ .prepare(`INSERT OR REPLACE INTO intents (hash, user_id, json, expiry, revoked_at)
194
+ VALUES (?, ?, ?, ?, ?)`)
195
+ .run(m.hash, userId, serialise(m), m.mandate.expiry, m.revokedAt ?? null);
196
+ }
197
+ async getIntent(hash) {
198
+ const row = this.db
199
+ .prepare(`SELECT json, revoked_at FROM intents WHERE hash = ?`)
200
+ .get(hash);
201
+ if (!row)
202
+ return null;
203
+ const m = deserialise(row.json);
204
+ if (row.revoked_at)
205
+ m.revokedAt = row.revoked_at;
206
+ return m;
207
+ }
208
+ async listIntents(userId, includeExpired = false) {
209
+ const now = Math.floor(Date.now() / 1000);
210
+ const sql = includeExpired
211
+ ? `SELECT json, revoked_at FROM intents WHERE user_id = ? ORDER BY expiry DESC`
212
+ : `SELECT json, revoked_at FROM intents WHERE user_id = ? AND expiry > ${now} AND revoked_at IS NULL ORDER BY expiry DESC`;
213
+ const rows = this.db.prepare(sql).all(userId);
214
+ return rows.map((r) => {
215
+ const m = deserialise(r.json);
216
+ if (r.revoked_at)
217
+ m.revokedAt = r.revoked_at;
218
+ return m;
219
+ });
220
+ }
221
+ async revokeIntent(hash, at) {
222
+ this.db.prepare(`UPDATE intents SET revoked_at = ? WHERE hash = ?`).run(at, hash);
223
+ }
224
+ // --- spends ---
225
+ async putSpend(s) {
226
+ this.db
227
+ .prepare(`INSERT OR REPLACE INTO spends
228
+ (id, user_id, intent_hash, cart_hash, payment_hash, resource, host, pay_to,
229
+ amount, asset_json, inr_paise, fx_rate_scaled, status, tx_hash,
230
+ created_at, settled_at, block_reason)
231
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`)
232
+ .run(s.id, s.userId, s.intentHash, s.cartHash ?? null, s.paymentHash ?? null, s.resource, s.host, s.payTo, s.amount.toString(), JSON.stringify(s.asset), s.inrPaise.toString(), s.fxRateScaled.toString(), s.status, s.txHash ?? null, s.createdAt, s.settledAt ?? null, s.blockReason ?? null);
233
+ }
234
+ async updateSpend(id, patch) {
235
+ const map = {
236
+ status: "status", txHash: "tx_hash", settledAt: "settled_at",
237
+ blockReason: "block_reason", cartHash: "cart_hash", paymentHash: "payment_hash",
238
+ };
239
+ const sets = [];
240
+ const vals = [];
241
+ for (const [k, col] of Object.entries(map)) {
242
+ const v = patch[k];
243
+ if (v === undefined)
244
+ continue;
245
+ sets.push(`${col} = ?`);
246
+ vals.push(typeof v === "bigint" ? v.toString() : v);
247
+ }
248
+ if (sets.length === 0)
249
+ return;
250
+ vals.push(id);
251
+ this.db.prepare(`UPDATE spends SET ${sets.join(", ")} WHERE id = ?`).run(...vals);
252
+ }
253
+ async listSpends(userId, sinceUnix = 0) {
254
+ const rows = this.db
255
+ .prepare(`SELECT * FROM spends WHERE user_id = ? AND created_at >= ? ORDER BY created_at DESC`)
256
+ .all(userId, sinceUnix);
257
+ return rows.map(rowToSpend);
258
+ }
259
+ async spendsForIntent(hash, sinceUnix) {
260
+ const rows = this.db
261
+ .prepare(`SELECT * FROM spends WHERE intent_hash = ? AND created_at >= ? ORDER BY created_at DESC`)
262
+ .all(hash, sinceUnix);
263
+ return rows.map(rowToSpend);
264
+ }
265
+ async medianPriceForResource(userId, resource) {
266
+ const rows = this.db
267
+ .prepare(`SELECT amount FROM spends WHERE user_id = ? AND resource = ? AND status = 'settled'`)
268
+ .all(userId, resource);
269
+ if (rows.length === 0)
270
+ return undefined;
271
+ const sorted = rows.map((r) => BigInt(r.amount)).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
272
+ const mid = Math.floor(sorted.length / 2);
273
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2n;
274
+ }
275
+ async medianPriceOverall(userId) {
276
+ const rows = this.db
277
+ .prepare(`SELECT amount FROM spends WHERE user_id = ? AND status = 'settled'`)
278
+ .all(userId);
279
+ if (rows.length < 3)
280
+ return undefined; // too little history to call anything typical
281
+ const sorted = rows.map((r) => BigInt(r.amount)).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
282
+ const mid = Math.floor(sorted.length / 2);
283
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2n;
284
+ }
285
+ async knownHosts(userId) {
286
+ const rows = this.db
287
+ .prepare(`SELECT DISTINCT host FROM spends WHERE user_id = ? AND status = 'settled'`)
288
+ .all(userId);
289
+ return new Set(rows.map((r) => r.host));
290
+ }
291
+ // --- lots ---
292
+ async putLot(l) {
293
+ this.db
294
+ .prepare(`INSERT OR REPLACE INTO lots
295
+ (id, user_id, quantity, remaining, cost_inr_paise, acquired_at, provider_tx_id, provider)
296
+ VALUES (?,?,?,?,?,?,?,?)`)
297
+ .run(l.id, l.userId, l.quantity.toString(), l.remaining.toString(), l.costInrPaise.toString(), l.acquiredAt, l.providerTxId, l.provider);
298
+ }
299
+ async listLots(userId) {
300
+ const rows = this.db
301
+ .prepare(`SELECT * FROM lots WHERE user_id = ? ORDER BY acquired_at ASC`)
302
+ .all(userId);
303
+ return rows.map(rowToLot);
304
+ }
305
+ async updateLotRemaining(id, remaining) {
306
+ this.db.prepare(`UPDATE lots SET remaining = ? WHERE id = ?`).run(remaining.toString(), id);
307
+ }
308
+ async latestLot(userId) {
309
+ const row = this.db
310
+ .prepare(`SELECT * FROM lots WHERE user_id = ? ORDER BY acquired_at DESC LIMIT 1`)
311
+ .get(userId);
312
+ return row ? rowToLot(row) : null;
313
+ }
314
+ // --- hosted commerce events ---------------------------------------------
315
+ async putCommerceEvent(event) {
316
+ this.db.prepare(`INSERT OR REPLACE INTO commerce_events
317
+ (id, side, status, product_id, amount, payer, transaction_id, at)
318
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.side, event.status, event.productId, event.amount ?? null, event.payer ?? null, event.transaction ?? null, event.at);
319
+ }
320
+ async listCommerceEvents(limit = 100) {
321
+ const safeLimit = Math.max(1, Math.min(1000, Math.trunc(limit)));
322
+ const rows = this.db.prepare(`SELECT id, side, status, product_id, amount, payer, transaction_id, at
323
+ FROM commerce_events ORDER BY at DESC LIMIT ?`).all(safeLimit);
324
+ return rows.map((row) => ({
325
+ id: row.id, side: row.side, status: row.status, productId: row.product_id,
326
+ amount: row.amount ?? undefined, payer: row.payer ?? undefined,
327
+ transaction: row.transaction_id ?? undefined, at: row.at,
328
+ }));
329
+ }
330
+ close() {
331
+ this.db.close();
332
+ }
333
+ }
334
+ // --- serialisation helpers -------------------------------------------------
335
+ function hashMcpToken(token) {
336
+ return createHash("sha256").update(token).digest("hex");
337
+ }
338
+ function serialise(v) {
339
+ return JSON.stringify(v, (_k, val) => typeof val === "bigint" ? { __bigint: val.toString() } : val);
340
+ }
341
+ function deserialise(s) {
342
+ return JSON.parse(s, (_k, val) => {
343
+ if (val && typeof val === "object" && "__bigint" in val) {
344
+ return BigInt(val.__bigint);
345
+ }
346
+ return val;
347
+ });
348
+ }
349
+ /* eslint-disable @typescript-eslint/no-explicit-any */
350
+ function rowToSpend(r) {
351
+ return {
352
+ id: r.id, userId: r.user_id, intentHash: r.intent_hash,
353
+ cartHash: r.cart_hash ?? undefined, paymentHash: r.payment_hash ?? undefined,
354
+ resource: r.resource, host: r.host, payTo: r.pay_to,
355
+ amount: BigInt(r.amount), asset: JSON.parse(r.asset_json),
356
+ inrPaise: BigInt(r.inr_paise), fxRateScaled: BigInt(r.fx_rate_scaled),
357
+ status: r.status, txHash: r.tx_hash ?? undefined,
358
+ createdAt: r.created_at, settledAt: r.settled_at ?? undefined,
359
+ blockReason: r.block_reason ?? undefined,
360
+ };
361
+ }
362
+ function rowToLot(r) {
363
+ return {
364
+ id: r.id, userId: r.user_id, quantity: BigInt(r.quantity),
365
+ remaining: BigInt(r.remaining), costInrPaise: BigInt(r.cost_inr_paise),
366
+ acquiredAt: r.acquired_at, providerTxId: r.provider_tx_id, provider: r.provider,
367
+ };
368
+ }
369
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}