clockwork-press 0.2.1 → 0.2.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.
- package/dist/env.js +1 -1
- package/dist/jobs/init.js +3 -3
- package/dist/press.js +50 -1
- package/package.json +2 -2
- package/skills/clockwork/SKILL.md +11 -10
package/dist/env.js
CHANGED
|
@@ -34,7 +34,7 @@ export const cfg = {
|
|
|
34
34
|
// a native launch is quoted in eth: the pair address is the zero address and the escrow keeps it on its native ledger.
|
|
35
35
|
gme: c.pair.address, pair: c.pair.address, pairSymbol: pairNative ? 'ETH' : c.pair.symbol, pairDecimals: pairNative ? 18 : c.pair.decimals ?? 18, pairNative,
|
|
36
36
|
token: c.token.address, tokenSymbol: c.token.symbol, tokenName: c.token.name, totalSupply: c.token.supply ?? 1_000_000_000,
|
|
37
|
-
escrow: (c.launch.feeEscrow || ''), locker: (c.launch.locker || ''), claimMode: c.claim.mode, claimFloor: Number(c.claim.floor ?? 5), claimEveryHours: Number(c.claim.atLeastEveryHours ?? 24),
|
|
37
|
+
escrow: (c.launch.feeEscrow || ''), locker: (c.launch.locker || ''), claimMode: c.claim.mode, claimFloor: Number(c.claim.floor ?? 5), lowGasEth: Number(c.alerts?.lowGasEth ?? 0.005), claimEveryHours: Number(c.claim.atLeastEveryHours ?? 24),
|
|
38
38
|
hook: (c.launch.hook || '0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044'), vault: (c.launch.vault || '0x42df2a798f82289E177311362e8f5ccC45c1219c'),
|
|
39
39
|
vestMode: c.buyback?.vest ?? 'burn', paceWord: pace,
|
|
40
40
|
// ops is '' when the client has no ops wallet; the ops leg then holds (and validate() refuses opsBps > 0 without one)
|
package/dist/jobs/init.js
CHANGED
|
@@ -56,10 +56,10 @@ export async function runInit() {
|
|
|
56
56
|
split: house ? { burnBps: 5000, treasuryBps: 5000, opsBps: 0, serviceBps: 0 } : { burnBps: 4500, treasuryBps: 4500, opsBps: 0, serviceBps: 1000 },
|
|
57
57
|
schedule: { cadenceMin: 15, weekends: true, napUntil: null },
|
|
58
58
|
slices: { rule: { kind: 'pace', pace: 'steady' }, dip: { on: false, bandBps: 1000, multiplier: 2 }, quoteSanityBps: 1500, maxSlippageBps: 300 },
|
|
59
|
-
burn: { method: 'burn' }, buyback: { vest: 'burn' }, claim: { mode: 'auto', floor: pair.symbol
|
|
60
|
-
telegram: { mode: '
|
|
59
|
+
burn: { method: 'burn' }, buyback: { vest: 'burn' }, claim: { mode: 'auto', floor: ['ETH', 'WETH'].includes(String(pair.symbol)) ? 0.05 : ['USDG', 'USDC', 'USDT', 'DAI', 'USD1'].includes(String(pair.symbol).toUpperCase()) ? 100 : 5, atLeastEveryHours: 24 },
|
|
60
|
+
telegram: { mode: 'own', chatId: '', cards: { claim: true, slice: true, percent: true, buys: false }, buyFloorUsd: 50 }, // own bot until the shared clockwork bot exists; chatId from `clockwork tgcheck`
|
|
61
61
|
site: { enabled: true, modules: ['treasury', 'burns', 'holders', 'seats', 'wallet', 'rank', 'ledger'], seatThreshold: 250000 },
|
|
62
|
-
brand: { name: tName, treasuryWord: 'treasury', burnWord: 'burn', accent: '#
|
|
62
|
+
brand: { name: tName, treasuryWord: 'treasury', burnWord: 'burn', accent: '#0B6E4F', avatar: '' },
|
|
63
63
|
};
|
|
64
64
|
writeFileSync(out, JSON.stringify(cfg, null, 1) + '\n');
|
|
65
65
|
console.log(`wrote ${out}: ${tName} (${tSym}) paired with ${pair.symbol}${native ? ' (native)' : ` at ${pair.address}`}, ${PHASES[Number(lt.phase)] ?? `phase ${lt.phase}`}, buybacks ${lt.buybackEnabled ? 'on' : 'off'}.`);
|
package/dist/press.js
CHANGED
|
@@ -108,6 +108,31 @@ async function scanStash(fairUsd) {
|
|
|
108
108
|
await postCard(ART.press, [`${cfg.emoji} ${W.claim} #${entry.k}`, `${W.treasury}: +${gme.toFixed(2)} ${cfg.pairSymbol}. never sold, never distributed.`, fedNote ? fedNote.trim() : null, `the ${W.treasury}: ${Math.round(totals().stashedGme).toLocaleString('en-US')} ${cfg.pairSymbol}`]);
|
|
109
109
|
added++;
|
|
110
110
|
}
|
|
111
|
+
// the treasury-outflow watch: the treasury only grows; any transfer out of it is news, posted once per hash
|
|
112
|
+
try {
|
|
113
|
+
const outs = await pub.getLogs({
|
|
114
|
+
address: cfg.gme, event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'),
|
|
115
|
+
args: { from: cfg.stash }, fromBlock: from, toBlock: latest,
|
|
116
|
+
});
|
|
117
|
+
for (const log of outs) {
|
|
118
|
+
const amt = log.args.value;
|
|
119
|
+
if (amt === 0n)
|
|
120
|
+
continue;
|
|
121
|
+
const l = readLedger();
|
|
122
|
+
l.meta = { ...(l.meta ?? {}) };
|
|
123
|
+
const seen = l.meta.treasuryOutflows ?? [];
|
|
124
|
+
if (seen.some((o) => o.tx === log.transactionHash))
|
|
125
|
+
continue;
|
|
126
|
+
const rec = { tx: log.transactionHash, amount: Number(formatUnits(amt, cfg.pairDecimals)).toFixed(4), to: String(log.args.to), at: new Date().toISOString() };
|
|
127
|
+
l.meta.treasuryOutflows = [...seen, rec].slice(-20);
|
|
128
|
+
writeLedger(l);
|
|
129
|
+
console.log(`[press] the ${W.treasury} moved: ${rec.amount} ${cfg.pairSymbol} left it to ${rec.to.slice(0, 6)}…${rec.to.slice(-4)} (${rec.tx})`);
|
|
130
|
+
await postCard('', [`${cfg.emoji} the ${W.treasury} moved`, `${rec.amount} ${cfg.pairSymbol} left the ${W.treasury} to ${rec.to.slice(0, 6)}…${rec.to.slice(-4)}.`, `if this was the founder, nothing to do. if not, look now.`]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
console.log(`[press] outflow watch skipped: ${e.shortMessage || e.message}`);
|
|
135
|
+
}
|
|
111
136
|
const l2 = readLedger();
|
|
112
137
|
l2.stashScanBlock = latest.toString();
|
|
113
138
|
writeLedger(l2);
|
|
@@ -303,8 +328,12 @@ async function pressOnce(runAt, commit) {
|
|
|
303
328
|
// what every stats write carries this run; the recipient watch and unswept are filled in once known.
|
|
304
329
|
// the recipient row is red whenever an auto-mode machine is not where the fees point, key or no key.
|
|
305
330
|
// lastRunAt is whatever the file holds: markRun sets it when a run commits to work, never a napping tick.
|
|
331
|
+
// supply locked at graduation sits in the pons locker and never comes out: out of circulation, like a burn
|
|
332
|
+
const lockedTokens = cfg.locker ? await tryRead('locker', () => pub.readContract({ address: token, abi: erc20Abi, functionName: 'balanceOf', args: [cfg.locker] }), 0n) : 0n;
|
|
333
|
+
const locked = lockedTokens > 0n ? { tokens: formatUnits(lockedTokens, 18), pctOfMint: ((Number(lockedTokens) / Number(TOTAL_SUPPLY)) * 100).toFixed(2) } : null;
|
|
306
334
|
const common = () => ({
|
|
307
335
|
presses: countKind('press'), snacks: countKind('snack'), checkedAt: new Date().toISOString(), peg: pegOut,
|
|
336
|
+
locked, treasuryOutflow: readLedger().meta?.treasuryOutflows?.at(-1) ?? null,
|
|
308
337
|
cadenceMin: cfg.cadenceMin, days: dailyRollup(), holders, lastRunAt: prevStats().lastRunAt,
|
|
309
338
|
phase: s.phaseWord, graduationPct: s.graduationPct,
|
|
310
339
|
feeRecipient: { address: s.recipient, ok: cfg.claimMode !== 'auto' || same(s.recipient, cfg.pressWallet) }, pendingRecipient: null,
|
|
@@ -327,6 +356,26 @@ async function pressOnce(runAt, commit) {
|
|
|
327
356
|
}
|
|
328
357
|
const me = account().address;
|
|
329
358
|
const w = wallet();
|
|
359
|
+
// one card a day when the machine wallet runs low on gas; the number rides in stats for the status page
|
|
360
|
+
let gasEth = '0', gasLow = false;
|
|
361
|
+
try {
|
|
362
|
+
const gas = await pub.getBalance({ address: me });
|
|
363
|
+
gasEth = Number(formatUnits(gas, 18)).toFixed(4);
|
|
364
|
+
gasLow = gas < parseUnits(String(cfg.lowGasEth), 18);
|
|
365
|
+
if (gasLow) {
|
|
366
|
+
const l = readLedger();
|
|
367
|
+
const last = l.meta?.lowGasAlertAt ? new Date(l.meta.lowGasAlertAt).getTime() : 0;
|
|
368
|
+
console.log(`[press] gas low: ${gasEth} eth in the machine wallet (floor ${cfg.lowGasEth})`);
|
|
369
|
+
if (Date.now() - last > 86_400_000 && !cfg.dry) {
|
|
370
|
+
l.meta = { ...(l.meta ?? {}), lowGasAlertAt: new Date().toISOString() };
|
|
371
|
+
writeLedger(l);
|
|
372
|
+
await postCard('', [`${cfg.emoji} gas is low`, `the machine wallet holds ${gasEth} eth. a few more ticks and it cannot burn.`, `send a little eth to ${me.slice(0, 6)}…${me.slice(-4)}.`]);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch (e) {
|
|
377
|
+
console.log(`[press] gas check skipped: ${e.shortMessage || e.message}`);
|
|
378
|
+
}
|
|
330
379
|
// 0b. The recipient watch, then the claim block.
|
|
331
380
|
const watch = await watchRecipient(s, me);
|
|
332
381
|
const mine = same(s.recipient, me);
|
|
@@ -425,7 +474,7 @@ async function pressOnce(runAt, commit) {
|
|
|
425
474
|
}
|
|
426
475
|
}
|
|
427
476
|
}
|
|
428
|
-
const watched = () => ({ ...common(), feeRecipient: watch.feeRecipient, pendingRecipient: watch.pendingRecipient, unswept: unsweptOut, escrowOwed: escrowOut, claimFloor: cfg.claimFloor });
|
|
477
|
+
const watched = () => ({ ...common(), feeRecipient: watch.feeRecipient, pendingRecipient: watch.pendingRecipient, unswept: unsweptOut, escrowOwed: escrowOut, claimFloor: cfg.claimFloor, gasEth, gasLow });
|
|
429
478
|
// 2. The float. Everything the wallet holds is pressed; held-back ops
|
|
430
479
|
// slices from earlier presses roll in naturally. A native pair keeps its gas money.
|
|
431
480
|
let floatBal = await pairBal(me);
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clockwork-press",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "your fees, on a clock, with receipts. the fee machine for tokens on robinhood chain.",
|
|
6
|
+
"description": "your fees, on a clock, with receipts. ClockWorks, the fee machine for tokens on robinhood chain.",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clockwork
|
|
3
|
-
description: Set up and run a
|
|
3
|
+
description: Set up and run a ClockWorks machine for a pons v2 token on Robinhood Chain. Use when a founder asks to automate their creator fees, buy back and burn, build a treasury, or "run ClockWorks" for their token. Walks the human through the machine wallet, the config, the repository, the secrets, the dry run, pointing fees at the machine, and going live. Never touches a private key.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# ClockWorks, with an assistant next to you
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
ClockWorks runs a token's creator fees on a clock: claims from the pons fee escrow, splits by percentages the
|
|
9
9
|
founder sets once, buys the token back and burns it in slices, sends the treasury share to a wallet that only
|
|
10
10
|
grows, and prints every hash. It runs in the founder's own GitHub repository on a wallet the founder created.
|
|
11
11
|
Docs: https://gmerald.xyz/clockwork/docs/
|
|
@@ -23,15 +23,16 @@ Docs: https://gmerald.xyz/clockwork/docs/
|
|
|
23
23
|
1. The token address (a pons v2 launch on Robinhood Chain, chain id 4663).
|
|
24
24
|
2. A fresh machine wallet address, created on their device, with about 0.02 ETH on Robinhood Chain.
|
|
25
25
|
3. A treasury wallet address (a cold wallet is best).
|
|
26
|
-
4. The split they want. Default: 45 burn / 45 treasury / 0 ops / 10
|
|
26
|
+
4. The split they want. Default: 45 burn / 45 treasury / 0 ops / 10 ClockWorks. The ClockWorks share is at
|
|
27
27
|
least 10 and is what pays for the software.
|
|
28
28
|
5. The pace: gentle (a claim over a day), steady (over six hours, the default), or once (one slice).
|
|
29
|
-
6. Telegram: their own bot token set as a secret (they create the bot in @BotFather)
|
|
30
|
-
7.
|
|
29
|
+
6. Telegram: their own bot token set as a secret (they create the bot in @BotFather) and the group's chat id from `clockwork tgcheck`, or `telegram.mode` set to `off` for now. The config defaults to `own`; with no token set, the machine logs and posts nothing.
|
|
30
|
+
7. The brand: `brand.name`, the words for treasury and burn (`brand.treasuryWord`, `brand.burnWord`, `brand.claimWord`), `brand.avatar` (an image URL the status page and the wallet card use), and `brand.art` (one image or short mp4 URL per Telegram card).
|
|
31
|
+
8. How often to claim: `claim.floor` is how much of the pairing asset must be waiting in the escrow before the machine claims (default 5), and `claim.atLeastEveryHours` claims whatever waits at least that often (default 24). A claim costs gas and posts a card; most machines keep the defaults.
|
|
31
32
|
|
|
32
33
|
## The steps
|
|
33
34
|
1. **Write the config.** In a terminal with Node 20 or newer, in an empty folder:
|
|
34
|
-
`npx --yes clockwork-press@0.2.
|
|
35
|
+
`npx --yes clockwork-press@0.2.1 init <token address>`
|
|
35
36
|
It reads the launch from the pons factory and writes `clockwork.json`. Fill `wallets.machine`,
|
|
36
37
|
`wallets.treasury`, the `split`, and `slices.rule` (`{ "kind": "pace", "pace": "steady" }`). If they want
|
|
37
38
|
Telegram, set `telegram.mode` to `own` and `telegram.chatId` to their group id. Do not put a key or a token
|
|
@@ -47,7 +48,7 @@ Docs: https://gmerald.xyz/clockwork/docs/
|
|
|
47
48
|
the float, and `dry: would swap …`. The machine refuses to run if the key belongs to a different wallet
|
|
48
49
|
than `wallets.machine`; that is the guard working, not a bug.
|
|
49
50
|
5. **Point the fees at the machine.** First claim what is already owed to the current recipient
|
|
50
|
-
(`npx --yes clockwork-press@0.2.
|
|
51
|
+
(`npx --yes clockwork-press@0.2.1 claimcheck` from the folder with `clockwork.json` prints it), because a
|
|
51
52
|
recipient change does not move credited balances. Then the current recipient signs
|
|
52
53
|
`transferCreatorFeeRecipient(token, machineWallet)` on the pons factory
|
|
53
54
|
`0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e`. Prepare the calldata for them (function selector
|
|
@@ -76,6 +77,6 @@ Docs: https://gmerald.xyz/clockwork/docs/
|
|
|
76
77
|
`claimcheck` what the escrow holds and what is unswept · `doctor` RPC, wallet, gas, recipient, Telegram ·
|
|
77
78
|
`handback <address>` claim what is credited, then move the fee recipient · `holders` the holder count.
|
|
78
79
|
|
|
79
|
-
## What
|
|
80
|
-
Ten percent of every claim, sent on chain by the machine, slice by slice, to the
|
|
80
|
+
## What ClockWorks costs
|
|
81
|
+
Ten percent of every claim, sent on chain by the machine, slice by slice, to the ClockWorks wallet pinned in
|
|
81
82
|
the package (`0x6EA62Bd07FE08C7491543d495B42F6dA7ad298D0`). No setup fee. The chain is the invoice.
|