@nordsym/apiclaw 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/AGENTS.md +74 -0
  2. package/HEARTBEAT.md +4 -0
  3. package/IDENTITY.md +22 -0
  4. package/README.md +193 -202
  5. package/SOUL.md +36 -0
  6. package/STATUS.md +237 -0
  7. package/TOOLS.md +36 -0
  8. package/USER.md +17 -0
  9. package/{backend/convex → convex}/_generated/api.d.ts +12 -6
  10. package/convex/analytics.ts +90 -0
  11. package/convex/credits.ts +211 -0
  12. package/convex/http.ts +578 -0
  13. package/convex/providers.ts +516 -0
  14. package/convex/purchases.ts +183 -0
  15. package/convex/ratelimit.ts +104 -0
  16. package/convex/schema.ts +220 -0
  17. package/convex/telemetry.ts +81 -0
  18. package/convex.json +3 -0
  19. package/dist/credentials.d.ts +19 -0
  20. package/dist/credentials.d.ts.map +1 -0
  21. package/dist/credentials.js +158 -0
  22. package/dist/credentials.js.map +1 -0
  23. package/dist/credits.d.ts +14 -11
  24. package/dist/credits.d.ts.map +1 -1
  25. package/dist/credits.js +151 -99
  26. package/dist/credits.js.map +1 -1
  27. package/dist/discovery.d.ts +7 -16
  28. package/dist/discovery.d.ts.map +1 -1
  29. package/dist/discovery.js +33 -40
  30. package/dist/discovery.js.map +1 -1
  31. package/dist/execute.d.ts +19 -0
  32. package/dist/execute.d.ts.map +1 -0
  33. package/dist/execute.js +285 -0
  34. package/dist/execute.js.map +1 -0
  35. package/dist/index.js +175 -31
  36. package/dist/index.js.map +1 -1
  37. package/dist/proxy.d.ts +6 -0
  38. package/dist/proxy.d.ts.map +1 -0
  39. package/dist/proxy.js +19 -0
  40. package/dist/proxy.js.map +1 -0
  41. package/dist/registry/apis.json +95362 -202
  42. package/dist/registry/apis_expanded.json +100853 -0
  43. package/dist/stripe.d.ts +68 -0
  44. package/dist/stripe.d.ts.map +1 -0
  45. package/dist/stripe.js +196 -0
  46. package/dist/stripe.js.map +1 -0
  47. package/dist/telemetry.d.ts +28 -0
  48. package/dist/telemetry.d.ts.map +1 -0
  49. package/dist/telemetry.js +50 -0
  50. package/dist/telemetry.js.map +1 -0
  51. package/dist/test.d.ts +3 -2
  52. package/dist/test.d.ts.map +1 -1
  53. package/dist/test.js +105 -75
  54. package/dist/test.js.map +1 -1
  55. package/dist/types.d.ts +0 -28
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/webhook.d.ts +2 -0
  58. package/dist/webhook.d.ts.map +1 -0
  59. package/dist/webhook.js +90 -0
  60. package/dist/webhook.js.map +1 -0
  61. package/landing/DESIGN.md +343 -0
  62. package/landing/package-lock.json +1196 -7
  63. package/landing/package.json +5 -1
  64. package/landing/public/android-chrome-192x192.png +0 -0
  65. package/landing/public/android-chrome-512x512.png +0 -0
  66. package/landing/public/apple-touch-icon.png +0 -0
  67. package/landing/public/demo.gif +0 -0
  68. package/landing/public/demo.mp4 +0 -0
  69. package/landing/public/favicon-16x16.png +0 -0
  70. package/landing/public/favicon-32x32.png +0 -0
  71. package/landing/public/favicon.ico +0 -0
  72. package/landing/public/favicon.svg +3 -0
  73. package/landing/public/icon.svg +47 -0
  74. package/landing/public/logo-mono.svg +37 -0
  75. package/landing/public/logo-simple.svg +45 -0
  76. package/landing/public/logo.svg +84 -0
  77. package/landing/public/og-template.html +184 -0
  78. package/landing/public/site.webmanifest +31 -0
  79. package/landing/scripts/generate-assets.js +284 -0
  80. package/landing/scripts/generate-pngs.js +48 -0
  81. package/landing/scripts/generate-stats.js +42 -0
  82. package/landing/src/app/admin/page.tsx +348 -0
  83. package/landing/src/app/api/auth/magic-link/route.ts +73 -0
  84. package/landing/src/app/api/auth/session/route.ts +38 -0
  85. package/landing/src/app/api/auth/verify/route.ts +43 -0
  86. package/landing/src/app/api/og/route.tsx +84 -0
  87. package/landing/src/app/globals.css +439 -100
  88. package/landing/src/app/layout.tsx +37 -7
  89. package/landing/src/app/page.tsx +627 -552
  90. package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
  91. package/landing/src/app/providers/dashboard/page.tsx +589 -0
  92. package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
  93. package/landing/src/app/providers/layout.tsx +14 -0
  94. package/landing/src/app/providers/page.tsx +402 -0
  95. package/landing/src/app/providers/register/page.tsx +670 -0
  96. package/landing/src/components/ProviderDashboard.tsx +794 -0
  97. package/landing/src/hooks/useDashboardData.ts +99 -0
  98. package/landing/src/lib/apis.json +116054 -0
  99. package/landing/src/lib/convex-client.ts +106 -0
  100. package/landing/src/lib/mock-data.ts +285 -0
  101. package/landing/src/lib/stats.json +6 -0
  102. package/landing/tailwind.config.ts +12 -11
  103. package/landing/tsconfig.tsbuildinfo +1 -0
  104. package/package.json +21 -20
  105. package/scripts/SYMBOT-FIX.md +238 -0
  106. package/scripts/demo-simulation.py +177 -0
  107. package/scripts/expand-more.py +502 -0
  108. package/scripts/expand-registry.py +434 -0
  109. package/scripts/history-sanitizer.ts +272 -0
  110. package/scripts/mass-scrape.py +1308 -0
  111. package/scripts/sync-and-deploy.sh +36 -0
  112. package/src/credentials.ts +177 -0
  113. package/src/credits.ts +190 -122
  114. package/src/discovery.ts +45 -58
  115. package/src/execute.ts +350 -0
  116. package/src/index.ts +184 -32
  117. package/src/proxy.ts +24 -0
  118. package/src/registry/apis.json +95362 -202
  119. package/src/registry/apis_expanded.json +100853 -0
  120. package/src/stripe.ts +243 -0
  121. package/src/telemetry.ts +71 -0
  122. package/src/test.ts +127 -89
  123. package/src/types.ts +0 -34
  124. package/src/webhook.ts +107 -0
  125. package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
  126. package/BRIEFING.md +0 -30
  127. package/backend/convex/apiKeys.ts +0 -75
  128. package/backend/convex/purchases.ts +0 -74
  129. package/backend/convex/schema.ts +0 -45
  130. package/backend/convex/transactions.ts +0 -57
  131. package/backend/convex/users.ts +0 -94
  132. package/backend/package-lock.json +0 -521
  133. package/backend/package.json +0 -15
  134. package/dist/registry/parse_apis.py +0 -146
  135. package/dist/revenuecat.d.ts +0 -61
  136. package/dist/revenuecat.d.ts.map +0 -1
  137. package/dist/revenuecat.js +0 -166
  138. package/dist/revenuecat.js.map +0 -1
  139. package/dist/webhooks/revenuecat.d.ts +0 -48
  140. package/dist/webhooks/revenuecat.d.ts.map +0 -1
  141. package/dist/webhooks/revenuecat.js +0 -119
  142. package/dist/webhooks/revenuecat.js.map +0 -1
  143. package/docs/revenuecat-setup.md +0 -89
  144. package/landing/src/app/api/keys/route.ts +0 -71
  145. package/landing/src/app/api/log/route.ts +0 -37
  146. package/landing/src/app/api/stats/route.ts +0 -37
  147. package/landing/src/app/page.tsx.bak +0 -567
  148. package/landing/src/components/AddKeyModal.tsx +0 -159
  149. package/newsletter-template.html +0 -71
  150. package/outreach/OUTREACH-SYSTEM.md +0 -211
  151. package/outreach/email-template.html +0 -179
  152. package/outreach/targets.md +0 -133
  153. package/src/registry/parse_apis.py +0 -146
  154. package/src/revenuecat.ts +0 -239
  155. package/src/webhooks/revenuecat.ts +0 -187
  156. /package/{backend/convex → convex}/README.md +0 -0
  157. /package/{backend/convex → convex}/_generated/api.js +0 -0
  158. /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
  159. /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
  160. /package/{backend/convex → convex}/_generated/server.js +0 -0
  161. /package/{backend/convex → convex}/tsconfig.json +0 -0
@@ -0,0 +1,104 @@
1
+ import { mutation, query } from "./_generated/server";
2
+ import { v } from "convex/values";
3
+
4
+ // Rate limit config per tier
5
+ const LIMITS = {
6
+ free: {
7
+ discovery: 100, // searches per hour
8
+ instant: 10, // API calls per hour
9
+ },
10
+ subscriber: {
11
+ discovery: 1000,
12
+ instant: 100,
13
+ },
14
+ provider: {
15
+ discovery: 10000,
16
+ instant: 1000,
17
+ },
18
+ };
19
+
20
+ // Check and increment rate limit
21
+ export const checkLimit = mutation({
22
+ args: {
23
+ identifier: v.string(), // IP or agentId
24
+ action: v.union(v.literal("discovery"), v.literal("instant")),
25
+ tier: v.optional(v.union(v.literal("free"), v.literal("subscriber"), v.literal("provider"))),
26
+ },
27
+ handler: async (ctx, args) => {
28
+ const tier = args.tier || "free";
29
+ const limit = LIMITS[tier][args.action];
30
+ const hourKey = Math.floor(Date.now() / 3600000); // Hour bucket
31
+ const key = `${args.identifier}:${args.action}:${hourKey}`;
32
+
33
+ // Get current count
34
+ const existing = await ctx.db
35
+ .query("rateLimits")
36
+ .withIndex("by_key", (q) => q.eq("key", key))
37
+ .first();
38
+
39
+ if (existing) {
40
+ if (existing.count >= limit) {
41
+ return { allowed: false, remaining: 0, resetIn: 3600 - (Date.now() % 3600000) / 1000 };
42
+ }
43
+ await ctx.db.patch(existing._id, { count: existing.count + 1 });
44
+ return { allowed: true, remaining: limit - existing.count - 1 };
45
+ }
46
+
47
+ // Create new entry
48
+ await ctx.db.insert("rateLimits", {
49
+ key,
50
+ identifier: args.identifier,
51
+ action: args.action,
52
+ count: 1,
53
+ hourBucket: hourKey,
54
+ createdAt: Date.now(),
55
+ });
56
+
57
+ return { allowed: true, remaining: limit - 1 };
58
+ },
59
+ });
60
+
61
+ // Get current usage stats
62
+ export const getUsage = query({
63
+ args: {
64
+ identifier: v.string(),
65
+ },
66
+ handler: async (ctx, args) => {
67
+ const hourKey = Math.floor(Date.now() / 3600000);
68
+
69
+ const discovery = await ctx.db
70
+ .query("rateLimits")
71
+ .withIndex("by_key", (q) => q.eq("key", `${args.identifier}:discovery:${hourKey}`))
72
+ .first();
73
+
74
+ const instant = await ctx.db
75
+ .query("rateLimits")
76
+ .withIndex("by_key", (q) => q.eq("key", `${args.identifier}:instant:${hourKey}`))
77
+ .first();
78
+
79
+ return {
80
+ discovery: discovery?.count || 0,
81
+ instant: instant?.count || 0,
82
+ limits: LIMITS.free,
83
+ };
84
+ },
85
+ });
86
+
87
+ // Cleanup old rate limit entries (run via cron)
88
+ export const cleanup = mutation({
89
+ args: {},
90
+ handler: async (ctx) => {
91
+ const hourAgo = Math.floor(Date.now() / 3600000) - 2; // Keep 2 hours
92
+
93
+ const old = await ctx.db
94
+ .query("rateLimits")
95
+ .filter((q) => q.lt(q.field("hourBucket"), hourAgo))
96
+ .take(100);
97
+
98
+ for (const entry of old) {
99
+ await ctx.db.delete(entry._id);
100
+ }
101
+
102
+ return { deleted: old.length };
103
+ },
104
+ });
@@ -0,0 +1,220 @@
1
+ import { defineSchema, defineTable } from "convex/server";
2
+ import { v } from "convex/values";
3
+
4
+ export default defineSchema({
5
+ // Credits per agent
6
+ agentCredits: defineTable({
7
+ agentId: v.string(),
8
+ balanceUsd: v.number(),
9
+ currency: v.string(),
10
+ createdAt: v.number(),
11
+ updatedAt: v.number(),
12
+ }).index("by_agentId", ["agentId"]),
13
+
14
+ // Purchases (API access bought by agents)
15
+ purchases: defineTable({
16
+ agentId: v.string(),
17
+ providerId: v.string(),
18
+ amountUsd: v.number(),
19
+ creditsGranted: v.number(),
20
+ status: v.string(), // active, exhausted, refunded
21
+ credentials: v.optional(v.any()),
22
+ createdAt: v.number(),
23
+ })
24
+ .index("by_agentId", ["agentId"])
25
+ .index("by_providerId", ["providerId"])
26
+ .index("by_agentId_providerId", ["agentId", "providerId"]),
27
+
28
+ // Usage tracking per purchase
29
+ usage: defineTable({
30
+ purchaseId: v.id("purchases"),
31
+ providerId: v.string(),
32
+ unitsUsed: v.number(),
33
+ unitsRemaining: v.number(),
34
+ costIncurredUsd: v.number(),
35
+ lastUsedAt: v.number(),
36
+ })
37
+ .index("by_purchaseId", ["purchaseId"])
38
+ .index("by_providerId", ["providerId"]),
39
+
40
+ // Credit top-ups (from Stripe payments)
41
+ creditTopups: defineTable({
42
+ agentId: v.string(),
43
+ stripePaymentIntentId: v.optional(v.string()),
44
+ stripeSessionId: v.optional(v.string()),
45
+ amountUsd: v.number(),
46
+ creditsGranted: v.number(),
47
+ packageType: v.string(), // starter, growth, scale
48
+ status: v.string(), // pending, completed, failed
49
+ createdAt: v.number(),
50
+ completedAt: v.optional(v.number()),
51
+ })
52
+ .index("by_agentId", ["agentId"])
53
+ .index("by_stripeSessionId", ["stripeSessionId"])
54
+ .index("by_stripePaymentIntentId", ["stripePaymentIntentId"]),
55
+
56
+ // ============================================
57
+ // PROVIDER TABLES (for provider dashboard)
58
+ // ============================================
59
+
60
+ // API Providers (companies/individuals offering APIs)
61
+ providers: defineTable({
62
+ email: v.string(),
63
+ name: v.string(),
64
+ company: v.optional(v.string()),
65
+ website: v.optional(v.string()),
66
+ avatarUrl: v.optional(v.string()),
67
+ stripeConnectId: v.optional(v.string()), // for payouts
68
+ stripeOnboardingComplete: v.optional(v.boolean()),
69
+ status: v.string(), // pending, approved, rejected, suspended
70
+ createdAt: v.number(),
71
+ updatedAt: v.number(),
72
+ approvedAt: v.optional(v.number()),
73
+ })
74
+ .index("by_email", ["email"])
75
+ .index("by_stripeConnectId", ["stripeConnectId"])
76
+ .index("by_status", ["status"]),
77
+
78
+ // APIs listed by providers (self-service onboarding)
79
+ providerAPIs: defineTable({
80
+ providerId: v.id("providers"),
81
+ name: v.string(),
82
+ description: v.string(),
83
+ category: v.string(),
84
+ openApiUrl: v.optional(v.string()),
85
+ docsUrl: v.optional(v.string()),
86
+ pricingModel: v.string(), // free, freemium, paid
87
+ pricingNotes: v.optional(v.string()),
88
+ status: v.string(), // pending, approved, rejected, suspended
89
+ createdAt: v.number(),
90
+ approvedAt: v.optional(v.number()),
91
+ // Analytics
92
+ discoveryCount: v.optional(v.number()),
93
+ lastDiscoveredAt: v.optional(v.number()),
94
+ })
95
+ .index("by_providerId", ["providerId"])
96
+ .index("by_category", ["category"])
97
+ .index("by_status", ["status"])
98
+ .index("by_status_category", ["status", "category"]),
99
+
100
+ // APIs listed by providers (for full dashboard)
101
+ apis: defineTable({
102
+ providerId: v.id("providers"),
103
+ name: v.string(),
104
+ description: v.string(),
105
+ category: v.string(),
106
+ icon: v.optional(v.string()), // emoji or URL
107
+ baseUrl: v.string(),
108
+ docsUrl: v.optional(v.string()),
109
+ authType: v.string(), // api_key, oauth, basic, bearer
110
+ pricingModel: v.string(), // free, per_call, monthly, credits
111
+ pricePerCall: v.optional(v.number()), // in USD cents
112
+ monthlyPrice: v.optional(v.number()), // in USD cents
113
+ rateLimitPerMinute: v.optional(v.number()),
114
+ regions: v.optional(v.array(v.string())),
115
+ tags: v.optional(v.array(v.string())),
116
+ status: v.string(), // active, paused, pending_review
117
+ isPublic: v.boolean(),
118
+ // Credentials (encrypted in production)
119
+ credentialTemplate: v.optional(v.any()),
120
+ createdAt: v.number(),
121
+ updatedAt: v.number(),
122
+ })
123
+ .index("by_providerId", ["providerId"])
124
+ .index("by_category", ["category"])
125
+ .index("by_status", ["status"]),
126
+
127
+ // API Calls / Usage logs (for analytics)
128
+ apiCalls: defineTable({
129
+ apiId: v.id("apis"),
130
+ providerId: v.id("providers"),
131
+ agentId: v.string(),
132
+ endpoint: v.optional(v.string()),
133
+ method: v.optional(v.string()),
134
+ statusCode: v.optional(v.number()),
135
+ latencyMs: v.optional(v.number()),
136
+ costUsd: v.number(), // cost in USD (fractional)
137
+ region: v.optional(v.string()),
138
+ timestamp: v.number(),
139
+ })
140
+ .index("by_apiId", ["apiId"])
141
+ .index("by_providerId", ["providerId"])
142
+ .index("by_agentId", ["agentId"])
143
+ .index("by_timestamp", ["timestamp"])
144
+ .index("by_providerId_timestamp", ["providerId", "timestamp"]),
145
+
146
+ // Provider Payouts
147
+ payouts: defineTable({
148
+ providerId: v.id("providers"),
149
+ amountUsd: v.number(),
150
+ status: v.string(), // pending, processing, completed, failed
151
+ stripePayoutId: v.optional(v.string()),
152
+ periodStart: v.number(),
153
+ periodEnd: v.number(),
154
+ createdAt: v.number(),
155
+ completedAt: v.optional(v.number()),
156
+ })
157
+ .index("by_providerId", ["providerId"])
158
+ .index("by_status", ["status"]),
159
+
160
+ // Magic link tokens for email auth
161
+ magicLinks: defineTable({
162
+ email: v.string(),
163
+ token: v.string(),
164
+ expiresAt: v.number(),
165
+ usedAt: v.optional(v.number()),
166
+ createdAt: v.number(),
167
+ })
168
+ .index("by_token", ["token"])
169
+ .index("by_email", ["email"]),
170
+
171
+ // Sessions for authenticated providers
172
+ sessions: defineTable({
173
+ providerId: v.id("providers"),
174
+ token: v.string(),
175
+ expiresAt: v.number(),
176
+ createdAt: v.number(),
177
+ })
178
+ .index("by_token", ["token"])
179
+ .index("by_providerId", ["providerId"]),
180
+
181
+ // Rate limiting
182
+ rateLimits: defineTable({
183
+ key: v.string(),
184
+ identifier: v.string(),
185
+ action: v.string(),
186
+ count: v.number(),
187
+ hourBucket: v.number(),
188
+ createdAt: v.number(),
189
+ })
190
+ .index("by_key", ["key"])
191
+ .index("by_identifier", ["identifier"]),
192
+
193
+ // Usage analytics
194
+ analytics: defineTable({
195
+ event: v.string(), // "discovery", "instant", "search_query"
196
+ provider: v.optional(v.string()),
197
+ query: v.optional(v.string()),
198
+ identifier: v.string(),
199
+ metadata: v.optional(v.any()),
200
+ timestamp: v.number(),
201
+ })
202
+ .index("by_event", ["event"])
203
+ .index("by_timestamp", ["timestamp"])
204
+ .index("by_provider", ["provider"]),
205
+
206
+ // MCP Server telemetry (anonymous usage tracking)
207
+ telemetry: defineTable({
208
+ type: v.string(), // "startup", "search", "execute", "discovery"
209
+ query: v.optional(v.string()),
210
+ apiId: v.optional(v.string()),
211
+ resultCount: v.optional(v.number()),
212
+ responseTimeMs: v.optional(v.number()),
213
+ version: v.string(),
214
+ platform: v.string(),
215
+ nodeVersion: v.string(),
216
+ timestamp: v.number(),
217
+ })
218
+ .index("by_type", ["type"])
219
+ .index("by_timestamp", ["timestamp"]),
220
+ });
@@ -0,0 +1,81 @@
1
+ import { mutation, query } from "./_generated/server";
2
+ import { v } from "convex/values";
3
+
4
+ export const track = mutation({
5
+ args: {
6
+ event: v.object({
7
+ type: v.string(),
8
+ query: v.optional(v.string()),
9
+ apiId: v.optional(v.string()),
10
+ resultCount: v.optional(v.number()),
11
+ responseTimeMs: v.optional(v.number()),
12
+ version: v.optional(v.string()),
13
+ platform: v.optional(v.string()),
14
+ nodeVersion: v.optional(v.string()),
15
+ timestamp: v.optional(v.number()),
16
+ }),
17
+ },
18
+ handler: async (ctx, { event }) => {
19
+ await ctx.db.insert("telemetry", {
20
+ type: event.type,
21
+ query: event.query,
22
+ apiId: event.apiId,
23
+ resultCount: event.resultCount,
24
+ responseTimeMs: event.responseTimeMs,
25
+ version: event.version || "unknown",
26
+ platform: event.platform || "unknown",
27
+ nodeVersion: event.nodeVersion || "unknown",
28
+ timestamp: event.timestamp || Date.now(),
29
+ });
30
+ },
31
+ });
32
+
33
+ export const getStats = query({
34
+ args: {},
35
+ handler: async (ctx) => {
36
+ const events = await ctx.db.query("telemetry").collect();
37
+
38
+ const startups = events.filter(e => e.type === "startup").length;
39
+ const searches = events.filter(e => e.type === "search").length;
40
+ const executes = events.filter(e => e.type === "execute").length;
41
+
42
+ const uniqueUsers = new Set(events.map(e => `${e.platform}-${e.nodeVersion}`)).size;
43
+
44
+ const topQueries = events
45
+ .filter(e => e.type === "search" && e.query)
46
+ .reduce((acc, e) => {
47
+ acc[e.query!] = (acc[e.query!] || 0) + 1;
48
+ return acc;
49
+ }, {} as Record<string, number>);
50
+
51
+ const topAPIs = events
52
+ .filter(e => e.type === "execute" && e.apiId)
53
+ .reduce((acc, e) => {
54
+ acc[e.apiId!] = (acc[e.apiId!] || 0) + 1;
55
+ return acc;
56
+ }, {} as Record<string, number>);
57
+
58
+ return {
59
+ totalStartups: startups,
60
+ totalSearches: searches,
61
+ totalExecutes: executes,
62
+ estimatedUniqueUsers: uniqueUsers,
63
+ topQueries: Object.entries(topQueries)
64
+ .sort(([,a], [,b]) => b - a)
65
+ .slice(0, 10),
66
+ topAPIs: Object.entries(topAPIs)
67
+ .sort(([,a], [,b]) => b - a)
68
+ .slice(0, 10),
69
+ };
70
+ },
71
+ });
72
+
73
+ export const getRecent = query({
74
+ args: { limit: v.optional(v.number()) },
75
+ handler: async (ctx, { limit = 50 }) => {
76
+ return await ctx.db
77
+ .query("telemetry")
78
+ .order("desc")
79
+ .take(limit);
80
+ },
81
+ });
package/convex.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "functions": "convex/"
3
+ }
@@ -0,0 +1,19 @@
1
+ import { APICredentials } from './types.js';
2
+ /**
3
+ * Get real credentials for a provider
4
+ * Returns null if provider not supported
5
+ */
6
+ export declare function getCredentials(providerId: string): APICredentials | null;
7
+ /**
8
+ * Check if a provider has real (non-demo) credentials available
9
+ */
10
+ export declare function hasRealCredentials(providerId: string): boolean;
11
+ /**
12
+ * List all supported providers
13
+ */
14
+ export declare function listProviders(): string[];
15
+ /**
16
+ * Get credential type for a provider
17
+ */
18
+ export declare function getCredentialType(providerId: string): string | null;
19
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqH5C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAIxE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA0B9D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnE"}
@@ -0,0 +1,158 @@
1
+ // Real credential providers for APIClaw Connected tier
2
+ // Reads from environment variables or ~/.secrets/
3
+ import { readFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ // Load env file helper
7
+ function loadEnvFile(filename) {
8
+ const paths = [
9
+ join(homedir(), '.secrets', filename),
10
+ join(process.cwd(), filename),
11
+ join(process.cwd(), '.env.local'),
12
+ ];
13
+ for (const path of paths) {
14
+ if (existsSync(path)) {
15
+ const content = readFileSync(path, 'utf-8');
16
+ const vars = {};
17
+ for (const line of content.split('\n')) {
18
+ const match = line.match(/^([^=]+)=(.*)$/);
19
+ if (match) {
20
+ vars[match[1].trim()] = match[2].trim().replace(/^["']|["']$/g, '');
21
+ }
22
+ }
23
+ return vars;
24
+ }
25
+ }
26
+ return {};
27
+ }
28
+ // Provider credential getters
29
+ const providers = {
30
+ '46elks': {
31
+ type: 'basic',
32
+ get() {
33
+ const env = loadEnvFile('46elks.env');
34
+ const user = env.ELKS_API_USER || process.env.ELKS_API_USER;
35
+ const pass = env.ELKS_API_PASSWORD || process.env.ELKS_API_PASSWORD;
36
+ if (!user || !pass)
37
+ return null;
38
+ return {
39
+ type: 'basic',
40
+ username: user,
41
+ password: pass,
42
+ };
43
+ },
44
+ },
45
+ twilio: {
46
+ type: 'basic',
47
+ get() {
48
+ const env = loadEnvFile('twilio.env');
49
+ const sid = env.TWILIO_ACCOUNT_SID || process.env.TWILIO_ACCOUNT_SID;
50
+ const token = env.TWILIO_AUTH_TOKEN || process.env.TWILIO_AUTH_TOKEN;
51
+ if (!sid || !token)
52
+ return null;
53
+ return {
54
+ type: 'basic',
55
+ username: sid,
56
+ password: token,
57
+ };
58
+ },
59
+ },
60
+ // Real credential providers
61
+ resend: {
62
+ type: 'api_key',
63
+ get() {
64
+ const env = loadEnvFile('resend.env');
65
+ const key = env.RESEND_API_KEY || process.env.RESEND_API_KEY;
66
+ if (key) {
67
+ return { type: 'api_key', api_key: key };
68
+ }
69
+ return null;
70
+ },
71
+ },
72
+ brave_search: {
73
+ type: 'api_key',
74
+ get() {
75
+ const env = loadEnvFile('brave.env');
76
+ const key = env.BRAVE_API_KEY || process.env.BRAVE_API_KEY;
77
+ if (key) {
78
+ return { type: 'api_key', api_key: key };
79
+ }
80
+ return null;
81
+ },
82
+ },
83
+ openrouter: {
84
+ type: 'bearer',
85
+ get() {
86
+ const env = loadEnvFile('openrouter.env');
87
+ const key = env.OPENROUTER_API_KEY || process.env.OPENROUTER_API_KEY;
88
+ if (key) {
89
+ return { type: 'bearer', api_key: key };
90
+ }
91
+ return null;
92
+ },
93
+ },
94
+ elevenlabs: {
95
+ type: 'api_key',
96
+ get() {
97
+ const env = loadEnvFile('elevenlabs.env');
98
+ const key = env.ELEVENLABS_API_KEY || process.env.ELEVENLABS_API_KEY;
99
+ if (key) {
100
+ return { type: 'api_key', api_key: key };
101
+ }
102
+ return null;
103
+ },
104
+ },
105
+ };
106
+ /**
107
+ * Get real credentials for a provider
108
+ * Returns null if provider not supported
109
+ */
110
+ export function getCredentials(providerId) {
111
+ const provider = providers[providerId];
112
+ if (!provider)
113
+ return null;
114
+ return provider.get();
115
+ }
116
+ /**
117
+ * Check if a provider has real (non-demo) credentials available
118
+ */
119
+ export function hasRealCredentials(providerId) {
120
+ if (providerId === '46elks') {
121
+ const env = loadEnvFile('46elks.env');
122
+ return !!(env.ELKS_API_USER || process.env.ELKS_API_USER);
123
+ }
124
+ if (providerId === 'twilio') {
125
+ const env = loadEnvFile('twilio.env');
126
+ return !!(env.TWILIO_ACCOUNT_SID || process.env.TWILIO_ACCOUNT_SID);
127
+ }
128
+ if (providerId === 'resend') {
129
+ const env = loadEnvFile('resend.env');
130
+ return !!(env.RESEND_API_KEY || process.env.RESEND_API_KEY);
131
+ }
132
+ if (providerId === 'brave_search') {
133
+ const env = loadEnvFile('brave.env');
134
+ return !!(env.BRAVE_API_KEY || process.env.BRAVE_API_KEY);
135
+ }
136
+ if (providerId === 'openrouter') {
137
+ const env = loadEnvFile('openrouter.env');
138
+ return !!(env.OPENROUTER_API_KEY || process.env.OPENROUTER_API_KEY);
139
+ }
140
+ if (providerId === 'elevenlabs') {
141
+ const env = loadEnvFile('elevenlabs.env');
142
+ return !!(env.ELEVENLABS_API_KEY || process.env.ELEVENLABS_API_KEY);
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * List all supported providers
148
+ */
149
+ export function listProviders() {
150
+ return Object.keys(providers);
151
+ }
152
+ /**
153
+ * Get credential type for a provider
154
+ */
155
+ export function getCredentialType(providerId) {
156
+ return providers[providerId]?.type || null;
157
+ }
158
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
package/dist/credits.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { AgentCredits, Purchase, UsageRecord, TransactionFee } from './types.js';
1
+ import { AgentCredits, Purchase, UsageRecord } from './types.js';
2
+ type StorageBackend = 'memory' | 'convex';
2
3
  /**
3
4
  * Get or create agent credits account
4
5
  */
@@ -9,7 +10,7 @@ export declare function getAgentCredits(agentId: string): AgentCredits;
9
10
  export declare function addCredits(agentId: string, amountUsd: number): AgentCredits;
10
11
  /**
11
12
  * Purchase API access
12
- * Returns credentials if successful
13
+ * Returns real credentials for 46elks and Twilio
13
14
  */
14
15
  export declare function purchaseAPIAccess(agentId: string, providerId: string, amountUsd: number): {
15
16
  success: boolean;
@@ -35,20 +36,22 @@ export declare function getBalanceSummary(agentId: string): {
35
36
  credits: AgentCredits;
36
37
  active_purchases: Purchase[];
37
38
  total_spent_usd: number;
39
+ real_credentials_available: string[];
38
40
  };
39
41
  /**
40
- * Calculate transaction fee based on user's subscription
41
- * Pro users: 2% fee
42
- * Free users: 5% fee
42
+ * Check which providers have real credentials
43
43
  */
44
- export declare function calculateTransactionFee(userId: string, amountUsd: number): Promise<TransactionFee>;
45
- /**
46
- * Purchase API access with subscription-aware fees
47
- */
48
- export declare function purchaseAPIAccessWithFees(agentId: string, userId: string, providerId: string, amountUsd: number): Promise<{
44
+ export declare function getProvidersWithRealCredentials(): string[];
45
+ export declare function getAgentCreditsAsync(agentId: string): Promise<AgentCredits | null>;
46
+ export declare function addCreditsAsync(agentId: string, amountUsd: number): Promise<AgentCredits | null>;
47
+ export declare function purchaseAPIAccessAsync(agentId: string, providerId: string, amountUsd: number): Promise<{
49
48
  success: boolean;
50
49
  purchase?: Purchase;
51
- fee?: TransactionFee;
52
50
  error?: string;
53
51
  }>;
52
+ export declare function getBackendInfo(): {
53
+ type: StorageBackend;
54
+ convexUrl: string | null;
55
+ };
56
+ export {};
54
57
  //# sourceMappingURL=credits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../src/credits.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAkB,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkCjG;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAW7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAK3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiD3D;AAkBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAE7D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAgBtG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAClD,OAAO,EAAE,YAAY,CAAC;IACtB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;CACzB,CAWA;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAYzB;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAgCD"}
1
+ {"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../src/credits.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAkB,WAAW,EAAE,MAAM,YAAY,CAAC;AAKjF,KAAK,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAwD1C;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAW7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAK3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAyD3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAE7D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAgBtG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAClD,OAAO,EAAE,YAAY,CAAC;IACtB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,0BAA0B,EAAE,MAAM,EAAE,CAAC;CACtC,CAeA;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,EAAE,CAE1D;AAwDD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOxF;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOtG;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBpE;AAGD,wBAAgB,cAAc,IAAI;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAKnF"}