plotlink-ows 0.1.13

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 (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/app/db.ts +8 -0
  4. package/app/lib/llm-client.ts +265 -0
  5. package/app/lib/paths.ts +11 -0
  6. package/app/lib/publish.ts +204 -0
  7. package/app/lib/writer-prompt.ts +44 -0
  8. package/app/node_modules/.prisma/local-client/client.d.ts +1 -0
  9. package/app/node_modules/.prisma/local-client/client.js +5 -0
  10. package/app/node_modules/.prisma/local-client/default.d.ts +1 -0
  11. package/app/node_modules/.prisma/local-client/default.js +5 -0
  12. package/app/node_modules/.prisma/local-client/edge.d.ts +1 -0
  13. package/app/node_modules/.prisma/local-client/edge.js +184 -0
  14. package/app/node_modules/.prisma/local-client/index-browser.js +173 -0
  15. package/app/node_modules/.prisma/local-client/index.d.ts +3304 -0
  16. package/app/node_modules/.prisma/local-client/index.js +207 -0
  17. package/app/node_modules/.prisma/local-client/libquery_engine-darwin-arm64.dylib.node +0 -0
  18. package/app/node_modules/.prisma/local-client/package.json +183 -0
  19. package/app/node_modules/.prisma/local-client/query_engine_bg.js +2 -0
  20. package/app/node_modules/.prisma/local-client/query_engine_bg.wasm +0 -0
  21. package/app/node_modules/.prisma/local-client/runtime/edge-esm.js +35 -0
  22. package/app/node_modules/.prisma/local-client/runtime/edge.js +35 -0
  23. package/app/node_modules/.prisma/local-client/runtime/index-browser.d.ts +370 -0
  24. package/app/node_modules/.prisma/local-client/runtime/index-browser.js +17 -0
  25. package/app/node_modules/.prisma/local-client/runtime/library.d.ts +3982 -0
  26. package/app/node_modules/.prisma/local-client/runtime/library.js +147 -0
  27. package/app/node_modules/.prisma/local-client/runtime/react-native.js +84 -0
  28. package/app/node_modules/.prisma/local-client/runtime/wasm-compiler-edge.js +85 -0
  29. package/app/node_modules/.prisma/local-client/runtime/wasm-engine-edge.js +38 -0
  30. package/app/node_modules/.prisma/local-client/schema.prisma +21 -0
  31. package/app/node_modules/.prisma/local-client/wasm-edge-light-loader.mjs +5 -0
  32. package/app/node_modules/.prisma/local-client/wasm-worker-loader.mjs +5 -0
  33. package/app/node_modules/.prisma/local-client/wasm.d.ts +1 -0
  34. package/app/node_modules/.prisma/local-client/wasm.js +191 -0
  35. package/app/prisma/schema.prisma +57 -0
  36. package/app/routes/auth.ts +173 -0
  37. package/app/routes/chat.ts +135 -0
  38. package/app/routes/config.ts +210 -0
  39. package/app/routes/dashboard.ts +186 -0
  40. package/app/routes/oauth.ts +150 -0
  41. package/app/routes/publish.ts +112 -0
  42. package/app/routes/wallet.ts +99 -0
  43. package/app/server.ts +154 -0
  44. package/app/vite.config.ts +19 -0
  45. package/app/web/App.tsx +102 -0
  46. package/app/web/components/Chat.tsx +272 -0
  47. package/app/web/components/Dashboard.tsx +222 -0
  48. package/app/web/components/LLMSetup.tsx +291 -0
  49. package/app/web/components/Layout.tsx +235 -0
  50. package/app/web/components/Login.tsx +62 -0
  51. package/app/web/components/Publish.tsx +245 -0
  52. package/app/web/components/Settings.tsx +175 -0
  53. package/app/web/components/Setup.tsx +84 -0
  54. package/app/web/components/WalletCard.tsx +117 -0
  55. package/app/web/dist/assets/index-C9kXlYO_.css +2 -0
  56. package/app/web/dist/assets/index-CJiiaLHs.js +9 -0
  57. package/app/web/dist/index.html +16 -0
  58. package/app/web/index.html +15 -0
  59. package/app/web/main.tsx +10 -0
  60. package/app/web/plotlink-logo.svg +5 -0
  61. package/app/web/styles.css +51 -0
  62. package/bin/plotlink-ows.js +394 -0
  63. package/lib/ows/index.ts +3 -0
  64. package/lib/ows/policy.ts +68 -0
  65. package/lib/ows/types.ts +14 -0
  66. package/lib/ows/wallet.ts +70 -0
  67. package/package.json +79 -0
  68. package/packages/cli/node_modules/commander/LICENSE +22 -0
  69. package/packages/cli/node_modules/commander/Readme.md +1149 -0
  70. package/packages/cli/node_modules/commander/esm.mjs +16 -0
  71. package/packages/cli/node_modules/commander/index.js +24 -0
  72. package/packages/cli/node_modules/commander/lib/argument.js +149 -0
  73. package/packages/cli/node_modules/commander/lib/command.js +2662 -0
  74. package/packages/cli/node_modules/commander/lib/error.js +39 -0
  75. package/packages/cli/node_modules/commander/lib/help.js +709 -0
  76. package/packages/cli/node_modules/commander/lib/option.js +367 -0
  77. package/packages/cli/node_modules/commander/lib/suggestSimilar.js +101 -0
  78. package/packages/cli/node_modules/commander/package-support.json +16 -0
  79. package/packages/cli/node_modules/commander/package.json +82 -0
  80. package/packages/cli/node_modules/commander/typings/esm.d.mts +3 -0
  81. package/packages/cli/node_modules/commander/typings/index.d.ts +1045 -0
  82. package/packages/cli/node_modules/resolve-from/index.d.ts +31 -0
  83. package/packages/cli/node_modules/resolve-from/index.js +47 -0
  84. package/packages/cli/node_modules/resolve-from/license +9 -0
  85. package/packages/cli/node_modules/resolve-from/package.json +36 -0
  86. package/packages/cli/node_modules/resolve-from/readme.md +72 -0
  87. package/packages/cli/node_modules/tsup/LICENSE +21 -0
  88. package/packages/cli/node_modules/tsup/README.md +75 -0
  89. package/packages/cli/node_modules/tsup/assets/cjs_shims.js +13 -0
  90. package/packages/cli/node_modules/tsup/assets/esm_shims.js +9 -0
  91. package/packages/cli/node_modules/tsup/assets/package.json +3 -0
  92. package/packages/cli/node_modules/tsup/dist/chunk-DI5BO6XE.js +153 -0
  93. package/packages/cli/node_modules/tsup/dist/chunk-JZ25TPTY.js +42 -0
  94. package/packages/cli/node_modules/tsup/dist/chunk-PEEXUWMS.js +6 -0
  95. package/packages/cli/node_modules/tsup/dist/chunk-TWFEYLU4.js +352 -0
  96. package/packages/cli/node_modules/tsup/dist/chunk-VGC3FXLU.js +203 -0
  97. package/packages/cli/node_modules/tsup/dist/cli-default.js +12 -0
  98. package/packages/cli/node_modules/tsup/dist/cli-main.js +8 -0
  99. package/packages/cli/node_modules/tsup/dist/cli-node.js +14 -0
  100. package/packages/cli/node_modules/tsup/dist/index.d.ts +511 -0
  101. package/packages/cli/node_modules/tsup/dist/index.js +1711 -0
  102. package/packages/cli/node_modules/tsup/dist/rollup.js +6949 -0
  103. package/packages/cli/node_modules/tsup/package.json +99 -0
  104. package/packages/cli/node_modules/tsup/schema.json +362 -0
  105. package/packages/cli/package.json +35 -0
  106. package/packages/cli/src/commands/agent-register.ts +77 -0
  107. package/packages/cli/src/commands/chain.ts +29 -0
  108. package/packages/cli/src/commands/claim.ts +70 -0
  109. package/packages/cli/src/commands/create.ts +34 -0
  110. package/packages/cli/src/commands/status.ts +201 -0
  111. package/packages/cli/src/config.ts +103 -0
  112. package/packages/cli/src/index.ts +21 -0
  113. package/packages/cli/src/sdk/abi.ts +222 -0
  114. package/packages/cli/src/sdk/client.ts +713 -0
  115. package/packages/cli/src/sdk/constants.ts +56 -0
  116. package/packages/cli/src/sdk/index.ts +46 -0
  117. package/packages/cli/src/sdk/ipfs.ts +88 -0
  118. package/packages/cli/src/sdk.ts +36 -0
  119. package/packages/cli/tsconfig.json +20 -0
  120. package/packages/cli/tsup.config.ts +14 -0
  121. package/public/.well-known/farcaster.json +38 -0
  122. package/public/basescan-icon.svg +4 -0
  123. package/public/embed-image.png +0 -0
  124. package/public/favicon.png +0 -0
  125. package/public/hunt-token.svg +11 -0
  126. package/public/icon-192.png +0 -0
  127. package/public/icon.png +0 -0
  128. package/public/manifest.json +26 -0
  129. package/public/mc-icon-light.svg +12 -0
  130. package/public/og-image.png +0 -0
  131. package/public/plotlink-logo-symbol.svg +5 -0
  132. package/public/plotlink-logo.svg +5 -0
  133. package/public/screenshot-1.png +0 -0
  134. package/public/screenshot-2.png +0 -0
  135. package/public/screenshot-3.png +0 -0
  136. package/public/splash.png +0 -0
  137. package/public/wide-banner.png +0 -0
  138. package/scripts/backfill-trade-prices.ts +97 -0
  139. package/scripts/backfill-usd-rates.ts +220 -0
  140. package/scripts/e2e-verify.ts +1100 -0
  141. package/scripts/ows-smoke-test.ts +37 -0
  142. package/scripts/score-users.mjs +203 -0
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from "node:fs";
2
+ import type { Command } from "commander";
3
+ import { buildClient } from "../sdk.js";
4
+
5
+ export function registerCreate(program: Command): void {
6
+ program
7
+ .command("create")
8
+ .description("Create a new storyline from a content file")
9
+ .requiredOption("-t, --title <title>", "Storyline title")
10
+ .requiredOption("-f, --file <path>", "Path to content file (plain text)")
11
+ .requiredOption("-g, --genre <genre>", "Genre label")
12
+ .action(async (opts: { title: string; file: string; genre: string }) => {
13
+ try {
14
+ const content = readFileSync(opts.file, "utf-8");
15
+ const client = buildClient({ ipfs: true });
16
+
17
+ console.log(`Creating storyline "${opts.title}" (7-day deadline)...`);
18
+ const result = await client.createStoryline(
19
+ opts.title,
20
+ content,
21
+ opts.genre,
22
+ true,
23
+ );
24
+
25
+ console.log("Storyline created!");
26
+ console.log(` ID: ${result.storylineId}`);
27
+ console.log(` TX: ${result.txHash}`);
28
+ console.log(` CID: ${result.contentCid}`);
29
+ } catch (err) {
30
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
31
+ process.exit(1);
32
+ }
33
+ });
34
+ }
@@ -0,0 +1,201 @@
1
+ import type { Command } from "commander";
2
+ import { createClient } from "@supabase/supabase-js";
3
+ import { type Address, erc20Abi, formatUnits } from "viem";
4
+ import { mcv2BondAbi } from "../sdk/index.js";
5
+ import { buildClient } from "../sdk.js";
6
+ import { loadConfig } from "../config.js";
7
+
8
+ export function registerStatus(program: Command): void {
9
+ program
10
+ .command("status")
11
+ .description("Query storyline data (plots, deadline, token price) from Supabase and on-chain")
12
+ .requiredOption("-s, --storyline <id>", "Storyline ID")
13
+ .action(async (opts: { storyline: string }) => {
14
+ try {
15
+ const storylineId = BigInt(opts.storyline);
16
+ const cfg = loadConfig();
17
+ const client = buildClient({ ipfs: false });
18
+
19
+ console.log(`Fetching storyline ${storylineId}...`);
20
+
21
+ // -----------------------------------------------------------------
22
+ // 1. Storyline data — Supabase primary, paginated RPC fallback
23
+ // -----------------------------------------------------------------
24
+ let title = "";
25
+ let creator: Address = "0x0000000000000000000000000000000000000000";
26
+ let tokenAddress: Address = "0x0000000000000000000000000000000000000000";
27
+ let hasDeadline = false;
28
+ let openingCID = "";
29
+ let plotCount = 0;
30
+
31
+ // Supabase-only metadata
32
+ let dbRow: {
33
+ last_plot_time: string | null;
34
+ sunset: boolean;
35
+ writer_type: number | null;
36
+ block_timestamp: string | null;
37
+ } | null = null;
38
+
39
+ // Try Supabase first (fast, indexed), fall back to paginated RPC
40
+ // if not configured or if the storyline isn't indexed yet
41
+ let fromSupabase = false;
42
+ if (cfg.supabaseUrl && cfg.supabaseAnonKey) {
43
+ const supabase = createClient(cfg.supabaseUrl, cfg.supabaseAnonKey);
44
+ const { data } = await supabase
45
+ .from("storylines")
46
+ .select("title, writer_address, token_address, has_deadline, plot_count, last_plot_time, sunset, writer_type, block_timestamp")
47
+ .eq("storyline_id", Number(storylineId))
48
+ .eq("contract_address", client.storyFactory.toLowerCase())
49
+ .single();
50
+
51
+ if (data) {
52
+ fromSupabase = true;
53
+ title = data.title;
54
+ creator = data.writer_address as Address;
55
+ tokenAddress = data.token_address as Address;
56
+ hasDeadline = data.has_deadline;
57
+ plotCount = data.plot_count;
58
+ dbRow = {
59
+ last_plot_time: data.last_plot_time,
60
+ sunset: data.sunset,
61
+ writer_type: data.writer_type,
62
+ block_timestamp: data.block_timestamp,
63
+ };
64
+
65
+ // Opening CID is only in event logs; fetch via paginated RPC
66
+ const info = await client.getStoryline(storylineId);
67
+ if (info) {
68
+ openingCID = info.openingCID;
69
+ }
70
+ }
71
+ }
72
+
73
+ if (!fromSupabase) {
74
+ // Fallback: paginated RPC log fetching (chunks into RPC-safe ranges)
75
+ const info = await client.getStoryline(storylineId);
76
+ if (!info) {
77
+ console.error(`Storyline ${storylineId} not found on-chain.`);
78
+ process.exit(1);
79
+ }
80
+
81
+ title = info.title;
82
+ creator = info.creator;
83
+ tokenAddress = info.tokenAddress;
84
+ hasDeadline = info.hasDeadline;
85
+ openingCID = info.openingCID;
86
+
87
+ const plots = await client.getPlots(storylineId);
88
+ plotCount = plots.length;
89
+ }
90
+
91
+ // -----------------------------------------------------------------
92
+ // 2. Reserve token metadata (symbol + decimals via tokenBond)
93
+ // -----------------------------------------------------------------
94
+ let tokenSymbol = "TOKEN";
95
+ let tokenDecimals = 18;
96
+ let bondCreator: Address | null = null;
97
+ let bondReserveToken: Address | null = null;
98
+ try {
99
+ const bond = await client.publicClient.readContract({
100
+ address: client.mcv2Bond,
101
+ abi: mcv2BondAbi,
102
+ functionName: "tokenBond",
103
+ args: [tokenAddress],
104
+ });
105
+ bondCreator = (bond as readonly unknown[])[0] as Address;
106
+ const reserveToken = (bond as readonly unknown[])[4] as Address;
107
+ bondReserveToken = reserveToken;
108
+ const [sym, dec] = await Promise.all([
109
+ client.publicClient.readContract({
110
+ address: reserveToken,
111
+ abi: erc20Abi,
112
+ functionName: "symbol",
113
+ }),
114
+ client.publicClient.readContract({
115
+ address: reserveToken,
116
+ abi: erc20Abi,
117
+ functionName: "decimals",
118
+ }),
119
+ ]);
120
+ tokenSymbol = sym;
121
+ tokenDecimals = dec;
122
+ } catch {
123
+ // Fall back to defaults if calls fail
124
+ }
125
+
126
+ // -----------------------------------------------------------------
127
+ // 3. On-chain token price (MCV2_Bond)
128
+ // -----------------------------------------------------------------
129
+ const tokenPrice = await client.getTokenPrice(tokenAddress);
130
+
131
+ // -----------------------------------------------------------------
132
+ // 4. On-chain royalty info
133
+ // -----------------------------------------------------------------
134
+ let unclaimedRoyalty: bigint | null = null;
135
+ try {
136
+ if (bondCreator && bondReserveToken) {
137
+ const royalty = await client.getRoyaltyInfo(bondCreator, bondReserveToken);
138
+ unclaimedRoyalty = royalty.balance;
139
+ }
140
+ } catch {
141
+ // Token may not have a bond yet
142
+ }
143
+
144
+ // -----------------------------------------------------------------
145
+ // Display
146
+ // -----------------------------------------------------------------
147
+ console.log();
148
+ console.log(`Title: ${title}`);
149
+ console.log(`Creator: ${creator}`);
150
+ console.log(`Token: ${tokenAddress}`);
151
+ console.log(`Has deadline: ${hasDeadline ? "yes" : "no"}`);
152
+ if (openingCID) {
153
+ console.log(`Opening CID: ${openingCID}`);
154
+ }
155
+ console.log(`Plot count: ${plotCount}`);
156
+
157
+ if (dbRow) {
158
+ console.log(`Sunset: ${dbRow.sunset ? "yes" : "no"}`);
159
+ console.log(`Writer type: ${dbRow.writer_type === 1 ? "agent" : dbRow.writer_type === 0 ? "human" : "unknown"}`);
160
+ if (dbRow.block_timestamp) {
161
+ console.log(`Created: ${new Date(dbRow.block_timestamp).toISOString()}`);
162
+ }
163
+ if (dbRow.last_plot_time) {
164
+ console.log(`Last plot: ${new Date(dbRow.last_plot_time).toISOString()}`);
165
+ }
166
+
167
+ // Deadline remaining (7 days from last plot)
168
+ if (hasDeadline && dbRow.last_plot_time && !dbRow.sunset) {
169
+ const DEADLINE_HOURS = 168;
170
+ const deadlineMs =
171
+ new Date(dbRow.last_plot_time).getTime() + DEADLINE_HOURS * 60 * 60 * 1000;
172
+ const remainingMs = deadlineMs - Date.now();
173
+ if (remainingMs <= 0) {
174
+ console.log(`Deadline: expired`);
175
+ } else {
176
+ const totalMin = Math.floor(remainingMs / 60_000);
177
+ const days = Math.floor(totalMin / 1440);
178
+ const hours = Math.floor((totalMin % 1440) / 60);
179
+ const mins = totalMin % 60;
180
+ const parts: string[] = [];
181
+ if (days > 0) parts.push(`${days}d`);
182
+ if (hours > 0) parts.push(`${hours}h`);
183
+ if (mins > 0 || parts.length === 0) parts.push(`${mins}m`);
184
+ console.log(`Deadline: ${parts.join(" ")} remaining`);
185
+ }
186
+ }
187
+ }
188
+
189
+ if (tokenPrice) {
190
+ console.log(`Token price: ${tokenPrice.priceFormatted} ${tokenSymbol}`);
191
+ }
192
+
193
+ if (unclaimedRoyalty !== null && unclaimedRoyalty > 0n) {
194
+ console.log(`Unclaimed royalty: ${formatUnits(unclaimedRoyalty, tokenDecimals)} ${tokenSymbol}`);
195
+ }
196
+ } catch (err) {
197
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
198
+ process.exit(1);
199
+ }
200
+ });
201
+ }
@@ -0,0 +1,103 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { homedir } from "node:os";
4
+
5
+ /**
6
+ * Resolved configuration for the CLI.
7
+ * Loaded from environment variables, falling back to `.plotlinkrc` in cwd or home dir.
8
+ */
9
+ export interface CliConfig {
10
+ privateKey: string;
11
+ rpcUrl: string;
12
+ chainId?: number;
13
+ filebaseAccessKey?: string;
14
+ filebaseSecretKey?: string;
15
+ filebaseBucket?: string;
16
+ supabaseUrl?: string;
17
+ supabaseAnonKey?: string;
18
+ }
19
+
20
+ /**
21
+ * Load CLI config by merging env vars over `.plotlinkrc` values.
22
+ *
23
+ * Priority (highest first):
24
+ * 1. Environment variables (PLOTLINK_PRIVATE_KEY, PLOTLINK_RPC_URL, etc.)
25
+ * 2. `.plotlinkrc` JSON file in cwd
26
+ * 3. `.plotlinkrc` JSON file in home dir
27
+ */
28
+ export function loadConfig(): CliConfig {
29
+ const rc = loadRcFile();
30
+
31
+ const privateKey = env("PLOTLINK_PRIVATE_KEY") ?? rc.privateKey;
32
+ const rpcUrl = env("PLOTLINK_RPC_URL") ?? rc.rpcUrl;
33
+
34
+ if (!privateKey) {
35
+ throw new Error(
36
+ "Missing private key. Set PLOTLINK_PRIVATE_KEY env var or add \"privateKey\" to .plotlinkrc",
37
+ );
38
+ }
39
+ if (!rpcUrl) {
40
+ throw new Error(
41
+ "Missing RPC URL. Set PLOTLINK_RPC_URL env var or add \"rpcUrl\" to .plotlinkrc",
42
+ );
43
+ }
44
+
45
+ const chainIdRaw = env("PLOTLINK_CHAIN_ID") ?? rc.chainId;
46
+ const chainId = chainIdRaw ? Number(chainIdRaw) : undefined;
47
+
48
+ return {
49
+ privateKey,
50
+ rpcUrl,
51
+ chainId,
52
+ filebaseAccessKey: env("PLOTLINK_FILEBASE_ACCESS_KEY") ?? rc.filebaseAccessKey,
53
+ filebaseSecretKey: env("PLOTLINK_FILEBASE_SECRET_KEY") ?? rc.filebaseSecretKey,
54
+ filebaseBucket: env("PLOTLINK_FILEBASE_BUCKET") ?? rc.filebaseBucket,
55
+ supabaseUrl: env("PLOTLINK_SUPABASE_URL") ?? rc.supabaseUrl,
56
+ supabaseAnonKey: env("PLOTLINK_SUPABASE_ANON_KEY") ?? rc.supabaseAnonKey,
57
+ };
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Helpers
62
+ // ---------------------------------------------------------------------------
63
+
64
+ function env(name: string): string | undefined {
65
+ const val = process.env[name];
66
+ return val && val.trim().length > 0 ? val.trim() : undefined;
67
+ }
68
+
69
+ interface RcData {
70
+ privateKey?: string;
71
+ rpcUrl?: string;
72
+ chainId?: string;
73
+ filebaseAccessKey?: string;
74
+ filebaseSecretKey?: string;
75
+ filebaseBucket?: string;
76
+ supabaseUrl?: string;
77
+ supabaseAnonKey?: string;
78
+ }
79
+
80
+ function loadRcFile(): RcData {
81
+ const candidates = [
82
+ resolve(process.cwd(), ".plotlinkrc"),
83
+ resolve(homedir(), ".plotlinkrc"),
84
+ ];
85
+
86
+ for (const filepath of candidates) {
87
+ if (existsSync(filepath)) {
88
+ const raw = readFileSync(filepath, "utf-8");
89
+ try {
90
+ const parsed = JSON.parse(raw) as RcData;
91
+ console.warn(
92
+ "WARNING: Loading keys from .plotlinkrc — ensure this file is in .gitignore and never committed.",
93
+ );
94
+ return parsed;
95
+ } catch (err) {
96
+ const message = err instanceof Error ? err.message : String(err);
97
+ console.error(`Error parsing .plotlinkrc: ${message}. Check your JSON syntax.`);
98
+ }
99
+ }
100
+ }
101
+
102
+ return {};
103
+ }
@@ -0,0 +1,21 @@
1
+ import { Command } from "commander";
2
+ import { registerCreate } from "./commands/create.js";
3
+ import { registerChain } from "./commands/chain.js";
4
+ import { registerStatus } from "./commands/status.js";
5
+ import { registerClaim } from "./commands/claim.js";
6
+ import { registerAgentRegister } from "./commands/agent-register.js";
7
+
8
+ const program = new Command();
9
+
10
+ program
11
+ .name("plotlink")
12
+ .description("CLI for the PlotLink protocol on Base")
13
+ .version("0.1.0");
14
+
15
+ registerCreate(program);
16
+ registerChain(program);
17
+ registerStatus(program);
18
+ registerClaim(program);
19
+ registerAgentRegister(program);
20
+
21
+ program.parse();
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Contract ABIs for the PlotLink protocol.
3
+ *
4
+ * Mirrored from lib/contracts/abi.ts and lib/contracts/erc8004.ts in the web
5
+ * app. The SDK keeps its own copy to avoid cross-package imports.
6
+ */
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // StoryFactory
10
+ // ---------------------------------------------------------------------------
11
+
12
+ export const storyFactoryAbi = [
13
+ // Events
14
+ {
15
+ type: "event",
16
+ name: "PlotChained",
17
+ inputs: [
18
+ { name: "storylineId", type: "uint256", indexed: true },
19
+ { name: "plotIndex", type: "uint256", indexed: true },
20
+ { name: "writer", type: "address", indexed: true },
21
+ { name: "title", type: "string", indexed: false },
22
+ { name: "contentCID", type: "string", indexed: false },
23
+ { name: "contentHash", type: "bytes32", indexed: false },
24
+ ],
25
+ },
26
+ {
27
+ type: "event",
28
+ name: "StorylineCreated",
29
+ inputs: [
30
+ { name: "storylineId", type: "uint256", indexed: true },
31
+ { name: "writer", type: "address", indexed: true },
32
+ { name: "tokenAddress", type: "address", indexed: false },
33
+ { name: "title", type: "string", indexed: false },
34
+ { name: "hasDeadline", type: "bool", indexed: false },
35
+ { name: "openingCID", type: "string", indexed: false },
36
+ { name: "openingHash", type: "bytes32", indexed: false },
37
+ ],
38
+ },
39
+ {
40
+ type: "event",
41
+ name: "Donation",
42
+ inputs: [
43
+ { name: "storylineId", type: "uint256", indexed: true },
44
+ { name: "donor", type: "address", indexed: true },
45
+ { name: "amount", type: "uint256", indexed: false },
46
+ ],
47
+ },
48
+ {
49
+ type: "event",
50
+ name: "CurveUpdated",
51
+ inputs: [{ name: "newStepCount", type: "uint256", indexed: false }],
52
+ },
53
+ // Functions
54
+ {
55
+ type: "function",
56
+ name: "createStoryline",
57
+ stateMutability: "payable",
58
+ inputs: [
59
+ { name: "title", type: "string" },
60
+ { name: "openingCID", type: "string" },
61
+ { name: "openingHash", type: "bytes32" },
62
+ { name: "hasDeadline", type: "bool" },
63
+ ],
64
+ outputs: [{ name: "storylineId", type: "uint256" }],
65
+ },
66
+ {
67
+ type: "function",
68
+ name: "chainPlot",
69
+ stateMutability: "nonpayable",
70
+ inputs: [
71
+ { name: "storylineId", type: "uint256" },
72
+ { name: "title", type: "string" },
73
+ { name: "contentCID", type: "string" },
74
+ { name: "contentHash", type: "bytes32" },
75
+ ],
76
+ outputs: [],
77
+ },
78
+ {
79
+ type: "function",
80
+ name: "donate",
81
+ stateMutability: "nonpayable",
82
+ inputs: [
83
+ { name: "storylineId", type: "uint256" },
84
+ { name: "amount", type: "uint256" },
85
+ ],
86
+ outputs: [],
87
+ },
88
+ {
89
+ type: "function",
90
+ name: "hasSunset",
91
+ stateMutability: "view",
92
+ inputs: [{ name: "storylineId", type: "uint256" }],
93
+ outputs: [{ name: "", type: "bool" }],
94
+ },
95
+ {
96
+ type: "function",
97
+ name: "updateCurve",
98
+ stateMutability: "nonpayable",
99
+ inputs: [
100
+ { name: "newRanges", type: "uint128[]" },
101
+ { name: "newPrices", type: "uint128[]" },
102
+ ],
103
+ outputs: [],
104
+ },
105
+ {
106
+ type: "function",
107
+ name: "owner",
108
+ stateMutability: "view",
109
+ inputs: [],
110
+ outputs: [{ name: "", type: "address" }],
111
+ },
112
+ {
113
+ type: "function",
114
+ name: "storylines",
115
+ stateMutability: "view",
116
+ inputs: [{ name: "storylineId", type: "uint256" }],
117
+ outputs: [
118
+ { name: "writer", type: "address" },
119
+ { name: "token", type: "address" },
120
+ { name: "plotCount", type: "uint24" },
121
+ { name: "lastPlotTime", type: "uint40" },
122
+ { name: "hasDeadline", type: "bool" },
123
+ ],
124
+ },
125
+ ] as const;
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // ERC-8004 Agent Registry
129
+ // ---------------------------------------------------------------------------
130
+
131
+ export const erc8004Abi = [
132
+ {
133
+ type: "function",
134
+ name: "agentIdByWallet",
135
+ stateMutability: "view",
136
+ inputs: [{ name: "wallet", type: "address" }],
137
+ outputs: [{ name: "agentId", type: "uint256" }],
138
+ },
139
+ {
140
+ type: "function",
141
+ name: "register",
142
+ stateMutability: "nonpayable",
143
+ inputs: [{ name: "agentURI", type: "string" }],
144
+ outputs: [{ name: "agentId", type: "uint256" }],
145
+ },
146
+ {
147
+ type: "function",
148
+ name: "setAgentWallet",
149
+ stateMutability: "nonpayable",
150
+ inputs: [
151
+ { name: "agentId", type: "uint256" },
152
+ { name: "newWallet", type: "address" },
153
+ { name: "deadline", type: "uint256" },
154
+ { name: "signature", type: "bytes" },
155
+ ],
156
+ outputs: [],
157
+ },
158
+ {
159
+ type: "event",
160
+ name: "Registered",
161
+ inputs: [
162
+ { name: "agentId", type: "uint256", indexed: true },
163
+ { name: "agentURI", type: "string", indexed: false },
164
+ { name: "owner", type: "address", indexed: true },
165
+ ],
166
+ },
167
+ ] as const;
168
+
169
+ // ---------------------------------------------------------------------------
170
+ // MCV2_Bond (Mint Club V2 bonding curve)
171
+ // ---------------------------------------------------------------------------
172
+
173
+ export const mcv2BondAbi = [
174
+ {
175
+ type: "function",
176
+ name: "creationFee",
177
+ stateMutability: "view",
178
+ inputs: [],
179
+ outputs: [{ name: "", type: "uint256" }],
180
+ },
181
+ {
182
+ type: "function",
183
+ name: "getRoyaltyInfo",
184
+ stateMutability: "view",
185
+ inputs: [
186
+ { name: "wallet", type: "address" },
187
+ { name: "reserveToken", type: "address" },
188
+ ],
189
+ outputs: [
190
+ { name: "balance", type: "uint256" },
191
+ { name: "claimed", type: "uint256" },
192
+ ],
193
+ },
194
+ {
195
+ type: "function",
196
+ name: "claimRoyalties",
197
+ stateMutability: "nonpayable",
198
+ inputs: [{ name: "reserveToken", type: "address" }],
199
+ outputs: [],
200
+ },
201
+ {
202
+ type: "function",
203
+ name: "priceForNextMint",
204
+ stateMutability: "view",
205
+ inputs: [{ name: "token", type: "address" }],
206
+ outputs: [{ name: "", type: "uint128" }],
207
+ },
208
+ {
209
+ type: "function",
210
+ name: "tokenBond",
211
+ stateMutability: "view",
212
+ inputs: [{ name: "token", type: "address" }],
213
+ outputs: [
214
+ { name: "creator", type: "address" },
215
+ { name: "mintRoyalty", type: "uint16" },
216
+ { name: "burnRoyalty", type: "uint16" },
217
+ { name: "createdAt", type: "uint40" },
218
+ { name: "reserveToken", type: "address" },
219
+ { name: "reserveBalance", type: "uint256" },
220
+ ],
221
+ },
222
+ ] as const;