@pickhooks/sdk 0.2.0 → 0.5.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.
@@ -0,0 +1,543 @@
1
+ import { type Address, type Hex } from "viem";
2
+ import { ANSWER_SCHEMA, type AgentAnswer, type AgentProfile, type Bucket, type Envelope, PERSONALITIES, type Plan, type Program, describeProgram, toPlan, toProgram } from "./agents-catalog.js";
3
+ import { type PoolKey } from "./infinity.js";
4
+ import { type Ctx, type SendOptions, type Sent, type TxRequest } from "./tx.js";
5
+ /**
6
+ * pickhooks agents: coins run by an agent. The agent (any wallet: the pickhooks pilot, your own bot, a model behind an
7
+ * MCP server) rewrites the coin's rule program live: the fee on each side, where the coin's part of every fee goes
8
+ * (burn, liquidity, floor, pots, creator, treasury) and up to eight pool rules. The limits are fixed at launch and
9
+ * checked on chain; every change is announced and lands after the notice; holders veto a change or fire the agent by
10
+ * locking coins. The coin is a plain ERC20 in a PancakeSwap Infinity pool, so every router trades it.
11
+ *
12
+ * const c = await ph.agents.coin(token); // program as sentences, limits, pending change, buckets
13
+ * const b = await ph.agents.brief(token); // { system, user, schema }: the pickhooks pilot's prompt for any model
14
+ * const a = await ph.agents.act(token, modelAnswer); // the propose / move transaction the answer asks for
15
+ * await ph.agents.propose(token, plan, "why"); // as the pilot
16
+ * await ph.agents.veto(token, coins); await ph.agents.fire(token, coins); // as a holder
17
+ */
18
+ export type AgentPending = {
19
+ id: bigint;
20
+ activeAt: number;
21
+ dueAt: number;
22
+ note: Hex;
23
+ vetoLocked: bigint;
24
+ vetoNeeded: bigint;
25
+ program: Program;
26
+ lines: string[];
27
+ };
28
+ export type AgentCoin = {
29
+ token: Address;
30
+ name: string;
31
+ symbol: string;
32
+ metadata: string;
33
+ creator: Address;
34
+ /** the coin's HOOKS floor (the factory's floors) */
35
+ floor: Address;
36
+ start: number;
37
+ /** the platform's share of every fee, fixed per coin */
38
+ platformBps: number;
39
+ /** the program's version (1 at launch, +1 per landed change) */
40
+ version: number;
41
+ /** the agent's wallet, or null once the holders fired it */
42
+ pilot: Address | null;
43
+ fired: boolean;
44
+ epoch: number;
45
+ lastChange: number;
46
+ env: Envelope;
47
+ /** the rules the envelope allows, by id */
48
+ allowed: string[];
49
+ program: Program;
50
+ /** the program as sentences */
51
+ lines: string[];
52
+ /** the rules that are on */
53
+ rules: {
54
+ kind: number;
55
+ id: string;
56
+ name: string;
57
+ text: string;
58
+ }[];
59
+ pending: AgentPending | null;
60
+ /** coins locked against the agent, and how many fire it */
61
+ fire: {
62
+ locked: bigint;
63
+ needed: bigint;
64
+ };
65
+ /** BNB (wei) in the coin's buckets */
66
+ pots: Record<Bucket, bigint>;
67
+ totals: {
68
+ burnedBnb: bigint;
69
+ burnedCoins: bigint;
70
+ lpBnb: bigint;
71
+ lpLiquidity: bigint;
72
+ floorBnb: bigint;
73
+ lpCoins: bigint;
74
+ };
75
+ stats: {
76
+ buyers: number;
77
+ buys: number;
78
+ sells: number;
79
+ buysSinceSell: number;
80
+ lastBuyTime: number;
81
+ lastBuyer: Address;
82
+ qualifyingBuys: number;
83
+ volume: bigint;
84
+ net: bigint;
85
+ peak: bigint;
86
+ };
87
+ jackpotLast: Address;
88
+ jackpotTime: number;
89
+ /** coins outside the pool (what veto and fire shares count against) */
90
+ outside: bigint;
91
+ id: Hex;
92
+ key: PoolKey;
93
+ priceBnb: number;
94
+ mcapBnb: number;
95
+ chainNow: number;
96
+ };
97
+ export type AgentLaunch = {
98
+ name: string;
99
+ symbol: string;
100
+ /** a link to the coin's metadata JSON; prepareMetadata() hosts one on pickhooks.com with the agent's profile */
101
+ metadata: string;
102
+ /** the program at launch (default starterProgram()), or a plan in plain units */
103
+ program?: Program;
104
+ plan?: Partial<Plan>;
105
+ /** the limits, fixed for good (default starterEnvelope()) */
106
+ envelope?: Partial<Envelope>;
107
+ /** the agent's wallet (default the pickhooks pilot, addresses.agentsPilot); your own bot's wallet for bring your own agent */
108
+ pilot?: Address;
109
+ /** the creator's first buy, BNB wei */
110
+ devBuy?: bigint;
111
+ salt?: Hex;
112
+ };
113
+ export type AgentLock = {
114
+ amount: bigint;
115
+ vetoId: bigint;
116
+ fireEpoch: number;
117
+ vetoing: boolean;
118
+ firing: boolean;
119
+ };
120
+ /** One entry of an agent's journal as pickhooks.com serves it (the pickhooks pilot writes one per look). */
121
+ export type JournalEntry = {
122
+ at: string;
123
+ title: string;
124
+ body: string;
125
+ action: "none" | "propose" | "move";
126
+ proposal?: string[];
127
+ move?: {
128
+ from: string;
129
+ to: string;
130
+ bnb: number;
131
+ };
132
+ expect?: {
133
+ metric: string;
134
+ target: string;
135
+ by_hours: number;
136
+ };
137
+ result?: string;
138
+ tx?: string | null;
139
+ note?: string;
140
+ model?: string;
141
+ [k: string]: unknown;
142
+ };
143
+ /** What a look at the coin gives a model: the same JSON the pickhooks pilot reads (bigints as strings in the prompt). */
144
+ export type AgentLook = {
145
+ now_utc: string;
146
+ coin: {
147
+ name: string;
148
+ symbol: string;
149
+ token: Address;
150
+ age_hours: number;
151
+ creator: Address;
152
+ floor: Address;
153
+ };
154
+ market: {
155
+ price_bnb_per_million_coins: number;
156
+ market_cap_bnb: number;
157
+ buys: number;
158
+ sells: number;
159
+ trades_since_last_look: number | null;
160
+ buyers: number;
161
+ volume_coins: string;
162
+ coins_outside_pool: string;
163
+ };
164
+ live_program: {
165
+ version: number;
166
+ } & ReturnType<typeof toPlan>;
167
+ pending_change: {
168
+ id: number;
169
+ lands_at_utc: string;
170
+ veto_locked: string;
171
+ veto_needed: string;
172
+ plan: ReturnType<typeof toPlan>;
173
+ } | null;
174
+ holders_against_you: {
175
+ locked: string;
176
+ fires_you_at: string;
177
+ };
178
+ buckets_bnb: Record<Bucket, string>;
179
+ done_so_far: {
180
+ burned_bnb: string;
181
+ burned_coins: string;
182
+ liquidity_bnb: string;
183
+ floor_bnb: string;
184
+ };
185
+ last_change_utc: string;
186
+ your_last_entries: Pick<JournalEntry, "at" | "title" | "body" | "action" | "expect" | "result">[];
187
+ };
188
+ export declare function agentsModule(ctx: Ctx): {
189
+ readonly on: boolean;
190
+ factory: `0x${string}`;
191
+ hook: () => Promise<`0x${string}`>;
192
+ desk: () => Promise<`0x${string}`>;
193
+ key: (token: Address) => Promise<PoolKey>;
194
+ count: () => Promise<number>;
195
+ isCoin: (token: Address) => Promise<boolean>;
196
+ coins: (o?: {
197
+ limit?: number;
198
+ offset?: number;
199
+ }) => Promise<AgentCoin[]>;
200
+ coin: (token: Address) => Promise<AgentCoin | null>;
201
+ program: (token: Address) => Promise<Program>;
202
+ envelopeOf: (token: Address) => Promise<{
203
+ pilot: Address | null;
204
+ env: Envelope;
205
+ version: number;
206
+ lastChange: number;
207
+ }>;
208
+ locks: (token: Address, who: Address) => Promise<AgentLock>;
209
+ owed: (who: Address) => Promise<bigint>;
210
+ wallet: (token: Address, who: Address) => Promise<{
211
+ balance: bigint;
212
+ owed: bigint;
213
+ } & AgentLock>;
214
+ journal: (token: Address, limit?: number) => Promise<JournalEntry[]>;
215
+ look: (token: Address, o?: {
216
+ tradesSinceLastLook?: number;
217
+ entries?: AgentLook["your_last_entries"];
218
+ }) => Promise<AgentLook>;
219
+ brief: (token: Address, o?: Parameters<(token: Address, o?: {
220
+ tradesSinceLastLook?: number;
221
+ entries?: AgentLook["your_last_entries"];
222
+ }) => Promise<AgentLook>>[1]) => Promise<{
223
+ system: string;
224
+ user: string;
225
+ schema: typeof ANSWER_SCHEMA;
226
+ look: AgentLook;
227
+ profile: AgentProfile;
228
+ }>;
229
+ catalog: () => {
230
+ rules: {
231
+ kind: number;
232
+ id: string;
233
+ name: string;
234
+ line: string;
235
+ fields: import("./agents-catalog.js").AgentRuleField[];
236
+ }[];
237
+ limits: {
238
+ readonly baseFeeBps: 100;
239
+ readonly maxFeeBps: 1000;
240
+ readonly maxCreatorBps: 5000;
241
+ readonly maxRules: 8;
242
+ readonly notice: {
243
+ readonly min: 600;
244
+ readonly max: 86400;
245
+ };
246
+ readonly minGap: {
247
+ readonly min: 3600;
248
+ readonly max: number;
249
+ };
250
+ readonly vetoBps: {
251
+ readonly min: 100;
252
+ readonly max: 5000;
253
+ };
254
+ readonly fireBps: {
255
+ readonly min: 100;
256
+ readonly max: 5000;
257
+ };
258
+ readonly maxRunBnb: 0.2;
259
+ readonly runGapSeconds: 30;
260
+ readonly minLpBnb: 0.01;
261
+ };
262
+ buckets: ("floor" | "rewards" | "jackpot" | "treasury" | "burn" | "lp")[];
263
+ personalities: ("calm" | "analyst" | "contrarian" | "prankster" | "builder" | "guardian" | "degen" | "storyteller")[];
264
+ objectives: Record<string, string>;
265
+ starter: {
266
+ program: Program;
267
+ envelope: Envelope;
268
+ };
269
+ abi: {
270
+ program: string;
271
+ envelope: string;
272
+ };
273
+ answerSchema: {
274
+ readonly type: "object";
275
+ readonly additionalProperties: false;
276
+ readonly required: readonly ["title", "body", "action", "plan", "move", "expect"];
277
+ readonly properties: {
278
+ readonly title: {
279
+ readonly type: "string";
280
+ readonly description: "a short title for this journal entry, at most 60 characters, lower case";
281
+ };
282
+ readonly body: {
283
+ readonly type: "string";
284
+ readonly description: "the journal entry: what you saw (with numbers), what you decided and why, at most 700 characters";
285
+ };
286
+ readonly action: {
287
+ readonly type: "string";
288
+ readonly enum: readonly ["none", "propose", "move"];
289
+ };
290
+ readonly plan: {
291
+ readonly type: "object";
292
+ readonly additionalProperties: false;
293
+ readonly required: readonly ["buy_fee_pct", "sell_fee_pct", "route", "rules"];
294
+ readonly description: "the whole new program when action is propose (it replaces the live one); otherwise repeat the live program";
295
+ readonly properties: {
296
+ readonly buy_fee_pct: {
297
+ readonly type: "number";
298
+ };
299
+ readonly sell_fee_pct: {
300
+ readonly type: "number";
301
+ };
302
+ readonly route: {
303
+ readonly type: "object";
304
+ readonly additionalProperties: false;
305
+ readonly required: readonly ["burn", "lp", "floor", "rewards", "jackpot", "creator"];
306
+ readonly description: "percent of the coin's part of every fee; what is left goes to the treasury";
307
+ readonly properties: {
308
+ readonly burn: {
309
+ readonly type: "number";
310
+ };
311
+ readonly lp: {
312
+ readonly type: "number";
313
+ };
314
+ readonly floor: {
315
+ readonly type: "number";
316
+ };
317
+ readonly rewards: {
318
+ readonly type: "number";
319
+ };
320
+ readonly jackpot: {
321
+ readonly type: "number";
322
+ };
323
+ readonly creator: {
324
+ readonly type: "number";
325
+ };
326
+ };
327
+ };
328
+ readonly rules: {
329
+ readonly type: "array";
330
+ readonly items: {
331
+ readonly type: "object";
332
+ readonly additionalProperties: false;
333
+ readonly required: readonly ["id", "values"];
334
+ readonly properties: {
335
+ readonly id: {
336
+ readonly type: "string";
337
+ readonly enum: string[];
338
+ };
339
+ readonly values: {
340
+ readonly type: "array";
341
+ readonly items: {
342
+ readonly type: "object";
343
+ readonly additionalProperties: false;
344
+ readonly required: readonly ["key", "value"];
345
+ readonly properties: {
346
+ readonly key: {
347
+ readonly type: "string";
348
+ };
349
+ readonly value: {
350
+ readonly type: "string";
351
+ };
352
+ };
353
+ };
354
+ };
355
+ };
356
+ };
357
+ };
358
+ };
359
+ };
360
+ readonly move: {
361
+ readonly type: "object";
362
+ readonly additionalProperties: false;
363
+ readonly required: readonly ["from", "to", "bnb"];
364
+ readonly description: "when action is move: BNB from the treasury (or a pot whose rule is off) into a bucket; otherwise zeros";
365
+ readonly properties: {
366
+ readonly from: {
367
+ readonly type: "string";
368
+ readonly enum: readonly ["treasury", "rewards", "jackpot"];
369
+ };
370
+ readonly to: {
371
+ readonly type: "string";
372
+ readonly enum: readonly ["burn", "lp", "floor", "rewards", "jackpot"];
373
+ };
374
+ readonly bnb: {
375
+ readonly type: "number";
376
+ };
377
+ };
378
+ };
379
+ readonly expect: {
380
+ readonly type: "object";
381
+ readonly additionalProperties: false;
382
+ readonly required: readonly ["metric", "target", "by_hours"];
383
+ readonly description: "what this decision should move, so your next look can check it";
384
+ readonly properties: {
385
+ readonly metric: {
386
+ readonly type: "string";
387
+ };
388
+ readonly target: {
389
+ readonly type: "string";
390
+ };
391
+ readonly by_hours: {
392
+ readonly type: "number";
393
+ };
394
+ };
395
+ };
396
+ };
397
+ };
398
+ };
399
+ describe: typeof describeProgram;
400
+ toProgram: typeof toProgram;
401
+ toPlan: typeof toPlan;
402
+ problemsOf: (p: Program, env?: Envelope) => string[];
403
+ envelopeProblems: (e: Envelope) => string[];
404
+ checkProgram: (token: Address, p: Program) => Promise<{
405
+ ok: true;
406
+ } | {
407
+ ok: false;
408
+ text: string;
409
+ }>;
410
+ quote: (q: {
411
+ token: Address;
412
+ side: "buy" | "sell";
413
+ amount: bigint;
414
+ from?: Address;
415
+ }) => Promise<{
416
+ amountOut: bigint;
417
+ }>;
418
+ check: (c: {
419
+ token: Address;
420
+ side: "buy" | "sell";
421
+ wallet: Address;
422
+ amount: bigint;
423
+ }) => Promise<{
424
+ ok: true;
425
+ } | {
426
+ ok: false;
427
+ kind: number;
428
+ name: string;
429
+ text: string;
430
+ }>;
431
+ sellApprovals: (owner: Address, token: Address, amount: bigint) => Promise<TxRequest[]>;
432
+ build: {
433
+ /** the pilot proposes a whole new program; it lands after the notice (anyone may call activate then) */
434
+ propose: (token: Address, p: Program | Partial<Plan>, note?: Hex | string | {
435
+ title: string;
436
+ body: string;
437
+ }) => Promise<TxRequest>;
438
+ cancel: (token: Address) => Promise<TxRequest>;
439
+ /** the pilot moves treasury BNB (or a pot whose rule is off) into burn, lp, floor, rewards or jackpot */
440
+ move: (token: Address, from: Bucket | number, to: Bucket | number, wei: bigint) => Promise<TxRequest>;
441
+ handOver: (token: Address, to: Address) => Promise<TxRequest>;
442
+ /** anyone lands a change that is due */
443
+ activate: (token: Address) => Promise<TxRequest>;
444
+ /** a holder locks coins against the pending change (0: with coins locked already) */
445
+ veto: (token: Address, amount: bigint) => Promise<TxRequest>;
446
+ /** a holder locks coins against the agent (0: with coins locked already) */
447
+ fire: (token: Address, amount: bigint) => Promise<TxRequest>;
448
+ withdraw: (token: Address) => Promise<TxRequest>;
449
+ /** anyone adds BNB to a coin's bucket */
450
+ give: (token: Address, bucket: Bucket | number, wei: bigint) => Promise<TxRequest>;
451
+ /** jackpot wins, rewards and a creator's share, over every agent coin */
452
+ claim: () => Promise<TxRequest>;
453
+ /** the runs anyone may trigger: the burn bucket buys and burns, the lp bucket becomes liquidity, the floor bucket feeds the floor */
454
+ burn: (token: Address) => Promise<TxRequest>;
455
+ addLiquidity: (token: Address) => Promise<TxRequest>;
456
+ feedFloor: (token: Address) => Promise<TxRequest>;
457
+ settleJackpot: (token: Address) => Promise<TxRequest>;
458
+ buy: (k: PoolKey, bnbIn: bigint, minOut: bigint, deadline?: bigint) => TxRequest;
459
+ sell: (k: PoolKey, amount: bigint, minOut: bigint, deadline?: bigint) => TxRequest;
460
+ launch: (l: AgentLaunch) => TxRequest;
461
+ };
462
+ buy: (b: {
463
+ token: Address;
464
+ bnbIn: bigint;
465
+ slippageBps?: number;
466
+ minOut?: bigint;
467
+ deadline?: bigint;
468
+ }, s?: SendOptions) => Promise<Sent & {
469
+ quoted: bigint;
470
+ minOut: bigint;
471
+ }>;
472
+ sell: (x: {
473
+ token: Address;
474
+ amount: bigint;
475
+ slippageBps?: number;
476
+ minOut?: bigint;
477
+ deadline?: bigint;
478
+ }, s?: SendOptions) => Promise<Sent & {
479
+ quoted: bigint;
480
+ minOut: bigint;
481
+ }>;
482
+ act: (token: Address, answer: AgentAnswer) => Promise<{
483
+ tx: TxRequest | null;
484
+ proposal?: string[];
485
+ notes: string[];
486
+ note: Hex;
487
+ }>;
488
+ /** the pilot sends what a model's answer asks for; { tx: null } for "none" */
489
+ pilot: (token: Address, answer: AgentAnswer, s?: SendOptions) => Promise<{
490
+ sent: Sent | null;
491
+ tx: TxRequest | null;
492
+ proposal?: string[];
493
+ notes: string[];
494
+ note: Hex;
495
+ }>;
496
+ propose: (token: Address, p: Program | Partial<Plan>, note?: Hex | string | {
497
+ title: string;
498
+ body: string;
499
+ }, s?: SendOptions) => Promise<Sent>;
500
+ cancel: (token: Address, s?: SendOptions) => Promise<Sent>;
501
+ move: (token: Address, from: Bucket | number, to: Bucket | number, wei: bigint, s?: SendOptions) => Promise<Sent>;
502
+ handOver: (token: Address, to: Address, s?: SendOptions) => Promise<Sent>;
503
+ activate: (token: Address, s?: SendOptions) => Promise<Sent>;
504
+ veto: (token: Address, amount: bigint, s?: SendOptions) => Promise<Sent>;
505
+ fire: (token: Address, amount: bigint, s?: SendOptions) => Promise<Sent>;
506
+ withdraw: (token: Address, s?: SendOptions) => Promise<Sent>;
507
+ give: (token: Address, bucket: Bucket | number, wei: bigint, s?: SendOptions) => Promise<Sent>;
508
+ claim: (s?: SendOptions) => Promise<Sent>;
509
+ burn: (token: Address, s?: SendOptions) => Promise<Sent>;
510
+ addLiquidity: (token: Address, s?: SendOptions) => Promise<Sent>;
511
+ feedFloor: (token: Address, s?: SendOptions) => Promise<Sent>;
512
+ settleJackpot: (token: Address, s?: SendOptions) => Promise<Sent>;
513
+ launch: (l: AgentLaunch, s?: SendOptions) => Promise<Sent & {
514
+ token: Address;
515
+ id: Hex;
516
+ floor: Address;
517
+ }>;
518
+ prepareMetadata: (m: {
519
+ name: string;
520
+ symbol: string;
521
+ description?: string;
522
+ website?: string;
523
+ twitter?: string;
524
+ telegram?: string;
525
+ image: {
526
+ mime: "image/png" | "image/jpeg" | "image/webp" | "image/gif";
527
+ bytes: Uint8Array;
528
+ };
529
+ /** the agent's brief: name, a personality of PERSONALITIES, up to 3 objectives of OBJECTIVES, a mission, up to 3 ideas */
530
+ agent?: {
531
+ name?: string;
532
+ personality?: (typeof PERSONALITIES)[number];
533
+ objectives?: string[];
534
+ mission?: string;
535
+ ideas?: string[];
536
+ };
537
+ }) => Promise<{
538
+ metadata: string;
539
+ image: string;
540
+ salt: Hex;
541
+ }>;
542
+ };
543
+ export type AgentsModule = ReturnType<typeof agentsModule>;