@blockrun/clawrouter 0.12.262 → 0.12.264
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/cli.js +203 -92
- package/dist/index.d.ts +0 -6
- package/dist/index.js +190 -86
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -32632,7 +32632,7 @@ var init_spend_control = __esm({
|
|
|
32632
32632
|
}
|
|
32633
32633
|
}
|
|
32634
32634
|
if (this.limits.hourly !== void 0) {
|
|
32635
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32635
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
32636
32636
|
const remaining = this.limits.hourly - hourlySpent;
|
|
32637
32637
|
if (estimatedCost2 > remaining) {
|
|
32638
32638
|
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
@@ -32647,7 +32647,7 @@ var init_spend_control = __esm({
|
|
|
32647
32647
|
}
|
|
32648
32648
|
}
|
|
32649
32649
|
if (this.limits.daily !== void 0) {
|
|
32650
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32650
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
32651
32651
|
const remaining = this.limits.daily - dailySpent;
|
|
32652
32652
|
if (estimatedCost2 > remaining) {
|
|
32653
32653
|
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
@@ -32744,17 +32744,30 @@ var init_spend_control = __esm({
|
|
|
32744
32744
|
}
|
|
32745
32745
|
}
|
|
32746
32746
|
}
|
|
32747
|
-
|
|
32747
|
+
// `now` is the single clock reading the caller already took to build the
|
|
32748
|
+
// window; it must be passed in, not re-read here. In-flight reservations are
|
|
32749
|
+
// "now" holds, so they count only against a window that reaches the present
|
|
32750
|
+
// (`to >= now`). The bug this guards against: reading the clock a SECOND time
|
|
32751
|
+
// inside this method (the old `to >= this.now()`) could land a millisecond
|
|
32752
|
+
// after the caller's `now`, flip the guard false, and silently drop the
|
|
32753
|
+
// pending total from the hourly/daily check — letting two concurrent payments
|
|
32754
|
+
// both clear the same remaining budget. Threading the caller's `now` keeps the
|
|
32755
|
+
// guard meaningful (a genuinely historical window with `to < now` still
|
|
32756
|
+
// excludes live holds) without a second, racing read. Every existing test
|
|
32757
|
+
// injects a frozen clock (`now: () => clock`), so the two reads always matched
|
|
32758
|
+
// and the sub-ms window went uncaught; see the live-clock test in
|
|
32759
|
+
// spend-control.test.ts.
|
|
32760
|
+
getSpendingInWindow(from15, to, now2) {
|
|
32748
32761
|
const recorded = this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
32749
|
-
return recorded + (to >=
|
|
32762
|
+
return recorded + (to >= now2 ? this.pendingTotal() : 0);
|
|
32750
32763
|
}
|
|
32751
32764
|
getSpending(window2) {
|
|
32752
32765
|
const now2 = this.now();
|
|
32753
32766
|
switch (window2) {
|
|
32754
32767
|
case "hourly":
|
|
32755
|
-
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32768
|
+
return this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
32756
32769
|
case "daily":
|
|
32757
|
-
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32770
|
+
return this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
32758
32771
|
case "session":
|
|
32759
32772
|
return this.sessionSpent + this.pendingTotal();
|
|
32760
32773
|
}
|
|
@@ -32766,8 +32779,8 @@ var init_spend_control = __esm({
|
|
|
32766
32779
|
}
|
|
32767
32780
|
getStatus() {
|
|
32768
32781
|
const now2 = this.now();
|
|
32769
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32770
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32782
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
32783
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
32771
32784
|
return {
|
|
32772
32785
|
limits: cloneLimits(this.limits),
|
|
32773
32786
|
spending: {
|
|
@@ -39920,6 +39933,13 @@ var init_version4 = __esm({
|
|
|
39920
39933
|
import { readdir, unlink } from "fs/promises";
|
|
39921
39934
|
import { join as join5 } from "path";
|
|
39922
39935
|
import { homedir as homedir3 } from "os";
|
|
39936
|
+
function resolveStatsDays(raw) {
|
|
39937
|
+
const parsed = parseInt(raw ?? "", 10);
|
|
39938
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
39939
|
+
return DEFAULT_STATS_DAYS;
|
|
39940
|
+
}
|
|
39941
|
+
return Math.min(parsed, MAX_STATS_DAYS);
|
|
39942
|
+
}
|
|
39923
39943
|
async function parseLogFile(filePath) {
|
|
39924
39944
|
try {
|
|
39925
39945
|
const content = await readTextFile(filePath);
|
|
@@ -40105,7 +40125,8 @@ function formatStatsAscii(stats) {
|
|
|
40105
40125
|
lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
40106
40126
|
return lines.join("\n");
|
|
40107
40127
|
}
|
|
40108
|
-
async function formatRecentLogs(
|
|
40128
|
+
async function formatRecentLogs(requestedDays = 1) {
|
|
40129
|
+
const days = Number.isFinite(requestedDays) && requestedDays > 0 ? Math.floor(requestedDays) : 1;
|
|
40109
40130
|
const logFiles = await getLogFiles();
|
|
40110
40131
|
const filesToRead = logFiles.slice(0, days);
|
|
40111
40132
|
const allEntries = [];
|
|
@@ -40161,13 +40182,15 @@ async function clearStats() {
|
|
|
40161
40182
|
return { deletedFiles: 0 };
|
|
40162
40183
|
}
|
|
40163
40184
|
}
|
|
40164
|
-
var LOG_DIR2;
|
|
40185
|
+
var LOG_DIR2, DEFAULT_STATS_DAYS, MAX_STATS_DAYS;
|
|
40165
40186
|
var init_stats = __esm({
|
|
40166
40187
|
"src/stats.ts"() {
|
|
40167
40188
|
"use strict";
|
|
40168
40189
|
init_fs_read();
|
|
40169
40190
|
init_version4();
|
|
40170
40191
|
LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
|
|
40192
|
+
DEFAULT_STATS_DAYS = 7;
|
|
40193
|
+
MAX_STATS_DAYS = 30;
|
|
40171
40194
|
}
|
|
40172
40195
|
});
|
|
40173
40196
|
|
|
@@ -91086,8 +91109,8 @@ async function startProxy(options) {
|
|
|
91086
91109
|
if (req.url === "/stats" || req.url?.startsWith("/stats?")) {
|
|
91087
91110
|
try {
|
|
91088
91111
|
const url2 = new URL(req.url, "http://localhost");
|
|
91089
|
-
const days =
|
|
91090
|
-
const stats = await getStats(
|
|
91112
|
+
const days = resolveStatsDays(url2.searchParams.get("days"));
|
|
91113
|
+
const stats = await getStats(days);
|
|
91091
91114
|
res.writeHead(200, {
|
|
91092
91115
|
"Content-Type": "application/json",
|
|
91093
91116
|
"Cache-Control": "no-cache"
|
|
@@ -117009,6 +117032,35 @@ var init_client5 = __esm({
|
|
|
117009
117032
|
}
|
|
117010
117033
|
});
|
|
117011
117034
|
|
|
117035
|
+
// src/polymarket/spend-policy.ts
|
|
117036
|
+
function resolveSpendControl(deps) {
|
|
117037
|
+
if (deps?.spendControl) return deps.spendControl;
|
|
117038
|
+
defaultControl ??= new SpendControl();
|
|
117039
|
+
return defaultControl;
|
|
117040
|
+
}
|
|
117041
|
+
function usdToMicros(usd) {
|
|
117042
|
+
return String(Math.ceil(usd * 1e6));
|
|
117043
|
+
}
|
|
117044
|
+
async function signUnderSpendPolicy(deps, quote, action, sign4) {
|
|
117045
|
+
const control = resolveSpendControl(deps);
|
|
117046
|
+
const reservation = assertSpendPolicyAllows(control, quote);
|
|
117047
|
+
try {
|
|
117048
|
+
const signed2 = await sign4();
|
|
117049
|
+
if (reservation !== void 0) control.settleReservation(reservation, { action });
|
|
117050
|
+
return signed2;
|
|
117051
|
+
} catch (err) {
|
|
117052
|
+
if (reservation !== void 0) control.releaseReservation(reservation);
|
|
117053
|
+
throw err;
|
|
117054
|
+
}
|
|
117055
|
+
}
|
|
117056
|
+
var defaultControl;
|
|
117057
|
+
var init_spend_policy = __esm({
|
|
117058
|
+
"src/polymarket/spend-policy.ts"() {
|
|
117059
|
+
"use strict";
|
|
117060
|
+
init_spend_control();
|
|
117061
|
+
}
|
|
117062
|
+
});
|
|
117063
|
+
|
|
117012
117064
|
// src/polymarket/orders.ts
|
|
117013
117065
|
function getSessionLedger() {
|
|
117014
117066
|
return {
|
|
@@ -117077,6 +117129,9 @@ function isCredsMismatchError(err) {
|
|
|
117077
117129
|
return msg.includes("unauthorized") || msg.includes("api key not found") || msg.includes("invalid api key");
|
|
117078
117130
|
}
|
|
117079
117131
|
async function mapClobError(err) {
|
|
117132
|
+
if (err instanceof SpendPolicyError) {
|
|
117133
|
+
return `Refused by spend policy \u2014 nothing was signed. ${err.message} (see ~/.openclaw/blockrun/spending.json)`;
|
|
117134
|
+
}
|
|
117080
117135
|
const e7 = err;
|
|
117081
117136
|
const dataText = e7?.data ? ` \u2014 ${typeof e7.data === "string" ? e7.data : JSON.stringify(e7.data)}` : "";
|
|
117082
117137
|
const message = `${e7?.message ?? String(err)}${dataText}`;
|
|
@@ -117123,7 +117178,7 @@ async function withCredsRetry(fn) {
|
|
|
117123
117178
|
return fn(fresh);
|
|
117124
117179
|
}
|
|
117125
117180
|
}
|
|
117126
|
-
async function executeTrade(input) {
|
|
117181
|
+
async function executeTrade(input, deps) {
|
|
117127
117182
|
const side = input.action === "buy" ? Side.BUY : Side.SELL;
|
|
117128
117183
|
const isLimit = input.price !== void 0;
|
|
117129
117184
|
if (isLimit && input.size === void 0) {
|
|
@@ -117135,6 +117190,18 @@ async function executeTrade(input) {
|
|
|
117135
117190
|
isError: true
|
|
117136
117191
|
};
|
|
117137
117192
|
}
|
|
117193
|
+
if (!isLimit && input.action === "buy" && input.amount_usd !== void 0 && !(Number.isFinite(input.amount_usd) && input.amount_usd > 0)) {
|
|
117194
|
+
return {
|
|
117195
|
+
text: `amount_usd must be a positive dollar amount to spend, got ${input.amount_usd}.`,
|
|
117196
|
+
isError: true
|
|
117197
|
+
};
|
|
117198
|
+
}
|
|
117199
|
+
if (isLimit && input.size !== void 0 && !(Number.isFinite(input.size) && input.size > 0)) {
|
|
117200
|
+
return {
|
|
117201
|
+
text: `size must be a positive number of shares, got ${input.size}.`,
|
|
117202
|
+
isError: true
|
|
117203
|
+
};
|
|
117204
|
+
}
|
|
117138
117205
|
if (!isLimit && input.action === "sell" && input.size === void 0) {
|
|
117139
117206
|
return { text: `Market sells need size (shares to sell).`, isError: true };
|
|
117140
117207
|
}
|
|
@@ -117234,39 +117301,44 @@ Re-call with confirm:true to sign and submit.`,
|
|
|
117234
117301
|
}
|
|
117235
117302
|
const options = { tickSize, negRisk };
|
|
117236
117303
|
reserveBet(notional, input.agent_id);
|
|
117237
|
-
|
|
117304
|
+
const policyQuote = {
|
|
117305
|
+
payTo: negRisk ? NEG_RISK_CTF_EXCHANGE_V2 : CTF_EXCHANGE_V2,
|
|
117306
|
+
network: `eip155:${POLYGON_CHAIN_ID}`,
|
|
117307
|
+
asset: PUSD_COLLATERAL,
|
|
117308
|
+
amount: usdToMicros(notional)
|
|
117309
|
+
};
|
|
117310
|
+
let r2;
|
|
117238
117311
|
try {
|
|
117239
|
-
|
|
117240
|
-
|
|
117241
|
-
|
|
117242
|
-
|
|
117243
|
-
|
|
117244
|
-
|
|
117245
|
-
|
|
117246
|
-
|
|
117247
|
-
|
|
117248
|
-
|
|
117249
|
-
|
|
117250
|
-
|
|
117251
|
-
|
|
117252
|
-
|
|
117253
|
-
|
|
117254
|
-
|
|
117255
|
-
|
|
117256
|
-
|
|
117257
|
-
|
|
117258
|
-
|
|
117259
|
-
|
|
117312
|
+
r2 = await signUnderSpendPolicy(deps, policyQuote, "polymarket order", async () => {
|
|
117313
|
+
const res = await (isLimit ? clob.createAndPostOrder(
|
|
117314
|
+
{
|
|
117315
|
+
tokenID: token.tokenId,
|
|
117316
|
+
price,
|
|
117317
|
+
size: size5,
|
|
117318
|
+
side,
|
|
117319
|
+
...orderKind === "GTD" && input.expires_at ? { expiration: input.expires_at } : {}
|
|
117320
|
+
},
|
|
117321
|
+
options,
|
|
117322
|
+
orderKind === "GTD" ? OrderType.GTD : OrderType.GTC,
|
|
117323
|
+
input.post_only ?? false
|
|
117324
|
+
) : clob.createAndPostMarketOrder(
|
|
117325
|
+
{
|
|
117326
|
+
tokenID: token.tokenId,
|
|
117327
|
+
amount: input.action === "buy" ? input.amount_usd : size5,
|
|
117328
|
+
side,
|
|
117329
|
+
orderType: orderKind === "FAK" ? OrderType.FAK : OrderType.FOK
|
|
117330
|
+
},
|
|
117331
|
+
options,
|
|
117332
|
+
orderKind === "FAK" ? OrderType.FAK : OrderType.FOK
|
|
117333
|
+
));
|
|
117334
|
+
const placed = res?.success !== false && (res?.orderID || res?.status === "matched");
|
|
117335
|
+
if (!placed) throw new Error(res?.errorMsg || "order rejected");
|
|
117336
|
+
return res;
|
|
117337
|
+
});
|
|
117260
117338
|
} catch (submitErr) {
|
|
117261
117339
|
releaseBet(notional, input.agent_id);
|
|
117262
117340
|
throw submitErr;
|
|
117263
117341
|
}
|
|
117264
|
-
const r2 = response;
|
|
117265
|
-
const placed = r2?.success !== false && (r2?.orderID || r2?.status === "matched");
|
|
117266
|
-
if (!placed) {
|
|
117267
|
-
releaseBet(notional, input.agent_id);
|
|
117268
|
-
throw new Error(r2?.errorMsg || "order rejected");
|
|
117269
|
-
}
|
|
117270
117342
|
commitBet();
|
|
117271
117343
|
const filled = r2?.status === "matched" || (r2?.transactionsHashes?.length ?? 0) > 0;
|
|
117272
117344
|
return {
|
|
@@ -117355,6 +117427,8 @@ var init_orders = __esm({
|
|
|
117355
117427
|
init_client5();
|
|
117356
117428
|
init_constants3();
|
|
117357
117429
|
init_creds();
|
|
117430
|
+
init_spend_control();
|
|
117431
|
+
init_spend_policy();
|
|
117358
117432
|
ledger = {
|
|
117359
117433
|
totalUsd: 0,
|
|
117360
117434
|
count: 0,
|
|
@@ -225289,7 +225363,7 @@ var init_setup = __esm({
|
|
|
225289
225363
|
});
|
|
225290
225364
|
|
|
225291
225365
|
// src/polymarket/redeem.ts
|
|
225292
|
-
async function redeemPosition(input) {
|
|
225366
|
+
async function redeemPosition(input, deps) {
|
|
225293
225367
|
if (!input.condition_id) {
|
|
225294
225368
|
return {
|
|
225295
225369
|
text: `Pass condition_id:"0x\u2026" (see action:"positions" for redeemable markets).`,
|
|
@@ -225365,20 +225439,31 @@ async function redeemPosition(input) {
|
|
|
225365
225439
|
]
|
|
225366
225440
|
});
|
|
225367
225441
|
const target = negRisk ? NEG_RISK_ADAPTER : CONDITIONAL_TOKENS;
|
|
225368
|
-
|
|
225369
|
-
|
|
225370
|
-
|
|
225371
|
-
|
|
225372
|
-
|
|
225373
|
-
|
|
225374
|
-
|
|
225375
|
-
|
|
225376
|
-
|
|
225377
|
-
|
|
225378
|
-
|
|
225379
|
-
|
|
225380
|
-
|
|
225381
|
-
|
|
225442
|
+
const eoa = getSigType() !== 3;
|
|
225443
|
+
const txHash = await signUnderSpendPolicy(
|
|
225444
|
+
deps,
|
|
225445
|
+
{
|
|
225446
|
+
payTo: target,
|
|
225447
|
+
network: `eip155:${POLYGON_CHAIN_ID}`,
|
|
225448
|
+
asset: PUSD_COLLATERAL,
|
|
225449
|
+
amount: "0"
|
|
225450
|
+
},
|
|
225451
|
+
"polymarket redeem",
|
|
225452
|
+
async () => {
|
|
225453
|
+
if (!eoa) {
|
|
225454
|
+
const res = await sendWalletBatch([{ target, value: "0", data }], owner, "Redeem");
|
|
225455
|
+
return res.transactionHash;
|
|
225456
|
+
}
|
|
225457
|
+
const account = getPolymarketAccount();
|
|
225458
|
+
const wallet = createWalletClient({
|
|
225459
|
+
account,
|
|
225460
|
+
chain: polygon,
|
|
225461
|
+
transport: http(POLYGON_RPC_URLS[0])
|
|
225462
|
+
});
|
|
225463
|
+
return wallet.sendTransaction({ to: target, data, chain: polygon, account });
|
|
225464
|
+
}
|
|
225465
|
+
);
|
|
225466
|
+
if (eoa) await pc.waitForTransactionReceipt({ hash: txHash });
|
|
225382
225467
|
const balanceAfter = await getPusdBalance(owner).catch(() => null);
|
|
225383
225468
|
return {
|
|
225384
225469
|
text: [
|
|
@@ -225409,6 +225494,7 @@ var init_redeem = __esm({
|
|
|
225409
225494
|
init_positions();
|
|
225410
225495
|
init_relayer();
|
|
225411
225496
|
init_setup();
|
|
225497
|
+
init_spend_policy();
|
|
225412
225498
|
}
|
|
225413
225499
|
});
|
|
225414
225500
|
|
|
@@ -225421,7 +225507,13 @@ async function rawPusdBalance(owner) {
|
|
|
225421
225507
|
args: [owner]
|
|
225422
225508
|
});
|
|
225423
225509
|
}
|
|
225424
|
-
async function withdrawFunds(input) {
|
|
225510
|
+
async function withdrawFunds(input, deps) {
|
|
225511
|
+
if (input.amount_usd !== void 0 && !(Number.isFinite(input.amount_usd) && input.amount_usd > 0)) {
|
|
225512
|
+
return {
|
|
225513
|
+
text: `amount_usd must be a positive dollar amount, got ${input.amount_usd}. Omit it to withdraw the full balance.`,
|
|
225514
|
+
isError: true
|
|
225515
|
+
};
|
|
225516
|
+
}
|
|
225425
225517
|
let owner;
|
|
225426
225518
|
try {
|
|
225427
225519
|
owner = getFundsAddress();
|
|
@@ -225492,29 +225584,40 @@ async function withdrawFunds(input) {
|
|
|
225492
225584
|
functionName: "transfer",
|
|
225493
225585
|
args: [bridgeEvm, amountRaw]
|
|
225494
225586
|
});
|
|
225495
|
-
|
|
225496
|
-
|
|
225497
|
-
|
|
225498
|
-
|
|
225499
|
-
|
|
225500
|
-
|
|
225501
|
-
|
|
225502
|
-
|
|
225503
|
-
|
|
225504
|
-
|
|
225505
|
-
|
|
225506
|
-
|
|
225507
|
-
|
|
225508
|
-
|
|
225509
|
-
|
|
225510
|
-
|
|
225511
|
-
|
|
225512
|
-
|
|
225513
|
-
|
|
225514
|
-
account
|
|
225515
|
-
|
|
225516
|
-
|
|
225517
|
-
|
|
225587
|
+
const eoa = getSigType() !== 3;
|
|
225588
|
+
const txHash = await signUnderSpendPolicy(
|
|
225589
|
+
deps,
|
|
225590
|
+
{
|
|
225591
|
+
payTo: recipient,
|
|
225592
|
+
network: `eip155:${BASE_CHAIN_ID}`,
|
|
225593
|
+
asset: BASE_USDC,
|
|
225594
|
+
amount: amountRaw.toString()
|
|
225595
|
+
},
|
|
225596
|
+
"polymarket withdraw",
|
|
225597
|
+
async () => {
|
|
225598
|
+
if (!eoa) {
|
|
225599
|
+
const res = await sendWalletBatch(
|
|
225600
|
+
[{ target: PUSD_COLLATERAL, value: "0", data }],
|
|
225601
|
+
owner,
|
|
225602
|
+
"Withdraw"
|
|
225603
|
+
);
|
|
225604
|
+
return res.transactionHash;
|
|
225605
|
+
}
|
|
225606
|
+
const account = getPolymarketAccount();
|
|
225607
|
+
const wallet = createWalletClient({
|
|
225608
|
+
account,
|
|
225609
|
+
chain: polygon,
|
|
225610
|
+
transport: http(POLYGON_RPC_URLS[0])
|
|
225611
|
+
});
|
|
225612
|
+
return wallet.sendTransaction({
|
|
225613
|
+
to: PUSD_COLLATERAL,
|
|
225614
|
+
data,
|
|
225615
|
+
chain: polygon,
|
|
225616
|
+
account
|
|
225617
|
+
});
|
|
225618
|
+
}
|
|
225619
|
+
);
|
|
225620
|
+
if (eoa) await getPublicClient().waitForTransactionReceipt({ hash: txHash });
|
|
225518
225621
|
return {
|
|
225519
225622
|
text: [
|
|
225520
225623
|
`\u2705 Withdrawal submitted: $${amountUsd.toFixed(2)} pUSD \u2192 USDC on Base`,
|
|
@@ -225549,6 +225652,7 @@ var init_withdraw = __esm({
|
|
|
225549
225652
|
init_positions();
|
|
225550
225653
|
init_relayer();
|
|
225551
225654
|
init_setup();
|
|
225655
|
+
init_spend_policy();
|
|
225552
225656
|
}
|
|
225553
225657
|
});
|
|
225554
225658
|
|
|
@@ -226194,7 +226298,7 @@ async function bridgeAddressFor(vault) {
|
|
|
226194
226298
|
throw new Error(`Bridge did not return a deposit address (got: ${JSON.stringify(res.data)}).`);
|
|
226195
226299
|
return evm;
|
|
226196
226300
|
}
|
|
226197
|
-
async function fundVault(input) {
|
|
226301
|
+
async function fundVault(input, deps) {
|
|
226198
226302
|
if (input.amount_usd === void 0 || input.amount_usd <= 0) {
|
|
226199
226303
|
return {
|
|
226200
226304
|
text: `Pass amount_usd \u2014 the USDC amount to move from your Base wallet into your Polymarket vault (e.g. amount_usd:5).`,
|
|
@@ -226251,12 +226355,12 @@ async function fundVault(input) {
|
|
|
226251
226355
|
}
|
|
226252
226356
|
const privateKey = getOrCreateWalletKey();
|
|
226253
226357
|
const amountMicro = String(Math.floor(amountUsd * 10 ** USDC_DECIMALS));
|
|
226254
|
-
const
|
|
226255
|
-
|
|
226256
|
-
|
|
226257
|
-
bridge,
|
|
226258
|
-
|
|
226259
|
-
|
|
226358
|
+
const network = `eip155:${BASE_CHAIN_ID}`;
|
|
226359
|
+
const depositAuthorization = await signUnderSpendPolicy(
|
|
226360
|
+
deps,
|
|
226361
|
+
{ payTo: bridge, network, asset: BASE_USDC, amount: amountMicro },
|
|
226362
|
+
"polymarket fund",
|
|
226363
|
+
() => createPaymentPayload(privateKey, agent, bridge, amountMicro, network)
|
|
226260
226364
|
);
|
|
226261
226365
|
const client = new BlockrunClient({ privateKey });
|
|
226262
226366
|
const result = await client.post("/v1/polymarket/fund", {
|
|
@@ -226306,6 +226410,7 @@ var init_fund = __esm({
|
|
|
226306
226410
|
init_constants3();
|
|
226307
226411
|
init_positions();
|
|
226308
226412
|
init_setup();
|
|
226413
|
+
init_spend_policy();
|
|
226309
226414
|
FUND_FEE_USD = 0.01;
|
|
226310
226415
|
USDC_DECIMALS = 6;
|
|
226311
226416
|
FUND_MIN_USD = Number(process.env.POLYMARKET_FUND_MIN_USD || "2");
|
|
@@ -228605,6 +228710,7 @@ init_balance();
|
|
|
228605
228710
|
init_wallet2();
|
|
228606
228711
|
init_stats();
|
|
228607
228712
|
init_proxy();
|
|
228713
|
+
init_spend_control();
|
|
228608
228714
|
init_version4();
|
|
228609
228715
|
import { platform, arch, freemem, totalmem } from "os";
|
|
228610
228716
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
@@ -228871,6 +228977,15 @@ var DOCTOR_MODELS = {
|
|
|
228871
228977
|
cost: "~$0.01"
|
|
228872
228978
|
}
|
|
228873
228979
|
};
|
|
228980
|
+
function createDoctorX402Client(opts) {
|
|
228981
|
+
const account = privateKeyToAccount(opts.walletKey);
|
|
228982
|
+
const publicClient = createPublicClient({ chain: base, transport: http() });
|
|
228983
|
+
const evmSigner = toClientEvmSigner(account, publicClient);
|
|
228984
|
+
const x402 = new x402Client();
|
|
228985
|
+
registerSpendPolicyHook(x402, opts.spendControl ?? new SpendControl());
|
|
228986
|
+
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
228987
|
+
return x402;
|
|
228988
|
+
}
|
|
228874
228989
|
async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
|
|
228875
228990
|
if (diagnostics.wallet.isEmpty) {
|
|
228876
228991
|
console.log("\n\u{1F4B3} Wallet is empty - cannot call AI for analysis.");
|
|
@@ -228888,11 +229003,7 @@ async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
|
|
|
228888
229003
|
`);
|
|
228889
229004
|
try {
|
|
228890
229005
|
const { key: key2 } = await resolveOrGenerateWalletKey();
|
|
228891
|
-
const
|
|
228892
|
-
const publicClient = createPublicClient({ chain: base, transport: http() });
|
|
228893
|
-
const evmSigner = toClientEvmSigner(account, publicClient);
|
|
228894
|
-
const x402 = new x402Client();
|
|
228895
|
-
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
229006
|
+
const x402 = createDoctorX402Client({ walletKey: key2 });
|
|
228896
229007
|
const paymentChain = diagnostics.wallet.paymentChain;
|
|
228897
229008
|
if (paymentChain === "solana") {
|
|
228898
229009
|
try {
|
package/dist/index.d.ts
CHANGED
|
@@ -1467,12 +1467,6 @@ declare function fetchWithRetry(fetchFn: (url: string, init?: RequestInit) => Pr
|
|
|
1467
1467
|
*/
|
|
1468
1468
|
declare function isRetryable(errorOrResponse: Error | Response, config?: Partial<RetryConfig>): boolean;
|
|
1469
1469
|
|
|
1470
|
-
/**
|
|
1471
|
-
* Usage Statistics Aggregator
|
|
1472
|
-
*
|
|
1473
|
-
* Reads usage log files and aggregates statistics for terminal display.
|
|
1474
|
-
* Supports filtering by date range and provides multiple aggregation views.
|
|
1475
|
-
*/
|
|
1476
1470
|
type DailyStats = {
|
|
1477
1471
|
date: string;
|
|
1478
1472
|
totalRequests: number;
|
package/dist/index.js
CHANGED
|
@@ -34768,7 +34768,7 @@ var init_spend_control = __esm({
|
|
|
34768
34768
|
}
|
|
34769
34769
|
}
|
|
34770
34770
|
if (this.limits.hourly !== void 0) {
|
|
34771
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34771
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
34772
34772
|
const remaining = this.limits.hourly - hourlySpent;
|
|
34773
34773
|
if (estimatedCost2 > remaining) {
|
|
34774
34774
|
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
@@ -34783,7 +34783,7 @@ var init_spend_control = __esm({
|
|
|
34783
34783
|
}
|
|
34784
34784
|
}
|
|
34785
34785
|
if (this.limits.daily !== void 0) {
|
|
34786
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34786
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
34787
34787
|
const remaining = this.limits.daily - dailySpent;
|
|
34788
34788
|
if (estimatedCost2 > remaining) {
|
|
34789
34789
|
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
@@ -34880,17 +34880,30 @@ var init_spend_control = __esm({
|
|
|
34880
34880
|
}
|
|
34881
34881
|
}
|
|
34882
34882
|
}
|
|
34883
|
-
|
|
34883
|
+
// `now` is the single clock reading the caller already took to build the
|
|
34884
|
+
// window; it must be passed in, not re-read here. In-flight reservations are
|
|
34885
|
+
// "now" holds, so they count only against a window that reaches the present
|
|
34886
|
+
// (`to >= now`). The bug this guards against: reading the clock a SECOND time
|
|
34887
|
+
// inside this method (the old `to >= this.now()`) could land a millisecond
|
|
34888
|
+
// after the caller's `now`, flip the guard false, and silently drop the
|
|
34889
|
+
// pending total from the hourly/daily check — letting two concurrent payments
|
|
34890
|
+
// both clear the same remaining budget. Threading the caller's `now` keeps the
|
|
34891
|
+
// guard meaningful (a genuinely historical window with `to < now` still
|
|
34892
|
+
// excludes live holds) without a second, racing read. Every existing test
|
|
34893
|
+
// injects a frozen clock (`now: () => clock`), so the two reads always matched
|
|
34894
|
+
// and the sub-ms window went uncaught; see the live-clock test in
|
|
34895
|
+
// spend-control.test.ts.
|
|
34896
|
+
getSpendingInWindow(from15, to, now2) {
|
|
34884
34897
|
const recorded = this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
34885
|
-
return recorded + (to >=
|
|
34898
|
+
return recorded + (to >= now2 ? this.pendingTotal() : 0);
|
|
34886
34899
|
}
|
|
34887
34900
|
getSpending(window2) {
|
|
34888
34901
|
const now2 = this.now();
|
|
34889
34902
|
switch (window2) {
|
|
34890
34903
|
case "hourly":
|
|
34891
|
-
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34904
|
+
return this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
34892
34905
|
case "daily":
|
|
34893
|
-
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34906
|
+
return this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
34894
34907
|
case "session":
|
|
34895
34908
|
return this.sessionSpent + this.pendingTotal();
|
|
34896
34909
|
}
|
|
@@ -34902,8 +34915,8 @@ var init_spend_control = __esm({
|
|
|
34902
34915
|
}
|
|
34903
34916
|
getStatus() {
|
|
34904
34917
|
const now2 = this.now();
|
|
34905
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34906
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34918
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2, now2);
|
|
34919
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2, now2);
|
|
34907
34920
|
return {
|
|
34908
34921
|
limits: cloneLimits(this.limits),
|
|
34909
34922
|
spending: {
|
|
@@ -39835,6 +39848,13 @@ var init_version4 = __esm({
|
|
|
39835
39848
|
import { readdir, unlink } from "fs/promises";
|
|
39836
39849
|
import { join as join5 } from "path";
|
|
39837
39850
|
import { homedir as homedir3 } from "os";
|
|
39851
|
+
function resolveStatsDays(raw) {
|
|
39852
|
+
const parsed = parseInt(raw ?? "", 10);
|
|
39853
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
39854
|
+
return DEFAULT_STATS_DAYS;
|
|
39855
|
+
}
|
|
39856
|
+
return Math.min(parsed, MAX_STATS_DAYS);
|
|
39857
|
+
}
|
|
39838
39858
|
async function parseLogFile(filePath) {
|
|
39839
39859
|
try {
|
|
39840
39860
|
const content = await readTextFile(filePath);
|
|
@@ -40030,13 +40050,15 @@ async function clearStats() {
|
|
|
40030
40050
|
return { deletedFiles: 0 };
|
|
40031
40051
|
}
|
|
40032
40052
|
}
|
|
40033
|
-
var LOG_DIR2;
|
|
40053
|
+
var LOG_DIR2, DEFAULT_STATS_DAYS, MAX_STATS_DAYS;
|
|
40034
40054
|
var init_stats = __esm({
|
|
40035
40055
|
"src/stats.ts"() {
|
|
40036
40056
|
"use strict";
|
|
40037
40057
|
init_fs_read();
|
|
40038
40058
|
init_version4();
|
|
40039
40059
|
LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
|
|
40060
|
+
DEFAULT_STATS_DAYS = 7;
|
|
40061
|
+
MAX_STATS_DAYS = 30;
|
|
40040
40062
|
}
|
|
40041
40063
|
});
|
|
40042
40064
|
|
|
@@ -90906,8 +90928,8 @@ async function startProxy(options) {
|
|
|
90906
90928
|
if (req.url === "/stats" || req.url?.startsWith("/stats?")) {
|
|
90907
90929
|
try {
|
|
90908
90930
|
const url2 = new URL(req.url, "http://localhost");
|
|
90909
|
-
const days =
|
|
90910
|
-
const stats = await getStats(
|
|
90931
|
+
const days = resolveStatsDays(url2.searchParams.get("days"));
|
|
90932
|
+
const stats = await getStats(days);
|
|
90911
90933
|
res.writeHead(200, {
|
|
90912
90934
|
"Content-Type": "application/json",
|
|
90913
90935
|
"Cache-Control": "no-cache"
|
|
@@ -116829,6 +116851,35 @@ var init_client5 = __esm({
|
|
|
116829
116851
|
}
|
|
116830
116852
|
});
|
|
116831
116853
|
|
|
116854
|
+
// src/polymarket/spend-policy.ts
|
|
116855
|
+
function resolveSpendControl(deps) {
|
|
116856
|
+
if (deps?.spendControl) return deps.spendControl;
|
|
116857
|
+
defaultControl ??= new SpendControl();
|
|
116858
|
+
return defaultControl;
|
|
116859
|
+
}
|
|
116860
|
+
function usdToMicros(usd) {
|
|
116861
|
+
return String(Math.ceil(usd * 1e6));
|
|
116862
|
+
}
|
|
116863
|
+
async function signUnderSpendPolicy(deps, quote, action, sign4) {
|
|
116864
|
+
const control = resolveSpendControl(deps);
|
|
116865
|
+
const reservation = assertSpendPolicyAllows(control, quote);
|
|
116866
|
+
try {
|
|
116867
|
+
const signed2 = await sign4();
|
|
116868
|
+
if (reservation !== void 0) control.settleReservation(reservation, { action });
|
|
116869
|
+
return signed2;
|
|
116870
|
+
} catch (err) {
|
|
116871
|
+
if (reservation !== void 0) control.releaseReservation(reservation);
|
|
116872
|
+
throw err;
|
|
116873
|
+
}
|
|
116874
|
+
}
|
|
116875
|
+
var defaultControl;
|
|
116876
|
+
var init_spend_policy = __esm({
|
|
116877
|
+
"src/polymarket/spend-policy.ts"() {
|
|
116878
|
+
"use strict";
|
|
116879
|
+
init_spend_control();
|
|
116880
|
+
}
|
|
116881
|
+
});
|
|
116882
|
+
|
|
116832
116883
|
// src/polymarket/orders.ts
|
|
116833
116884
|
function getSessionLedger() {
|
|
116834
116885
|
return {
|
|
@@ -116897,6 +116948,9 @@ function isCredsMismatchError(err) {
|
|
|
116897
116948
|
return msg.includes("unauthorized") || msg.includes("api key not found") || msg.includes("invalid api key");
|
|
116898
116949
|
}
|
|
116899
116950
|
async function mapClobError(err) {
|
|
116951
|
+
if (err instanceof SpendPolicyError) {
|
|
116952
|
+
return `Refused by spend policy \u2014 nothing was signed. ${err.message} (see ~/.openclaw/blockrun/spending.json)`;
|
|
116953
|
+
}
|
|
116900
116954
|
const e7 = err;
|
|
116901
116955
|
const dataText = e7?.data ? ` \u2014 ${typeof e7.data === "string" ? e7.data : JSON.stringify(e7.data)}` : "";
|
|
116902
116956
|
const message = `${e7?.message ?? String(err)}${dataText}`;
|
|
@@ -116943,7 +116997,7 @@ async function withCredsRetry(fn) {
|
|
|
116943
116997
|
return fn(fresh);
|
|
116944
116998
|
}
|
|
116945
116999
|
}
|
|
116946
|
-
async function executeTrade(input) {
|
|
117000
|
+
async function executeTrade(input, deps) {
|
|
116947
117001
|
const side = input.action === "buy" ? Side.BUY : Side.SELL;
|
|
116948
117002
|
const isLimit = input.price !== void 0;
|
|
116949
117003
|
if (isLimit && input.size === void 0) {
|
|
@@ -116955,6 +117009,18 @@ async function executeTrade(input) {
|
|
|
116955
117009
|
isError: true
|
|
116956
117010
|
};
|
|
116957
117011
|
}
|
|
117012
|
+
if (!isLimit && input.action === "buy" && input.amount_usd !== void 0 && !(Number.isFinite(input.amount_usd) && input.amount_usd > 0)) {
|
|
117013
|
+
return {
|
|
117014
|
+
text: `amount_usd must be a positive dollar amount to spend, got ${input.amount_usd}.`,
|
|
117015
|
+
isError: true
|
|
117016
|
+
};
|
|
117017
|
+
}
|
|
117018
|
+
if (isLimit && input.size !== void 0 && !(Number.isFinite(input.size) && input.size > 0)) {
|
|
117019
|
+
return {
|
|
117020
|
+
text: `size must be a positive number of shares, got ${input.size}.`,
|
|
117021
|
+
isError: true
|
|
117022
|
+
};
|
|
117023
|
+
}
|
|
116958
117024
|
if (!isLimit && input.action === "sell" && input.size === void 0) {
|
|
116959
117025
|
return { text: `Market sells need size (shares to sell).`, isError: true };
|
|
116960
117026
|
}
|
|
@@ -117054,39 +117120,44 @@ Re-call with confirm:true to sign and submit.`,
|
|
|
117054
117120
|
}
|
|
117055
117121
|
const options = { tickSize, negRisk };
|
|
117056
117122
|
reserveBet(notional, input.agent_id);
|
|
117057
|
-
|
|
117123
|
+
const policyQuote = {
|
|
117124
|
+
payTo: negRisk ? NEG_RISK_CTF_EXCHANGE_V2 : CTF_EXCHANGE_V2,
|
|
117125
|
+
network: `eip155:${POLYGON_CHAIN_ID}`,
|
|
117126
|
+
asset: PUSD_COLLATERAL,
|
|
117127
|
+
amount: usdToMicros(notional)
|
|
117128
|
+
};
|
|
117129
|
+
let r2;
|
|
117058
117130
|
try {
|
|
117059
|
-
|
|
117060
|
-
|
|
117061
|
-
|
|
117062
|
-
|
|
117063
|
-
|
|
117064
|
-
|
|
117065
|
-
|
|
117066
|
-
|
|
117067
|
-
|
|
117068
|
-
|
|
117069
|
-
|
|
117070
|
-
|
|
117071
|
-
|
|
117072
|
-
|
|
117073
|
-
|
|
117074
|
-
|
|
117075
|
-
|
|
117076
|
-
|
|
117077
|
-
|
|
117078
|
-
|
|
117079
|
-
|
|
117131
|
+
r2 = await signUnderSpendPolicy(deps, policyQuote, "polymarket order", async () => {
|
|
117132
|
+
const res = await (isLimit ? clob.createAndPostOrder(
|
|
117133
|
+
{
|
|
117134
|
+
tokenID: token.tokenId,
|
|
117135
|
+
price,
|
|
117136
|
+
size: size5,
|
|
117137
|
+
side,
|
|
117138
|
+
...orderKind === "GTD" && input.expires_at ? { expiration: input.expires_at } : {}
|
|
117139
|
+
},
|
|
117140
|
+
options,
|
|
117141
|
+
orderKind === "GTD" ? OrderType.GTD : OrderType.GTC,
|
|
117142
|
+
input.post_only ?? false
|
|
117143
|
+
) : clob.createAndPostMarketOrder(
|
|
117144
|
+
{
|
|
117145
|
+
tokenID: token.tokenId,
|
|
117146
|
+
amount: input.action === "buy" ? input.amount_usd : size5,
|
|
117147
|
+
side,
|
|
117148
|
+
orderType: orderKind === "FAK" ? OrderType.FAK : OrderType.FOK
|
|
117149
|
+
},
|
|
117150
|
+
options,
|
|
117151
|
+
orderKind === "FAK" ? OrderType.FAK : OrderType.FOK
|
|
117152
|
+
));
|
|
117153
|
+
const placed = res?.success !== false && (res?.orderID || res?.status === "matched");
|
|
117154
|
+
if (!placed) throw new Error(res?.errorMsg || "order rejected");
|
|
117155
|
+
return res;
|
|
117156
|
+
});
|
|
117080
117157
|
} catch (submitErr) {
|
|
117081
117158
|
releaseBet(notional, input.agent_id);
|
|
117082
117159
|
throw submitErr;
|
|
117083
117160
|
}
|
|
117084
|
-
const r2 = response;
|
|
117085
|
-
const placed = r2?.success !== false && (r2?.orderID || r2?.status === "matched");
|
|
117086
|
-
if (!placed) {
|
|
117087
|
-
releaseBet(notional, input.agent_id);
|
|
117088
|
-
throw new Error(r2?.errorMsg || "order rejected");
|
|
117089
|
-
}
|
|
117090
117161
|
commitBet();
|
|
117091
117162
|
const filled = r2?.status === "matched" || (r2?.transactionsHashes?.length ?? 0) > 0;
|
|
117092
117163
|
return {
|
|
@@ -117175,6 +117246,8 @@ var init_orders = __esm({
|
|
|
117175
117246
|
init_client5();
|
|
117176
117247
|
init_constants3();
|
|
117177
117248
|
init_creds();
|
|
117249
|
+
init_spend_control();
|
|
117250
|
+
init_spend_policy();
|
|
117178
117251
|
ledger = {
|
|
117179
117252
|
totalUsd: 0,
|
|
117180
117253
|
count: 0,
|
|
@@ -225109,7 +225182,7 @@ var init_setup = __esm({
|
|
|
225109
225182
|
});
|
|
225110
225183
|
|
|
225111
225184
|
// src/polymarket/redeem.ts
|
|
225112
|
-
async function redeemPosition(input) {
|
|
225185
|
+
async function redeemPosition(input, deps) {
|
|
225113
225186
|
if (!input.condition_id) {
|
|
225114
225187
|
return {
|
|
225115
225188
|
text: `Pass condition_id:"0x\u2026" (see action:"positions" for redeemable markets).`,
|
|
@@ -225185,20 +225258,31 @@ async function redeemPosition(input) {
|
|
|
225185
225258
|
]
|
|
225186
225259
|
});
|
|
225187
225260
|
const target = negRisk ? NEG_RISK_ADAPTER : CONDITIONAL_TOKENS;
|
|
225188
|
-
|
|
225189
|
-
|
|
225190
|
-
|
|
225191
|
-
|
|
225192
|
-
|
|
225193
|
-
|
|
225194
|
-
|
|
225195
|
-
|
|
225196
|
-
|
|
225197
|
-
|
|
225198
|
-
|
|
225199
|
-
|
|
225200
|
-
|
|
225201
|
-
|
|
225261
|
+
const eoa = getSigType() !== 3;
|
|
225262
|
+
const txHash = await signUnderSpendPolicy(
|
|
225263
|
+
deps,
|
|
225264
|
+
{
|
|
225265
|
+
payTo: target,
|
|
225266
|
+
network: `eip155:${POLYGON_CHAIN_ID}`,
|
|
225267
|
+
asset: PUSD_COLLATERAL,
|
|
225268
|
+
amount: "0"
|
|
225269
|
+
},
|
|
225270
|
+
"polymarket redeem",
|
|
225271
|
+
async () => {
|
|
225272
|
+
if (!eoa) {
|
|
225273
|
+
const res = await sendWalletBatch([{ target, value: "0", data }], owner, "Redeem");
|
|
225274
|
+
return res.transactionHash;
|
|
225275
|
+
}
|
|
225276
|
+
const account = getPolymarketAccount();
|
|
225277
|
+
const wallet = createWalletClient({
|
|
225278
|
+
account,
|
|
225279
|
+
chain: polygon,
|
|
225280
|
+
transport: http(POLYGON_RPC_URLS[0])
|
|
225281
|
+
});
|
|
225282
|
+
return wallet.sendTransaction({ to: target, data, chain: polygon, account });
|
|
225283
|
+
}
|
|
225284
|
+
);
|
|
225285
|
+
if (eoa) await pc.waitForTransactionReceipt({ hash: txHash });
|
|
225202
225286
|
const balanceAfter = await getPusdBalance(owner).catch(() => null);
|
|
225203
225287
|
return {
|
|
225204
225288
|
text: [
|
|
@@ -225229,6 +225313,7 @@ var init_redeem = __esm({
|
|
|
225229
225313
|
init_positions();
|
|
225230
225314
|
init_relayer();
|
|
225231
225315
|
init_setup();
|
|
225316
|
+
init_spend_policy();
|
|
225232
225317
|
}
|
|
225233
225318
|
});
|
|
225234
225319
|
|
|
@@ -225241,7 +225326,13 @@ async function rawPusdBalance(owner) {
|
|
|
225241
225326
|
args: [owner]
|
|
225242
225327
|
});
|
|
225243
225328
|
}
|
|
225244
|
-
async function withdrawFunds(input) {
|
|
225329
|
+
async function withdrawFunds(input, deps) {
|
|
225330
|
+
if (input.amount_usd !== void 0 && !(Number.isFinite(input.amount_usd) && input.amount_usd > 0)) {
|
|
225331
|
+
return {
|
|
225332
|
+
text: `amount_usd must be a positive dollar amount, got ${input.amount_usd}. Omit it to withdraw the full balance.`,
|
|
225333
|
+
isError: true
|
|
225334
|
+
};
|
|
225335
|
+
}
|
|
225245
225336
|
let owner;
|
|
225246
225337
|
try {
|
|
225247
225338
|
owner = getFundsAddress();
|
|
@@ -225312,29 +225403,40 @@ async function withdrawFunds(input) {
|
|
|
225312
225403
|
functionName: "transfer",
|
|
225313
225404
|
args: [bridgeEvm, amountRaw]
|
|
225314
225405
|
});
|
|
225315
|
-
|
|
225316
|
-
|
|
225317
|
-
|
|
225318
|
-
|
|
225319
|
-
|
|
225320
|
-
|
|
225321
|
-
|
|
225322
|
-
|
|
225323
|
-
|
|
225324
|
-
|
|
225325
|
-
|
|
225326
|
-
|
|
225327
|
-
|
|
225328
|
-
|
|
225329
|
-
|
|
225330
|
-
|
|
225331
|
-
|
|
225332
|
-
|
|
225333
|
-
|
|
225334
|
-
account
|
|
225335
|
-
|
|
225336
|
-
|
|
225337
|
-
|
|
225406
|
+
const eoa = getSigType() !== 3;
|
|
225407
|
+
const txHash = await signUnderSpendPolicy(
|
|
225408
|
+
deps,
|
|
225409
|
+
{
|
|
225410
|
+
payTo: recipient,
|
|
225411
|
+
network: `eip155:${BASE_CHAIN_ID}`,
|
|
225412
|
+
asset: BASE_USDC,
|
|
225413
|
+
amount: amountRaw.toString()
|
|
225414
|
+
},
|
|
225415
|
+
"polymarket withdraw",
|
|
225416
|
+
async () => {
|
|
225417
|
+
if (!eoa) {
|
|
225418
|
+
const res = await sendWalletBatch(
|
|
225419
|
+
[{ target: PUSD_COLLATERAL, value: "0", data }],
|
|
225420
|
+
owner,
|
|
225421
|
+
"Withdraw"
|
|
225422
|
+
);
|
|
225423
|
+
return res.transactionHash;
|
|
225424
|
+
}
|
|
225425
|
+
const account = getPolymarketAccount();
|
|
225426
|
+
const wallet = createWalletClient({
|
|
225427
|
+
account,
|
|
225428
|
+
chain: polygon,
|
|
225429
|
+
transport: http(POLYGON_RPC_URLS[0])
|
|
225430
|
+
});
|
|
225431
|
+
return wallet.sendTransaction({
|
|
225432
|
+
to: PUSD_COLLATERAL,
|
|
225433
|
+
data,
|
|
225434
|
+
chain: polygon,
|
|
225435
|
+
account
|
|
225436
|
+
});
|
|
225437
|
+
}
|
|
225438
|
+
);
|
|
225439
|
+
if (eoa) await getPublicClient().waitForTransactionReceipt({ hash: txHash });
|
|
225338
225440
|
return {
|
|
225339
225441
|
text: [
|
|
225340
225442
|
`\u2705 Withdrawal submitted: $${amountUsd.toFixed(2)} pUSD \u2192 USDC on Base`,
|
|
@@ -225369,6 +225471,7 @@ var init_withdraw = __esm({
|
|
|
225369
225471
|
init_positions();
|
|
225370
225472
|
init_relayer();
|
|
225371
225473
|
init_setup();
|
|
225474
|
+
init_spend_policy();
|
|
225372
225475
|
}
|
|
225373
225476
|
});
|
|
225374
225477
|
|
|
@@ -226014,7 +226117,7 @@ async function bridgeAddressFor(vault) {
|
|
|
226014
226117
|
throw new Error(`Bridge did not return a deposit address (got: ${JSON.stringify(res.data)}).`);
|
|
226015
226118
|
return evm;
|
|
226016
226119
|
}
|
|
226017
|
-
async function fundVault(input) {
|
|
226120
|
+
async function fundVault(input, deps) {
|
|
226018
226121
|
if (input.amount_usd === void 0 || input.amount_usd <= 0) {
|
|
226019
226122
|
return {
|
|
226020
226123
|
text: `Pass amount_usd \u2014 the USDC amount to move from your Base wallet into your Polymarket vault (e.g. amount_usd:5).`,
|
|
@@ -226071,12 +226174,12 @@ async function fundVault(input) {
|
|
|
226071
226174
|
}
|
|
226072
226175
|
const privateKey = getOrCreateWalletKey();
|
|
226073
226176
|
const amountMicro = String(Math.floor(amountUsd * 10 ** USDC_DECIMALS));
|
|
226074
|
-
const
|
|
226075
|
-
|
|
226076
|
-
|
|
226077
|
-
bridge,
|
|
226078
|
-
|
|
226079
|
-
|
|
226177
|
+
const network = `eip155:${BASE_CHAIN_ID}`;
|
|
226178
|
+
const depositAuthorization = await signUnderSpendPolicy(
|
|
226179
|
+
deps,
|
|
226180
|
+
{ payTo: bridge, network, asset: BASE_USDC, amount: amountMicro },
|
|
226181
|
+
"polymarket fund",
|
|
226182
|
+
() => createPaymentPayload(privateKey, agent, bridge, amountMicro, network)
|
|
226080
226183
|
);
|
|
226081
226184
|
const client = new BlockrunClient({ privateKey });
|
|
226082
226185
|
const result = await client.post("/v1/polymarket/fund", {
|
|
@@ -226126,6 +226229,7 @@ var init_fund = __esm({
|
|
|
226126
226229
|
init_constants3();
|
|
226127
226230
|
init_positions();
|
|
226128
226231
|
init_setup();
|
|
226232
|
+
init_spend_policy();
|
|
226129
226233
|
FUND_FEE_USD = 0.01;
|
|
226130
226234
|
USDC_DECIMALS = 6;
|
|
226131
226235
|
FUND_MIN_USD = Number(process.env.POLYMARKET_FUND_MIN_USD || "2");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockrun/clawrouter",
|
|
3
|
-
"version": "0.12.
|
|
4
|
-
"description": "Smart LLM router
|
|
3
|
+
"version": "0.12.264",
|
|
4
|
+
"description": "Smart LLM router \u2014 save 84% on inference costs. 76 models (7 free), one wallet, x402 micropayments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|