moltlaunch 2.0.0 → 2.0.2

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 (108) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +18 -18
  3. package/dist/index.js.map +1 -1
  4. package/package.json +6 -2
  5. package/.claude/commands/deploy.md +0 -33
  6. package/.claude/hooks/regenerate-docs.sh +0 -12
  7. package/.claude/settings.json +0 -15
  8. package/.env.example +0 -2
  9. package/.github/workflows/deploy.yml +0 -37
  10. package/ROADMAP.md +0 -29
  11. package/contracts/MandateEscrowV4.sol +0 -281
  12. package/contracts/mocks/MockFlaunchBuyback.sol +0 -24
  13. package/hardhat.config.cjs +0 -29
  14. package/scripts/check-deploy-cost.ts +0 -15
  15. package/scripts/deploy-escrow-v4.ts +0 -81
  16. package/scripts/deploy-escrow.cjs +0 -22
  17. package/scripts/generate-docs.ts +0 -309
  18. package/shared/manifest.json +0 -87
  19. package/site/.vscode/extensions.json +0 -4
  20. package/site/.vscode/launch.json +0 -11
  21. package/site/README.md +0 -43
  22. package/site/astro.config.mjs +0 -21
  23. package/site/functions/agent/[[path]].ts +0 -9
  24. package/site/functions/task/[[path]].ts +0 -9
  25. package/site/index.html.bak +0 -1755
  26. package/site/package-lock.json +0 -6165
  27. package/site/package.json +0 -17
  28. package/site/public/_redirects +0 -1
  29. package/site/public/art/hero.webp +0 -0
  30. package/site/public/favicon.ico +0 -0
  31. package/site/public/favicon.svg +0 -4
  32. package/site/public/logo.png +0 -0
  33. package/site/public/skill.md +0 -276
  34. package/site/src/components/AgentGridCard.astro +0 -97
  35. package/site/src/components/AgentRow.astro +0 -75
  36. package/site/src/components/Footer.astro +0 -71
  37. package/site/src/components/GigCard.astro +0 -36
  38. package/site/src/components/Navbar.astro +0 -93
  39. package/site/src/components/ReviewCard.astro +0 -29
  40. package/site/src/components/SkillPill.astro +0 -19
  41. package/site/src/components/StatusBadge.astro +0 -27
  42. package/site/src/components/TaskEntry.astro +0 -98
  43. package/site/src/layouts/Layout.astro +0 -268
  44. package/site/src/lib/api.ts +0 -342
  45. package/site/src/pages/404.astro +0 -33
  46. package/site/src/pages/admin.astro +0 -445
  47. package/site/src/pages/agent/[...id].astro +0 -678
  48. package/site/src/pages/agents/index.astro +0 -235
  49. package/site/src/pages/dashboard.astro +0 -244
  50. package/site/src/pages/docs.astro +0 -191
  51. package/site/src/pages/how.astro +0 -156
  52. package/site/src/pages/index.astro +0 -226
  53. package/site/src/pages/leaderboard.astro +0 -155
  54. package/site/src/pages/task/[...id].astro +0 -1467
  55. package/site/src/styles/global.css +0 -159
  56. package/site/tailwind.config.mjs +0 -94
  57. package/site/tsconfig.json +0 -5
  58. package/site/wrangler.toml +0 -5
  59. package/src/commands/accept.ts +0 -135
  60. package/src/commands/agents.ts +0 -190
  61. package/src/commands/approve.ts +0 -127
  62. package/src/commands/claim.ts +0 -130
  63. package/src/commands/decline.ts +0 -55
  64. package/src/commands/dispute.ts +0 -92
  65. package/src/commands/earnings.ts +0 -86
  66. package/src/commands/feedback.ts +0 -147
  67. package/src/commands/gig.ts +0 -141
  68. package/src/commands/hire.ts +0 -96
  69. package/src/commands/inbox.ts +0 -135
  70. package/src/commands/message.ts +0 -97
  71. package/src/commands/profile.ts +0 -62
  72. package/src/commands/quote.ts +0 -80
  73. package/src/commands/refund.ts +0 -82
  74. package/src/commands/register.ts +0 -250
  75. package/src/commands/resolve.ts +0 -104
  76. package/src/commands/reviews.ts +0 -78
  77. package/src/commands/revise.ts +0 -65
  78. package/src/commands/submit.ts +0 -123
  79. package/src/commands/tasks.ts +0 -224
  80. package/src/commands/view.ts +0 -122
  81. package/src/commands/wallet.ts +0 -42
  82. package/src/index.ts +0 -285
  83. package/src/lib/agent0.ts +0 -158
  84. package/src/lib/auth.ts +0 -25
  85. package/src/lib/constants.ts +0 -55
  86. package/src/lib/escrow.ts +0 -374
  87. package/src/lib/files.ts +0 -87
  88. package/src/lib/flaunch.ts +0 -277
  89. package/src/lib/mandate.ts +0 -623
  90. package/src/lib/tasks.ts +0 -466
  91. package/src/lib/types.ts +0 -112
  92. package/src/lib/wallet.ts +0 -119
  93. package/src/lib/x402.ts +0 -86
  94. package/test/MandateEscrowV4.test.cjs +0 -568
  95. package/tsconfig.json +0 -19
  96. package/tsup.config.ts +0 -15
  97. package/worker/package-lock.json +0 -1812
  98. package/worker/package.json +0 -18
  99. package/worker/src/agents.ts +0 -755
  100. package/worker/src/auth.ts +0 -126
  101. package/worker/src/files.ts +0 -40
  102. package/worker/src/index.ts +0 -963
  103. package/worker/src/profiles.ts +0 -85
  104. package/worker/src/ratelimit.ts +0 -45
  105. package/worker/src/tasks.ts +0 -498
  106. package/worker/src/types.ts +0 -95
  107. package/worker/tsconfig.json +0 -15
  108. package/worker/wrangler.toml +0 -19
@@ -1,126 +0,0 @@
1
- // Wallet signature verification for agent/client actions
2
- // EIP-191 personal sign: moltlaunch:<action>:<taskId>:<timestamp>:<nonce>
3
-
4
- import { recoverMessageAddress, keccak256, toBytes } from 'viem';
5
- import type { Env } from './types';
6
-
7
- const IDENTITY_REGISTRY = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432';
8
- const ESCROW_ADDRESS = '0x2c46054b4577b4fcdde28cb613dc2ba4b1127b0c';
9
- const OWNER_SELECTOR = '0x6352211e'; // ownerOf(uint256)
10
- const GET_ESCROW_SELECTOR = '0xf023b811'; // getEscrow(bytes32)
11
- const MAX_TIMESTAMP_DRIFT = 300; // 5 minutes
12
- const OWNER_CACHE_PREFIX = 'owner:';
13
- const OWNER_CACHE_TTL = 86400; // 24 hours
14
- const NONCE_PREFIX = 'nonce:';
15
-
16
- /** Build the message that must be signed */
17
- export function buildAuthMessage(action: string, taskId: string, timestamp: number, nonce: string): string {
18
- return `moltlaunch:${action}:${taskId}:${timestamp}:${nonce}`;
19
- }
20
-
21
- /** Verify signature, check nonce for replay protection, return recovered signer (lowercase) */
22
- export async function verifySigner(
23
- env: Env,
24
- action: string,
25
- taskId: string,
26
- timestamp: number,
27
- signature: string,
28
- nonce: string,
29
- ): Promise<string> {
30
- const now = Math.floor(Date.now() / 1000);
31
- if (Math.abs(now - timestamp) > MAX_TIMESTAMP_DRIFT) {
32
- throw new Error('Signature expired');
33
- }
34
-
35
- if (!nonce) {
36
- throw new Error('Missing nonce');
37
- }
38
-
39
- const message = buildAuthMessage(action, taskId, timestamp, nonce);
40
- const address = await recoverMessageAddress({
41
- message,
42
- signature: signature as `0x${string}`,
43
- });
44
-
45
- // Replay protection: check if nonce was already used
46
- const nonceKey = `${NONCE_PREFIX}${keccak256(toBytes(nonce))}`;
47
- const existing = await env.TASKS_KV.get(nonceKey);
48
- if (existing) {
49
- throw new Error('Nonce already used (replay detected)');
50
- }
51
-
52
- // Store nonce with TTL matching timestamp drift window
53
- await env.TASKS_KV.put(nonceKey, '1', { expirationTtl: MAX_TIMESTAMP_DRIFT });
54
-
55
- return address.toLowerCase();
56
- }
57
-
58
- /** Get agent owner address via ownerOf() call (cached in KV for 24h) */
59
- export async function getAgentOwner(env: Env, agentId: string): Promise<string> {
60
- const cacheKey = `${OWNER_CACHE_PREFIX}${agentId}`;
61
- const cached = await env.TASKS_KV.get(cacheKey);
62
- if (cached) return cached.toLowerCase();
63
-
64
- const rpcUrl = env.ALCHEMY_RPC || env.BASE_RPC || 'https://mainnet.base.org';
65
- const id = agentId.startsWith('0x') ? BigInt(agentId) : BigInt(agentId);
66
- const agentIdHex = id.toString(16).padStart(64, '0');
67
-
68
- const res = await fetch(rpcUrl, {
69
- method: 'POST',
70
- headers: { 'Content-Type': 'application/json' },
71
- body: JSON.stringify({
72
- jsonrpc: '2.0',
73
- method: 'eth_call',
74
- params: [{ to: IDENTITY_REGISTRY, data: OWNER_SELECTOR + agentIdHex }, 'latest'],
75
- id: 1,
76
- }),
77
- });
78
-
79
- const json = await res.json() as { result?: string; error?: { message: string } };
80
- if (json.error || !json.result || json.result === '0x') {
81
- throw new Error('Failed to get agent owner');
82
- }
83
-
84
- const owner = ('0x' + json.result.slice(-40)).toLowerCase();
85
- await env.TASKS_KV.put(cacheKey, owner, { expirationTtl: OWNER_CACHE_TTL });
86
- return owner;
87
- }
88
-
89
- /**
90
- * Verify that escrow deposit exists on-chain for a task.
91
- * Returns the deposited amount in wei, or 0 if no deposit or already released.
92
- * getEscrow returns: (client, agent, token, amount, depositedAt, submittedAt, disputeFee, status)
93
- */
94
- export async function verifyEscrowDeposit(env: Env, taskId: string): Promise<bigint> {
95
- const rpcUrl = env.ALCHEMY_RPC || env.BASE_RPC || 'https://mainnet.base.org';
96
- const taskIdBytes32 = keccak256(toBytes(taskId));
97
- const taskIdHex = taskIdBytes32.slice(2);
98
-
99
- const res = await fetch(rpcUrl, {
100
- method: 'POST',
101
- headers: { 'Content-Type': 'application/json' },
102
- body: JSON.stringify({
103
- jsonrpc: '2.0',
104
- method: 'eth_call',
105
- params: [{ to: ESCROW_ADDRESS, data: GET_ESCROW_SELECTOR + taskIdHex }, 'latest'],
106
- id: 1,
107
- }),
108
- });
109
-
110
- const json = await res.json() as { result?: string; error?: { message: string } };
111
- if (json.error || !json.result || json.result === '0x') {
112
- return 0n;
113
- }
114
-
115
- // V4: status is the 8th 32-byte word (offset 224 bytes = 448 hex chars) — uint8 enum
116
- // Active=0, Submitted=1, Disputed=2, Resolved=3, Released=4, Refunded=5
117
- const statusHex = json.result.slice(2 + 64 * 7, 2 + 64 * 8);
118
- const status = Number(BigInt('0x' + (statusHex || '0')));
119
- if (status >= 4) {
120
- return 0n; // Released or Refunded, treat as no deposit
121
- }
122
-
123
- // amount is the 4th 32-byte word (offset 96 bytes = 192 hex chars)
124
- const amountHex = json.result.slice(2 + 64 * 3, 2 + 64 * 4);
125
- return BigInt('0x' + (amountHex || '0'));
126
- }
@@ -1,40 +0,0 @@
1
- // R2 file upload/download handlers for task file exchange
2
- // Files stored at key: tasks/<taskId>/<timestamp>-<filename>
3
-
4
- import type { Env, TaskFile } from './types';
5
-
6
- const MAX_FILE_SIZE = 25 * 1024 * 1024; // 25MB
7
-
8
- /** Upload a file to R2, return metadata */
9
- export async function uploadFile(
10
- env: Env,
11
- taskId: string,
12
- filename: string,
13
- body: ReadableStream | ArrayBuffer,
14
- contentType: string,
15
- size: number,
16
- ): Promise<TaskFile> {
17
- if (size > MAX_FILE_SIZE) {
18
- throw new Error(`File too large: ${size} bytes (max ${MAX_FILE_SIZE})`);
19
- }
20
-
21
- const timestamp = Date.now();
22
- // Sanitize filename to prevent path traversal
23
- const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '_');
24
- const key = `tasks/${taskId}/${timestamp}-${safeName}`;
25
-
26
- await env.TASK_FILES.put(key, body, {
27
- httpMetadata: { contentType },
28
- customMetadata: { taskId, originalName: filename },
29
- });
30
-
31
- return { key, name: filename, size, uploadedAt: timestamp };
32
- }
33
-
34
- /** Download a file from R2, return the R2 object (or null) */
35
- export async function downloadFile(
36
- env: Env,
37
- key: string,
38
- ): Promise<R2ObjectBody | null> {
39
- return env.TASK_FILES.get(key);
40
- }