@tempoxyz/patron 0.0.29 → 0.0.31
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/bin.js +11 -3
- package/dist/chunks/{-OLVAZG3H.js → -K6MPD575.js} +256 -64
- package/dist/chunks/{chunk-HQ2ZLUTT.js → chunk-6G6SAUGB.js} +1 -1
- package/dist/chunks/{chunk-SAEZ54SS.js → chunk-AN64RW3X.js} +8 -8
- package/dist/chunks/{chunk-ZOQJ4CZE.js → chunk-GBZCXMDZ.js} +7 -165
- package/dist/chunks/chunk-IIB6TI3U.js +196 -0
- package/dist/chunks/{chunk-EISHX7Q3.js → chunk-JTPFWITF.js} +208 -48
- package/dist/chunks/{chunk-OQXACACU.js → chunk-NDBTADXZ.js} +9 -2
- package/dist/chunks/{hook-HYV4BSCN.js → hook-6DQ3RLVH.js} +7 -8
- package/dist/chunks/{hook-process-6WSLYXC7.js → hook-process-W3ZK5FT3.js} +60 -14
- package/dist/chunks/{wallet-LOLL66ID.js → wallet-WR6EBMN6.js} +3 -4
- package/package.json +1 -1
- package/dist/chunks/chunk-3CYJJJR3.js +0 -56
package/dist/bin.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
3
3
|
const require = __patronCreateRequire(import.meta.url)
|
|
4
|
+
import {
|
|
5
|
+
inferHome
|
|
6
|
+
} from "./chunks/chunk-NDBTADXZ.js";
|
|
7
|
+
import "./chunks/chunk-GTMLTZRN.js";
|
|
4
8
|
|
|
5
9
|
// src/bin.ts
|
|
10
|
+
if (!process.env.PATRON_HOME) {
|
|
11
|
+
const home = inferHome(process.argv[1]);
|
|
12
|
+
if (home) process.env.PATRON_HOME = home;
|
|
13
|
+
}
|
|
6
14
|
if (process.argv[2] === "hook") {
|
|
7
|
-
const { runHookProcess } = await import("./chunks/hook-process-
|
|
15
|
+
const { runHookProcess } = await import("./chunks/hook-process-W3ZK5FT3.js");
|
|
8
16
|
await runHookProcess().catch(() => void 0);
|
|
9
17
|
process.exit(0);
|
|
10
18
|
} else if (process.argv[2] === "pay") {
|
|
11
|
-
const { runPayProcess } = await import("./chunks/hook-process-
|
|
19
|
+
const { runPayProcess } = await import("./chunks/hook-process-W3ZK5FT3.js");
|
|
12
20
|
await runPayProcess().catch(() => void 0);
|
|
13
21
|
process.exit(0);
|
|
14
22
|
} else {
|
|
15
|
-
const { run } = await import("./chunks/-
|
|
23
|
+
const { run } = await import("./chunks/-K6MPD575.js");
|
|
16
24
|
process.exitCode = await run(process.argv.slice(2));
|
|
17
25
|
}
|
|
@@ -21,7 +21,9 @@ import {
|
|
|
21
21
|
purchasableTokens,
|
|
22
22
|
readJsonObject,
|
|
23
23
|
redeem,
|
|
24
|
+
refillSize,
|
|
24
25
|
removeCodex,
|
|
26
|
+
storedIssuer,
|
|
25
27
|
tipTokens,
|
|
26
28
|
upgradeCodex,
|
|
27
29
|
withHooksKey,
|
|
@@ -29,41 +31,44 @@ import {
|
|
|
29
31
|
withPatronStatus,
|
|
30
32
|
withoutPatronHandlers,
|
|
31
33
|
writeJsonObject
|
|
32
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-AN64RW3X.js";
|
|
33
35
|
import {
|
|
36
|
+
awaitRedemptions,
|
|
37
|
+
gatewayTurn,
|
|
34
38
|
startRefill
|
|
35
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-IIB6TI3U.js";
|
|
36
40
|
import {
|
|
41
|
+
inferHome,
|
|
37
42
|
resolveSettings,
|
|
38
43
|
settingsFor
|
|
39
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-NDBTADXZ.js";
|
|
40
45
|
import {
|
|
41
|
-
AGENT_IDS,
|
|
42
46
|
LeaderboardResponse,
|
|
43
47
|
PatronInfo,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
readConfig,
|
|
47
|
-
readJson,
|
|
48
|
-
readUsage,
|
|
49
|
-
statePaths,
|
|
50
|
-
updateUsage,
|
|
51
|
-
writeConfig,
|
|
52
|
-
writePrivateFile
|
|
53
|
-
} from "./chunk-ZOQJ4CZE.js";
|
|
48
|
+
profileMessage
|
|
49
|
+
} from "./chunk-GBZCXMDZ.js";
|
|
54
50
|
import {
|
|
51
|
+
AGENT_IDS,
|
|
55
52
|
DEFAULT_MONTHLY_BUDGET_USD,
|
|
56
53
|
MAX_TOKENS_PER_PAGE,
|
|
57
54
|
MIN_TOKENS_PER_PAGE,
|
|
58
55
|
PACK_SIZE,
|
|
59
56
|
TOKEN_PRICE_UNITS,
|
|
60
57
|
clampTokensPerPage,
|
|
58
|
+
ensureHome,
|
|
61
59
|
formatUsd,
|
|
62
60
|
normalizePayee,
|
|
61
|
+
readConfig,
|
|
62
|
+
readJson,
|
|
63
|
+
readUsage,
|
|
64
|
+
statePaths,
|
|
63
65
|
tokensToUnits,
|
|
64
66
|
tryLock,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
updateUsage,
|
|
68
|
+
withLock,
|
|
69
|
+
writeConfig,
|
|
70
|
+
writePrivateFile
|
|
71
|
+
} from "./chunk-JTPFWITF.js";
|
|
67
72
|
import "./chunk-GTMLTZRN.js";
|
|
68
73
|
|
|
69
74
|
// src/index.ts
|
|
@@ -356,15 +361,16 @@ import {
|
|
|
356
361
|
realpath,
|
|
357
362
|
rename,
|
|
358
363
|
rm as rm3,
|
|
359
|
-
symlink
|
|
364
|
+
symlink,
|
|
365
|
+
writeFile as writeFile2
|
|
360
366
|
} from "node:fs/promises";
|
|
361
367
|
import { basename, dirname as dirname3, join as join4 } from "node:path";
|
|
362
368
|
function stableBin(home) {
|
|
363
369
|
return join4(home, "cli", "current", "dist", "bin.js");
|
|
364
370
|
}
|
|
365
|
-
async function installStableCli(home, script = process.argv[1]) {
|
|
371
|
+
async function installStableCli(home, script = process.argv[1], anySource = process.platform === "win32" && Boolean(process.env.PATRON_HOME)) {
|
|
366
372
|
const resolved = script ? await realpath(script).catch(() => void 0) : void 0;
|
|
367
|
-
if (!resolved || !/[/\\]_npx[/\\]/.test(resolved) || basename(resolved) !== "bin.js")
|
|
373
|
+
if (!resolved || !anySource && !/[/\\]_npx[/\\]/.test(resolved) || basename(resolved) !== "bin.js")
|
|
368
374
|
return void 0;
|
|
369
375
|
const packageDir = dirname3(dirname3(resolved));
|
|
370
376
|
const { version } = JSON.parse(await readFile3(join4(packageDir, "package.json"), "utf8"));
|
|
@@ -377,6 +383,7 @@ async function installStableCli(home, script = process.argv[1]) {
|
|
|
377
383
|
await rm3(staging, { force: true, recursive: true });
|
|
378
384
|
await cp(join4(packageDir, "dist"), join4(staging, "dist"), { recursive: true });
|
|
379
385
|
await cp(join4(packageDir, "package.json"), join4(staging, "package.json"));
|
|
386
|
+
await writeFile2(join4(staging, "origin.json"), JSON.stringify({ bin: resolved }));
|
|
380
387
|
await rm3(target, { force: true, recursive: true });
|
|
381
388
|
await rename(staging, target);
|
|
382
389
|
}
|
|
@@ -549,23 +556,45 @@ function failure(agent, error) {
|
|
|
549
556
|
state: "failed"
|
|
550
557
|
};
|
|
551
558
|
}
|
|
552
|
-
async function hookCommand(env = process.env, script = process.argv[1], node = process.execPath, patronHome = env.PATRON_HOME || join5(homedir(), ".patron")) {
|
|
559
|
+
async function hookCommand(env = process.env, script = process.argv[1], node = process.execPath, patronHome = env.PATRON_HOME || join5(homedir(), ".patron"), platform = process.platform) {
|
|
553
560
|
if (env.PATRON_HOOK_COMMAND) return env.PATRON_HOOK_COMMAND;
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
561
|
+
const windows = platform === "win32";
|
|
562
|
+
const run2 = await runCommand(
|
|
563
|
+
script,
|
|
564
|
+
node,
|
|
565
|
+
patronHome,
|
|
566
|
+
windows && Boolean(env.PATRON_HOME),
|
|
567
|
+
platform
|
|
568
|
+
);
|
|
569
|
+
if (!env.PATRON_HOME || windows || await runsFromHome(run2.bin, patronHome))
|
|
570
|
+
return run2.command;
|
|
571
|
+
return withPatronHome(run2.command, env.PATRON_HOME);
|
|
572
|
+
}
|
|
573
|
+
async function runCommand(script, node, patronHome, preferCopy, platform) {
|
|
574
|
+
const run2 = (bin) => ({
|
|
575
|
+
bin,
|
|
576
|
+
command: `${quote(node, platform)} ${quote(bin, platform)} hook`
|
|
577
|
+
});
|
|
578
|
+
const stable = stableBin(patronHome);
|
|
579
|
+
if (preferCopy && await exists(stable)) return run2(stable);
|
|
557
580
|
const resolved = script ? await realpath2(script).catch(() => void 0) : void 0;
|
|
558
581
|
if (resolved && /[/\\]bin\.js$/.test(resolved) && !/[/\\]_npx[/\\]/.test(resolved))
|
|
559
|
-
return
|
|
560
|
-
if (await exists(
|
|
561
|
-
|
|
562
|
-
|
|
582
|
+
return run2(resolved);
|
|
583
|
+
if (await exists(stable)) return run2(stable);
|
|
584
|
+
return { command: "npx -y @tempoxyz/patron hook" };
|
|
585
|
+
}
|
|
586
|
+
async function runsFromHome(bin, patronHome) {
|
|
587
|
+
const inferred = inferHome(bin);
|
|
588
|
+
if (!inferred) return false;
|
|
589
|
+
const real = (path) => realpath2(path).catch(() => resolve(path));
|
|
590
|
+
return await real(inferred) === await real(patronHome);
|
|
563
591
|
}
|
|
564
592
|
function withPatronHome(command, patronHome) {
|
|
565
593
|
return patronHome ? `PATRON_HOME=${quote(resolve(patronHome))} ${command}` : command;
|
|
566
594
|
}
|
|
567
|
-
function quote(value) {
|
|
568
|
-
|
|
595
|
+
function quote(value, platform = process.platform) {
|
|
596
|
+
if (/^[\w./:@-]+$/.test(value)) return value;
|
|
597
|
+
return platform === "win32" ? `"${value}"` : `'${value.replaceAll("'", "'\\''")}'`;
|
|
569
598
|
}
|
|
570
599
|
async function exists(path) {
|
|
571
600
|
return access2(path).then(
|
|
@@ -751,10 +780,10 @@ async function linkRefillFailedAt(home) {
|
|
|
751
780
|
}
|
|
752
781
|
var defaultOpenWallet = async (settings, config, issuer, maxUnits) => {
|
|
753
782
|
if (config.wallet === "link") {
|
|
754
|
-
const { openLinkWallet } = await import("./wallet-
|
|
783
|
+
const { openLinkWallet } = await import("./wallet-WR6EBMN6.js");
|
|
755
784
|
return openLinkWallet(config, maxUnits);
|
|
756
785
|
}
|
|
757
|
-
const { openWallet } = await import("./wallet-
|
|
786
|
+
const { openWallet } = await import("./wallet-WR6EBMN6.js");
|
|
758
787
|
return openWallet(settings, config.wallet, issuer, maxUnits);
|
|
759
788
|
};
|
|
760
789
|
var REFILL_LOCK_STALE_MS = 5 * 60 * 1e3;
|
|
@@ -794,23 +823,43 @@ async function delayedRefill(base, openWallet = defaultOpenWallet, sleep = (ms)
|
|
|
794
823
|
if (!await readConfig(base.home)) return 0;
|
|
795
824
|
const release = await tryLock(
|
|
796
825
|
statePaths(base.home).refillWait,
|
|
797
|
-
REFILL_DELAY_MS.max + REFILL_LOCK_STALE_MS
|
|
826
|
+
REFILL_DELAY_MS.max + REFILL_GATEWAY_WAIT_MS + REFILL_LOCK_STALE_MS
|
|
798
827
|
);
|
|
799
828
|
if (!release) return 0;
|
|
800
829
|
try {
|
|
801
830
|
await sleep(
|
|
802
831
|
REFILL_DELAY_MS.min + random() * (REFILL_DELAY_MS.max - REFILL_DELAY_MS.min)
|
|
803
832
|
);
|
|
833
|
+
return await refill(base, openWallet, Date.now, sleep);
|
|
804
834
|
} finally {
|
|
805
835
|
await release();
|
|
806
836
|
}
|
|
807
|
-
return refill(base, openWallet);
|
|
808
837
|
}
|
|
809
|
-
|
|
838
|
+
var REFILL_GATEWAY_WAIT_MS = 15 * 60 * 1e3;
|
|
839
|
+
async function refill(base, openWallet = defaultOpenWallet, now = Date.now, sleep) {
|
|
810
840
|
const config = await readConfig(base.home);
|
|
811
841
|
if (!config || config.paused) return 0;
|
|
812
842
|
const settings = settingsFor(base, config);
|
|
813
|
-
await
|
|
843
|
+
const stale = (await storedIssuer(settings.home, settings.gatewayUrl))?.stale ?? true;
|
|
844
|
+
const low = needsRefill(await new FileTokenStore(settings.home).count()) && await linkBackedOff(settings.home, config, now()) === false && await readUsage(settings.home).then(
|
|
845
|
+
(usage) => refillSize(config, usage) > 0,
|
|
846
|
+
() => true
|
|
847
|
+
);
|
|
848
|
+
if (!stale && !low) return 0;
|
|
849
|
+
const bought = await gatewayTurn(
|
|
850
|
+
settings.home,
|
|
851
|
+
async () => {
|
|
852
|
+
const current = await readConfig(base.home);
|
|
853
|
+
if (!current || current.paused) return 0;
|
|
854
|
+
const latest = settingsFor(base, current);
|
|
855
|
+
if (stale) await loadIssuer(latest.home, latest.gatewayUrl).catch(() => void 0);
|
|
856
|
+
return low ? refillLocked(latest, current, openWallet, now) : 0;
|
|
857
|
+
},
|
|
858
|
+
{ maxWaitMs: REFILL_GATEWAY_WAIT_MS, ...sleep ? { sleep } : {} }
|
|
859
|
+
);
|
|
860
|
+
return bought ?? 0;
|
|
861
|
+
}
|
|
862
|
+
async function refillLocked(settings, config, openWallet, now) {
|
|
814
863
|
const release = await tryLock(
|
|
815
864
|
statePaths(settings.home).refillLock,
|
|
816
865
|
REFILL_LOCK_STALE_MS
|
|
@@ -820,8 +869,7 @@ async function refill(base, openWallet = defaultOpenWallet, now = Date.now) {
|
|
|
820
869
|
if (!needsRefill(await new FileTokenStore(settings.home).count())) return 0;
|
|
821
870
|
if (config.wallet !== "link")
|
|
822
871
|
return await buyWithinBudget(settings, config, PACK_SIZE, openWallet);
|
|
823
|
-
|
|
824
|
-
if (failedAt !== void 0 && now() - failedAt < LINK_REFILL_BACKOFF_MS) return 0;
|
|
872
|
+
if (await linkBackedOff(settings.home, config, now())) return 0;
|
|
825
873
|
const path = statePaths(settings.home).linkRefill;
|
|
826
874
|
try {
|
|
827
875
|
const bought = await buyWithinBudget(settings, config, PACK_SIZE, openWallet);
|
|
@@ -835,6 +883,11 @@ async function refill(base, openWallet = defaultOpenWallet, now = Date.now) {
|
|
|
835
883
|
await release();
|
|
836
884
|
}
|
|
837
885
|
}
|
|
886
|
+
async function linkBackedOff(home, config, now) {
|
|
887
|
+
if (config.wallet !== "link") return false;
|
|
888
|
+
const failedAt = await linkRefillFailedAt(home);
|
|
889
|
+
return failedAt !== void 0 && now - failedAt < LINK_REFILL_BACKOFF_MS;
|
|
890
|
+
}
|
|
838
891
|
|
|
839
892
|
// src/render.ts
|
|
840
893
|
function tokensUsd(tokens) {
|
|
@@ -871,9 +924,20 @@ function formatStatus(view, color) {
|
|
|
871
924
|
),
|
|
872
925
|
row(
|
|
873
926
|
"Rank",
|
|
874
|
-
standing?.rank ? `#${standing.rank} \xB7 ${tokensUsd(standing.tokens)} added` : styleText("not ranked yet", "dim", color),
|
|
927
|
+
standing?.rank ? `#${standing.rank} \xB7 ${tokensUsd(standing.tokens)} added${view.standingSkipped ? styleText(" (last check)", "dim", color) : ""}` : view.standingSkipped ? styleText("not checked right now", "dim", color) : styleText("not ranked yet", "dim", color),
|
|
875
928
|
color
|
|
876
929
|
),
|
|
930
|
+
...view.standingSkipped ? [
|
|
931
|
+
row(
|
|
932
|
+
"",
|
|
933
|
+
styleText(
|
|
934
|
+
"Checked once your agents' payments go quiet, so the two can't be linked.",
|
|
935
|
+
"dim",
|
|
936
|
+
color
|
|
937
|
+
),
|
|
938
|
+
color
|
|
939
|
+
)
|
|
940
|
+
] : [],
|
|
877
941
|
row(
|
|
878
942
|
"Agents",
|
|
879
943
|
config.agents.length > 0 ? config.agents.map((agent) => AGENT_LABELS[agent]).join(", ") : styleText("none", "dim", color),
|
|
@@ -925,6 +989,76 @@ PATRON_WALLET=link (pay with Link through link-cli), PATRON_LINK_CLI (its path).
|
|
|
925
989
|
var UsageError = class extends Error {
|
|
926
990
|
};
|
|
927
991
|
var TIP_BATCH = 8;
|
|
992
|
+
var TIP_REDEEM_TIMEOUT_MS = 3e4;
|
|
993
|
+
var TIP_BATCH_LEASE_MS = 6e4;
|
|
994
|
+
async function inGatewayTurn(deps, fn) {
|
|
995
|
+
const result = await gatewayTurn(
|
|
996
|
+
deps.settings.home,
|
|
997
|
+
async () => ({ value: await fn() }),
|
|
998
|
+
gatewayWaiting(deps)
|
|
999
|
+
);
|
|
1000
|
+
return result.value;
|
|
1001
|
+
}
|
|
1002
|
+
function gatewayWaiting(deps) {
|
|
1003
|
+
return {
|
|
1004
|
+
...waiting(deps),
|
|
1005
|
+
onWait: (ms) => say(
|
|
1006
|
+
deps,
|
|
1007
|
+
styleText(
|
|
1008
|
+
` Waiting ${minutes(ms)} after the last payment, so Patron can't link the two.`,
|
|
1009
|
+
"dim",
|
|
1010
|
+
deps.color
|
|
1011
|
+
)
|
|
1012
|
+
)
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
async function currentIssuer(deps, settings) {
|
|
1016
|
+
const stored = await storedIssuer(settings.home, settings.gatewayUrl);
|
|
1017
|
+
if (stored && !stored.stale) return stored.issuer;
|
|
1018
|
+
return inGatewayTurn(
|
|
1019
|
+
deps,
|
|
1020
|
+
() => loadIssuer(settings.home, settings.gatewayUrl, { fetch: deps.fetch, fresh: true })
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
async function standingFor(deps, settings, config) {
|
|
1024
|
+
const address = config.address.toLowerCase();
|
|
1025
|
+
if (!address) return {};
|
|
1026
|
+
const path = statePaths(settings.home).standing;
|
|
1027
|
+
const fetched = await gatewayTurn(
|
|
1028
|
+
settings.home,
|
|
1029
|
+
async () => ({
|
|
1030
|
+
standing: await fetchStanding(
|
|
1031
|
+
settings.gatewayUrl,
|
|
1032
|
+
address,
|
|
1033
|
+
config.name,
|
|
1034
|
+
deps.fetch
|
|
1035
|
+
).catch(() => void 0)
|
|
1036
|
+
}),
|
|
1037
|
+
{ maxWaitMs: 0, want: false }
|
|
1038
|
+
).catch(() => void 0);
|
|
1039
|
+
if (fetched) {
|
|
1040
|
+
if (fetched.standing)
|
|
1041
|
+
await writePrivateFile(
|
|
1042
|
+
path,
|
|
1043
|
+
JSON.stringify({
|
|
1044
|
+
address,
|
|
1045
|
+
gatewayUrl: settings.gatewayUrl,
|
|
1046
|
+
standing: fetched.standing
|
|
1047
|
+
})
|
|
1048
|
+
).catch(() => void 0);
|
|
1049
|
+
return { standing: fetched.standing };
|
|
1050
|
+
}
|
|
1051
|
+
const cached = await readJson(path).catch(() => void 0);
|
|
1052
|
+
const last = cached?.address === address && cached.gatewayUrl === settings.gatewayUrl ? cached.standing : void 0;
|
|
1053
|
+
return { skipped: true, standing: last };
|
|
1054
|
+
}
|
|
1055
|
+
function waiting(deps) {
|
|
1056
|
+
return deps.sleep ? { sleep: deps.sleep } : {};
|
|
1057
|
+
}
|
|
1058
|
+
function minutes(ms) {
|
|
1059
|
+
const count = Math.max(1, Math.ceil(ms / 6e4));
|
|
1060
|
+
return count === 1 ? "about a minute" : `about ${count} minutes`;
|
|
1061
|
+
}
|
|
928
1062
|
function defaults() {
|
|
929
1063
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
930
1064
|
const color = supportsColor(process.stdout);
|
|
@@ -936,7 +1070,7 @@ function defaults() {
|
|
|
936
1070
|
prompter: () => createPrompter(process.stdout, color),
|
|
937
1071
|
settings: resolveSettings(),
|
|
938
1072
|
stderr: process.stderr,
|
|
939
|
-
startRefill: () => startRefill(),
|
|
1073
|
+
startRefill: (options) => startRefill(options),
|
|
940
1074
|
stdout: process.stdout
|
|
941
1075
|
};
|
|
942
1076
|
}
|
|
@@ -1086,10 +1220,13 @@ async function setup(deps) {
|
|
|
1086
1220
|
const settings = deps.settings;
|
|
1087
1221
|
say(deps, scrollBanner(VERSION, deps.color));
|
|
1088
1222
|
say(deps);
|
|
1089
|
-
const issuer = await
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1223
|
+
const issuer = await inGatewayTurn(
|
|
1224
|
+
deps,
|
|
1225
|
+
() => loadIssuer(settings.home, settings.gatewayUrl, {
|
|
1226
|
+
fetch: deps.fetch,
|
|
1227
|
+
fresh: true
|
|
1228
|
+
})
|
|
1229
|
+
).catch((error) => {
|
|
1093
1230
|
throw new Error(`Cannot reach Patron at ${settings.gatewayUrl}: ${error.message}`);
|
|
1094
1231
|
});
|
|
1095
1232
|
const budget = await askBudget(deps, DEFAULT_MONTHLY_BUDGET_USD);
|
|
@@ -1114,7 +1251,10 @@ async function setup(deps) {
|
|
|
1114
1251
|
const starter = config.wallet === "link" ? PACK_SIZE : STARTER_TOKENS;
|
|
1115
1252
|
const first = purchasableTokens(config, await readUsage(settings.home), starter);
|
|
1116
1253
|
step(deps, `Adding ${tokensUsd(first)} to your balance`);
|
|
1117
|
-
const bought = await
|
|
1254
|
+
const bought = await inGatewayTurn(
|
|
1255
|
+
deps,
|
|
1256
|
+
() => buyWithinBudget(settings, config, starter, deps.openWallet)
|
|
1257
|
+
);
|
|
1118
1258
|
done(deps, `${tokensUsd(bought)} ready to pay sites`);
|
|
1119
1259
|
deps.startRefill();
|
|
1120
1260
|
await installStableCli(settings.home).catch(() => void 0);
|
|
@@ -1163,7 +1303,7 @@ async function tempoSignIn(deps, budgetUnits, issuer) {
|
|
|
1163
1303
|
deps,
|
|
1164
1304
|
deps.settings.privateKey ? "Using PATRON_PRIVATE_KEY" : "Signing in with Tempo Wallet"
|
|
1165
1305
|
);
|
|
1166
|
-
const { signIn } = await import("./wallet-
|
|
1306
|
+
const { signIn } = await import("./wallet-WR6EBMN6.js");
|
|
1167
1307
|
const account = await signIn(deps.settings, {
|
|
1168
1308
|
budgetUnits,
|
|
1169
1309
|
issuer,
|
|
@@ -1221,18 +1361,23 @@ async function askBudget(deps, fallback) {
|
|
|
1221
1361
|
}
|
|
1222
1362
|
async function status(deps, menu) {
|
|
1223
1363
|
const { config, settings } = await loadSetup(deps);
|
|
1224
|
-
const [tokensLeft, usage,
|
|
1364
|
+
const [tokensLeft, usage, rank, refillFailedAt] = await Promise.all([
|
|
1225
1365
|
new FileTokenStore(settings.home).count(),
|
|
1226
1366
|
readUsage(settings.home),
|
|
1227
|
-
|
|
1228
|
-
() => void 0
|
|
1229
|
-
) : void 0,
|
|
1367
|
+
standingFor(deps, settings, config),
|
|
1230
1368
|
config.wallet === "link" ? linkRefillFailedAt(settings.home) : void 0
|
|
1231
1369
|
]);
|
|
1232
1370
|
say(
|
|
1233
1371
|
deps,
|
|
1234
1372
|
formatStatus(
|
|
1235
|
-
{
|
|
1373
|
+
{
|
|
1374
|
+
config,
|
|
1375
|
+
linkRefillFailedAt: refillFailedAt,
|
|
1376
|
+
standing: rank.standing,
|
|
1377
|
+
...rank.skipped ? { standingSkipped: true } : {},
|
|
1378
|
+
tokensLeft,
|
|
1379
|
+
usage
|
|
1380
|
+
},
|
|
1236
1381
|
deps.color
|
|
1237
1382
|
)
|
|
1238
1383
|
);
|
|
@@ -1277,10 +1422,8 @@ async function changeBudget(deps, input) {
|
|
|
1277
1422
|
} else budget = await askBudget(deps, config.monthlyBudgetUsd);
|
|
1278
1423
|
if (config.wallet === "tempo" && budget >= config.monthlyBudgetUsd) {
|
|
1279
1424
|
step(deps, "Approve the new spending limit in Tempo Wallet");
|
|
1280
|
-
const { authorizeBudget } = await import("./wallet-
|
|
1281
|
-
const issuer = await
|
|
1282
|
-
fetch: deps.fetch
|
|
1283
|
-
});
|
|
1425
|
+
const { authorizeBudget } = await import("./wallet-WR6EBMN6.js");
|
|
1426
|
+
const issuer = await currentIssuer(deps, settings);
|
|
1284
1427
|
await authorizeBudget(settings, {
|
|
1285
1428
|
budgetUnits: BigInt(budgetTokens(budget)) * TOKEN_PRICE_UNITS,
|
|
1286
1429
|
issuer,
|
|
@@ -1333,11 +1476,37 @@ async function tip(deps, url, amount = "0.10") {
|
|
|
1333
1476
|
);
|
|
1334
1477
|
const amount2 = Math.max(missing, purchasableTokens(config, usage, PACK_SIZE));
|
|
1335
1478
|
step(deps, `Adding ${tokensUsd(amount2)} to your balance`);
|
|
1336
|
-
await
|
|
1479
|
+
await inGatewayTurn(
|
|
1480
|
+
deps,
|
|
1481
|
+
() => buyWithinBudget(settings, config, amount2, deps.openWallet)
|
|
1482
|
+
);
|
|
1337
1483
|
}
|
|
1338
|
-
const
|
|
1339
|
-
|
|
1484
|
+
const stored = await storedIssuer(settings.home, settings.gatewayUrl);
|
|
1485
|
+
let issuer = stored?.issuer ?? await inGatewayTurn(
|
|
1486
|
+
deps,
|
|
1487
|
+
() => loadIssuer(settings.home, settings.gatewayUrl, { fetch: deps.fetch, fresh: true })
|
|
1488
|
+
);
|
|
1489
|
+
let stale = stored?.stale ?? false;
|
|
1490
|
+
let refreshed = false;
|
|
1491
|
+
const redeemFetch = (input, init) => deps.fetch(input, { ...init, signal: AbortSignal.timeout(TIP_REDEEM_TIMEOUT_MS) });
|
|
1492
|
+
let told = false;
|
|
1493
|
+
const claimBatch = (cancelled) => awaitRedemptions(settings.home, TIP_BATCH_LEASE_MS, {
|
|
1494
|
+
...waiting(deps),
|
|
1495
|
+
...cancelled ? { cancelled } : {},
|
|
1496
|
+
onWait: (ms) => {
|
|
1497
|
+
if (told) return;
|
|
1498
|
+
told = true;
|
|
1499
|
+
say(
|
|
1500
|
+
deps,
|
|
1501
|
+
styleText(
|
|
1502
|
+
` Waiting ${minutes(ms)} after a recent purchase, so Patron can't link it to this tip. Ctrl-C keeps your balance.`,
|
|
1503
|
+
"dim",
|
|
1504
|
+
deps.color
|
|
1505
|
+
)
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1340
1508
|
});
|
|
1509
|
+
await claimBatch();
|
|
1341
1510
|
let stopped = false;
|
|
1342
1511
|
const stop = () => {
|
|
1343
1512
|
stopped = true;
|
|
@@ -1349,8 +1518,11 @@ async function tip(deps, url, amount = "0.10") {
|
|
|
1349
1518
|
let paid = 0;
|
|
1350
1519
|
let sent = 0;
|
|
1351
1520
|
let rejection;
|
|
1521
|
+
let claimed = true;
|
|
1352
1522
|
try {
|
|
1353
1523
|
while (sent < count && !stopped) {
|
|
1524
|
+
if (!claimed && !await claimBatch(() => stopped)) break;
|
|
1525
|
+
claimed = false;
|
|
1354
1526
|
const batch = await store.takeMany(Math.min(TIP_BATCH, count - sent));
|
|
1355
1527
|
if (batch.length === 0) break;
|
|
1356
1528
|
sent += batch.length;
|
|
@@ -1360,7 +1532,7 @@ async function tip(deps, url, amount = "0.10") {
|
|
|
1360
1532
|
batch.map(
|
|
1361
1533
|
(token) => redeem({
|
|
1362
1534
|
domain,
|
|
1363
|
-
fetch:
|
|
1535
|
+
fetch: redeemFetch,
|
|
1364
1536
|
issuer,
|
|
1365
1537
|
relayUrl: settings.relayUrl,
|
|
1366
1538
|
token
|
|
@@ -1393,12 +1565,31 @@ async function tip(deps, url, amount = "0.10") {
|
|
|
1393
1565
|
deps.color
|
|
1394
1566
|
)
|
|
1395
1567
|
);
|
|
1396
|
-
if (ok === 0 && (rejected > 0 || unsent.length > 0))
|
|
1568
|
+
if (ok === 0 && (rejected > 0 || unsent.length > 0)) {
|
|
1569
|
+
if (rejected === 0 && stale && !refreshed) {
|
|
1570
|
+
refreshed = true;
|
|
1571
|
+
const fresh = await gatewayTurn(
|
|
1572
|
+
settings.home,
|
|
1573
|
+
() => loadIssuer(settings.home, settings.gatewayUrl, {
|
|
1574
|
+
fetch: deps.fetch,
|
|
1575
|
+
fresh: true
|
|
1576
|
+
}),
|
|
1577
|
+
{ ...gatewayWaiting(deps), cancelled: () => stopped }
|
|
1578
|
+
).catch(() => void 0);
|
|
1579
|
+
if (fresh) {
|
|
1580
|
+
issuer = fresh;
|
|
1581
|
+
stale = false;
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
break;
|
|
1586
|
+
}
|
|
1397
1587
|
}
|
|
1398
1588
|
} finally {
|
|
1399
1589
|
process.off("SIGINT", stop);
|
|
1400
1590
|
process.off("SIGTERM", stop);
|
|
1401
1591
|
}
|
|
1592
|
+
if (stale) deps.startRefill({ delayed: true });
|
|
1402
1593
|
if (stopped && sent < count)
|
|
1403
1594
|
throw new Error(
|
|
1404
1595
|
`Tip stopped: tipped ${domain} ${tokensUsd(paid)} of ${tokensUsd(count)}; the rest stays in your balance.`
|
|
@@ -1426,12 +1617,13 @@ async function setName(deps, name) {
|
|
|
1426
1617
|
throw new UsageError(
|
|
1427
1618
|
"Leaderboard names belong to Tempo addresses; Link purchases are not ranked."
|
|
1428
1619
|
);
|
|
1429
|
-
const issuer = await
|
|
1430
|
-
|
|
1431
|
-
});
|
|
1432
|
-
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-LOLL66ID.js")).openWallet(s, c.wallet, i, max));
|
|
1620
|
+
const issuer = await currentIssuer(deps, settings);
|
|
1621
|
+
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-WR6EBMN6.js")).openWallet(s, c.wallet, i, max));
|
|
1433
1622
|
const wallet = await open(settings, config, issuer, 0n);
|
|
1434
|
-
await
|
|
1623
|
+
await inGatewayTurn(
|
|
1624
|
+
deps,
|
|
1625
|
+
() => setProfile(settings.gatewayUrl, wallet, name, deps.fetch)
|
|
1626
|
+
);
|
|
1435
1627
|
await writeConfig(settings.home, { ...config, name });
|
|
1436
1628
|
done(deps, `Leaderboard name set to ${name}.`);
|
|
1437
1629
|
}
|
|
@@ -3,22 +3,22 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
3
3
|
import {
|
|
4
4
|
IssueResponse,
|
|
5
5
|
IssuerInfo,
|
|
6
|
-
RedeemResponse
|
|
7
|
-
|
|
8
|
-
readJson,
|
|
9
|
-
statePaths,
|
|
10
|
-
writePrivateFile
|
|
11
|
-
} from "./chunk-ZOQJ4CZE.js";
|
|
6
|
+
RedeemResponse
|
|
7
|
+
} from "./chunk-GBZCXMDZ.js";
|
|
12
8
|
import {
|
|
13
9
|
ISSUER_NAME,
|
|
14
10
|
MAX_TOKENS_PER_PURCHASE,
|
|
15
11
|
PACK_SIZE,
|
|
16
12
|
TOKEN_PRICE_UNITS,
|
|
17
13
|
TOKEN_TYPE,
|
|
14
|
+
ensureHome,
|
|
18
15
|
fromBase64Url,
|
|
16
|
+
readJson,
|
|
17
|
+
statePaths,
|
|
19
18
|
toBase64Url,
|
|
20
|
-
withLock
|
|
21
|
-
|
|
19
|
+
withLock,
|
|
20
|
+
writePrivateFile
|
|
21
|
+
} from "./chunk-JTPFWITF.js";
|
|
22
22
|
import {
|
|
23
23
|
__commonJS,
|
|
24
24
|
__export,
|