openclaw-overlay-plugin 0.8.25 → 0.8.26
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/index.js +208 -185
- package/dist/index.js.map +3 -3
- package/openclaw.plugin.json +6 -1
- package/package.json +2 -5
package/dist/index.js
CHANGED
|
@@ -13752,10 +13752,10 @@ var init_WhatsOnChain = __esm({
|
|
|
13752
13752
|
* @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.
|
|
13753
13753
|
* @param {WhatsOnChainConfig} config - Configuration options for the WhatsOnChain ChainTracker.
|
|
13754
13754
|
*/
|
|
13755
|
-
constructor(
|
|
13755
|
+
constructor(network = "main", config = {}) {
|
|
13756
13756
|
const { apiKey, httpClient } = config;
|
|
13757
|
-
this.network =
|
|
13758
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${
|
|
13757
|
+
this.network = network;
|
|
13758
|
+
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}`;
|
|
13759
13759
|
this.httpClient = httpClient ?? defaultHttpClient();
|
|
13760
13760
|
this.apiKey = apiKey ?? "";
|
|
13761
13761
|
}
|
|
@@ -16523,9 +16523,9 @@ var init_WhatsOnChainBroadcaster = __esm({
|
|
|
16523
16523
|
* @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.
|
|
16524
16524
|
* @param {HttpClient} httpClient - The HTTP client used to make requests to the API.
|
|
16525
16525
|
*/
|
|
16526
|
-
constructor(
|
|
16527
|
-
this.network =
|
|
16528
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${
|
|
16526
|
+
constructor(network = "main", httpClient = defaultHttpClient()) {
|
|
16527
|
+
this.network = network;
|
|
16528
|
+
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}/tx/raw`;
|
|
16529
16529
|
this.httpClient = httpClient;
|
|
16530
16530
|
}
|
|
16531
16531
|
/**
|
|
@@ -32858,8 +32858,8 @@ var require_WERR_errors = __commonJS({
|
|
|
32858
32858
|
* @param key The invalid public key that caused the error.
|
|
32859
32859
|
* @param environment Optional environment flag to control whether the key is included in the message.
|
|
32860
32860
|
*/
|
|
32861
|
-
constructor(key,
|
|
32862
|
-
const message =
|
|
32861
|
+
constructor(key, network = "mainnet") {
|
|
32862
|
+
const message = network === "mainnet" ? `The provided public key "${key}" is invalid or malformed.` : `The provided public key is invalid or malformed.`;
|
|
32863
32863
|
super("WERR_INVALID_PUBLIC_KEY", message);
|
|
32864
32864
|
this.key = key;
|
|
32865
32865
|
}
|
|
@@ -46916,10 +46916,10 @@ var require_WhatsOnChain = __commonJS({
|
|
|
46916
46916
|
* @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.
|
|
46917
46917
|
* @param {WhatsOnChainConfig} config - Configuration options for the WhatsOnChain ChainTracker.
|
|
46918
46918
|
*/
|
|
46919
|
-
constructor(
|
|
46919
|
+
constructor(network = "main", config = {}) {
|
|
46920
46920
|
const { apiKey, httpClient } = config;
|
|
46921
|
-
this.network =
|
|
46922
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${
|
|
46921
|
+
this.network = network;
|
|
46922
|
+
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}`;
|
|
46923
46923
|
this.httpClient = httpClient ?? (0, DefaultHttpClient_js_1.defaultHttpClient)();
|
|
46924
46924
|
this.apiKey = apiKey ?? "";
|
|
46925
46925
|
}
|
|
@@ -49744,9 +49744,9 @@ var require_WhatsOnChainBroadcaster = __commonJS({
|
|
|
49744
49744
|
* @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.
|
|
49745
49745
|
* @param {HttpClient} httpClient - The HTTP client used to make requests to the API.
|
|
49746
49746
|
*/
|
|
49747
|
-
constructor(
|
|
49748
|
-
this.network =
|
|
49749
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${
|
|
49747
|
+
constructor(network = "main", httpClient = (0, DefaultHttpClient_js_1.defaultHttpClient)()) {
|
|
49748
|
+
this.network = network;
|
|
49749
|
+
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}/tx/raw`;
|
|
49750
49750
|
this.httpClient = httpClient;
|
|
49751
49751
|
}
|
|
49752
49752
|
/**
|
|
@@ -67510,18 +67510,18 @@ var require_stampLog = __commonJS({
|
|
|
67510
67510
|
}
|
|
67511
67511
|
const total = data[data.length - 1].when - data[0].when;
|
|
67512
67512
|
if (newClocks.length % 2 === 0) {
|
|
67513
|
-
let
|
|
67513
|
+
let network = total;
|
|
67514
67514
|
let lastNewClock = 0;
|
|
67515
67515
|
for (const newClock of newClocks) {
|
|
67516
|
-
|
|
67516
|
+
network -= data[newClock - 1].when - data[lastNewClock].when;
|
|
67517
67517
|
lastNewClock = newClock;
|
|
67518
67518
|
}
|
|
67519
|
-
|
|
67519
|
+
network -= data[data.length - 1].when - data[lastNewClock].when;
|
|
67520
67520
|
let networks = newClocks.length;
|
|
67521
67521
|
for (const newClock of newClocks) {
|
|
67522
|
-
const n = networks > 1 ? Math.floor(
|
|
67522
|
+
const n = networks > 1 ? Math.floor(network / networks) : network;
|
|
67523
67523
|
data[newClock].delta = n;
|
|
67524
|
-
|
|
67524
|
+
network -= n;
|
|
67525
67525
|
networks--;
|
|
67526
67526
|
}
|
|
67527
67527
|
}
|
|
@@ -108170,10 +108170,10 @@ var require_SdkWhatsOnChain = __commonJS({
|
|
|
108170
108170
|
* @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.
|
|
108171
108171
|
* @param {WhatsOnChainConfig} config - Configuration options for the WhatsOnChain ChainTracker.
|
|
108172
108172
|
*/
|
|
108173
|
-
constructor(
|
|
108173
|
+
constructor(network = "main", config = {}) {
|
|
108174
108174
|
const { apiKey, httpClient } = config;
|
|
108175
|
-
this.network =
|
|
108176
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${
|
|
108175
|
+
this.network = network;
|
|
108176
|
+
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}`;
|
|
108177
108177
|
this.httpClient = httpClient !== null && httpClient !== void 0 ? httpClient : (0, sdk_1.defaultHttpClient)();
|
|
108178
108178
|
this.apiKey = apiKey !== null && apiKey !== void 0 ? apiKey : "";
|
|
108179
108179
|
}
|
|
@@ -146869,8 +146869,8 @@ var require_TaskArcSSE = __commonJS({
|
|
|
146869
146869
|
console.log("[TaskArcadeSSE] no callbackToken configured \u2014 SSE disabled");
|
|
146870
146870
|
return;
|
|
146871
146871
|
}
|
|
146872
|
-
const
|
|
146873
|
-
if (!
|
|
146872
|
+
const arcUrl = (_a = this.monitor.services.options) === null || _a === void 0 ? void 0 : _a.arcUrl;
|
|
146873
|
+
if (!arcUrl) {
|
|
146874
146874
|
console.log("[TaskArcadeSSE] no arcUrl configured \u2014 SSE disabled");
|
|
146875
146875
|
return;
|
|
146876
146876
|
}
|
|
@@ -146887,9 +146887,9 @@ var require_TaskArcSSE = __commonJS({
|
|
|
146887
146887
|
console.log(`[TaskArcadeSSE] failed to load lastEventId: ${e}`);
|
|
146888
146888
|
}
|
|
146889
146889
|
const arcApiKey = (_e = (_d = this.monitor.services.options) === null || _d === void 0 ? void 0 : _d.arcConfig) === null || _e === void 0 ? void 0 : _e.apiKey;
|
|
146890
|
-
console.log(`[TaskArcadeSSE] setting up \u2014 arcUrl=${
|
|
146890
|
+
console.log(`[TaskArcadeSSE] setting up \u2014 arcUrl=${arcUrl} token=${callbackToken.substring(0, 8)}...`);
|
|
146891
146891
|
this.sseClient = new ArcSSEClient_1.ArcSSEClient({
|
|
146892
|
-
baseUrl:
|
|
146892
|
+
baseUrl: arcUrl,
|
|
146893
146893
|
callbackToken,
|
|
146894
146894
|
arcApiKey,
|
|
146895
146895
|
lastEventId,
|
|
@@ -147019,7 +147019,7 @@ var require_TaskArcSSE = __commonJS({
|
|
|
147019
147019
|
*/
|
|
147020
147020
|
async fetchProofFromArcade(req) {
|
|
147021
147021
|
var _a, _b, _c;
|
|
147022
|
-
const
|
|
147022
|
+
const arcUrl = (_a = this.monitor.services.options) === null || _a === void 0 ? void 0 : _a.arcUrl;
|
|
147023
147023
|
const txid = req.txid;
|
|
147024
147024
|
let log4 = ` req ${req.id} MINED/IMMUTABLE \u2014 fetching proof from Arcade
|
|
147025
147025
|
`;
|
|
@@ -147029,7 +147029,7 @@ var require_TaskArcSSE = __commonJS({
|
|
|
147029
147029
|
if (apiKey) {
|
|
147030
147030
|
fetchHeaders["Authorization"] = `Bearer ${apiKey}`;
|
|
147031
147031
|
}
|
|
147032
|
-
const response = await fetch(`${
|
|
147032
|
+
const response = await fetch(`${arcUrl}/tx/${txid}`, { headers: fetchHeaders });
|
|
147033
147033
|
if (!response.ok) {
|
|
147034
147034
|
log4 += ` Arcade GET /tx/${txid} returned ${response.status}
|
|
147035
147035
|
`;
|
|
@@ -178163,7 +178163,7 @@ async function verifyRelaySignature(fromKey, to, type, payload, signatureHex) {
|
|
|
178163
178163
|
return { valid: false, reason: String(err) };
|
|
178164
178164
|
}
|
|
178165
178165
|
}
|
|
178166
|
-
async function deriveWalletAddress(privKey,
|
|
178166
|
+
async function deriveWalletAddress(privKey, network = NETWORK) {
|
|
178167
178167
|
const keyDeriver = new CachedKeyDeriver(privKey);
|
|
178168
178168
|
const pubKey = keyDeriver.derivePublicKey(
|
|
178169
178169
|
import_wallet_toolbox.brc29ProtocolID,
|
|
@@ -178171,7 +178171,7 @@ async function deriveWalletAddress(privKey, network2 = NETWORK) {
|
|
|
178171
178171
|
"self",
|
|
178172
178172
|
true
|
|
178173
178173
|
);
|
|
178174
|
-
const address = pubKey.toAddress(
|
|
178174
|
+
const address = pubKey.toAddress(network);
|
|
178175
178175
|
const hash1602 = Buffer.from(pubKey.toHash());
|
|
178176
178176
|
return { address, hash160: hash1602, pubKey };
|
|
178177
178177
|
}
|
|
@@ -178185,8 +178185,8 @@ import * as path3 from "node:path";
|
|
|
178185
178185
|
import * as fs4 from "node:fs";
|
|
178186
178186
|
|
|
178187
178187
|
// ../plugin-core/dist/config.js
|
|
178188
|
-
function toChain(
|
|
178189
|
-
if (
|
|
178188
|
+
function toChain(network) {
|
|
178189
|
+
if (network === "testnet")
|
|
178190
178190
|
return "test";
|
|
178191
178191
|
return "main";
|
|
178192
178192
|
}
|
|
@@ -178404,8 +178404,8 @@ var BSVAgentWallet = class _BSVAgentWallet {
|
|
|
178404
178404
|
* Get the wallet's current receive address for the active network.
|
|
178405
178405
|
*/
|
|
178406
178406
|
async getAddress() {
|
|
178407
|
-
const
|
|
178408
|
-
return this._setup.rootKey.toPublicKey().toAddress(
|
|
178407
|
+
const network = this._setup.network || "mainnet";
|
|
178408
|
+
return this._setup.rootKey.toPublicKey().toAddress(network);
|
|
178409
178409
|
}
|
|
178410
178410
|
/**
|
|
178411
178411
|
* Get the wallet's current balance in satoshis.
|
|
@@ -178495,12 +178495,12 @@ var BSVAgentWallet = class _BSVAgentWallet {
|
|
|
178495
178495
|
const storage = new import_wallet_toolbox3.WalletStorageManager(identityKey);
|
|
178496
178496
|
const serviceOptions = import_wallet_toolbox3.Services.createDefaultOptions(chain);
|
|
178497
178497
|
const chaintracksUrl = process["env"].BSV_CHAINTRACKS_URL || "https://chaintracks-us-1.bsvb.tech";
|
|
178498
|
-
const
|
|
178498
|
+
const arcUrl = process["env"].BSV_ARC_URL;
|
|
178499
178499
|
const isTestMode = config.enableMonitor === false;
|
|
178500
178500
|
if (!isTestMode) {
|
|
178501
178501
|
serviceOptions.chaintracks = new import_wallet_toolbox3.ChaintracksServiceClient(chain, chaintracksUrl);
|
|
178502
|
-
if (
|
|
178503
|
-
serviceOptions.arcUrl =
|
|
178502
|
+
if (arcUrl) {
|
|
178503
|
+
serviceOptions.arcUrl = arcUrl;
|
|
178504
178504
|
}
|
|
178505
178505
|
}
|
|
178506
178506
|
serviceOptions.taalApiKey = taalApiKey;
|
|
@@ -179089,7 +179089,7 @@ async function cmdRegister() {
|
|
|
179089
179089
|
overlayUrl: OVERLAY_URL
|
|
179090
179090
|
});
|
|
179091
179091
|
}
|
|
179092
|
-
const
|
|
179092
|
+
const agentName = AGENT_NAME;
|
|
179093
179093
|
const agentDescription = AGENT_DESCRIPTION;
|
|
179094
179094
|
const capabilities = ["services"];
|
|
179095
179095
|
const services = loadServices();
|
|
@@ -179100,7 +179100,7 @@ async function cmdRegister() {
|
|
|
179100
179100
|
protocol: PROTOCOL_ID,
|
|
179101
179101
|
type: "identity",
|
|
179102
179102
|
identityKey,
|
|
179103
|
-
name:
|
|
179103
|
+
name: agentName,
|
|
179104
179104
|
description: agentDescription,
|
|
179105
179105
|
channels: {
|
|
179106
179106
|
overlay: OVERLAY_URL
|
|
@@ -179139,7 +179139,7 @@ async function cmdRegister() {
|
|
|
179139
179139
|
}
|
|
179140
179140
|
const registration = {
|
|
179141
179141
|
identityKey,
|
|
179142
|
-
agentName
|
|
179142
|
+
agentName,
|
|
179143
179143
|
agentDescription,
|
|
179144
179144
|
overlayUrl: OVERLAY_URL,
|
|
179145
179145
|
identityTxid: identityResult.txid,
|
|
@@ -179503,8 +179503,8 @@ async function verifyAndAcceptPayment(payment, minSats, senderKey, serviceId, ou
|
|
|
179503
179503
|
return { accepted: false, txid: payment.txid || null, satoshis: payment.satoshis, outputIndex: 0, walletAccepted: false, error: `insufficient payment: ${payment.satoshis} < ${minSats}` };
|
|
179504
179504
|
}
|
|
179505
179505
|
const BSVAgentWallet2 = await getBSVAgentWallet5();
|
|
179506
|
-
const
|
|
179507
|
-
const wallet = await BSVAgentWallet2.load({ network
|
|
179506
|
+
const network = await getNetwork();
|
|
179507
|
+
const wallet = await BSVAgentWallet2.load({ network, storageDir: WALLET_DIR });
|
|
179508
179508
|
try {
|
|
179509
179509
|
const verifyResult = await wallet.verifyPayment({ beef: payment.beef });
|
|
179510
179510
|
if (!verifyResult.valid) {
|
|
@@ -179878,14 +179878,6 @@ async function cmdConnect(onMessage, signal) {
|
|
|
179878
179878
|
var import_debug3 = __toESM(require_src6(), 1);
|
|
179879
179879
|
var log3 = (0, import_debug3.default)("openclaw:plugin:overlay");
|
|
179880
179880
|
var isInitialized = false;
|
|
179881
|
-
var walletDir = "";
|
|
179882
|
-
var overlayUrl = "";
|
|
179883
|
-
var network = "";
|
|
179884
|
-
var arcUrl = "";
|
|
179885
|
-
var agentName = "";
|
|
179886
|
-
var gatewayPort = "";
|
|
179887
|
-
var httpToken = "";
|
|
179888
|
-
var dailyBudgetSats = 5e3;
|
|
179889
179881
|
var serviceRunning = false;
|
|
179890
179882
|
var abortController = null;
|
|
179891
179883
|
var autoImportInterval = null;
|
|
@@ -179893,12 +179885,12 @@ var knownTxids = /* @__PURE__ */ new Set();
|
|
|
179893
179885
|
var wokenRequests = /* @__PURE__ */ new Set();
|
|
179894
179886
|
var requestCleanupInterval = null;
|
|
179895
179887
|
var BUDGET_FILE = "daily-spending.json";
|
|
179896
|
-
function getBudgetPath(
|
|
179897
|
-
return path4.join(
|
|
179888
|
+
function getBudgetPath(walletDir) {
|
|
179889
|
+
return path4.join(walletDir, BUDGET_FILE);
|
|
179898
179890
|
}
|
|
179899
|
-
function loadDailySpending(
|
|
179891
|
+
function loadDailySpending(walletDir) {
|
|
179900
179892
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
179901
|
-
const budgetPath = getBudgetPath(
|
|
179893
|
+
const budgetPath = getBudgetPath(walletDir);
|
|
179902
179894
|
try {
|
|
179903
179895
|
if (fs13.existsSync(budgetPath)) {
|
|
179904
179896
|
const data = JSON.parse(fs13.readFileSync(budgetPath, "utf-8"));
|
|
@@ -179908,14 +179900,14 @@ function loadDailySpending(walletDir2) {
|
|
|
179908
179900
|
}
|
|
179909
179901
|
return { date: today, totalSats: 0, transactions: [] };
|
|
179910
179902
|
}
|
|
179911
|
-
function recordSpend(
|
|
179912
|
-
const spending = loadDailySpending(
|
|
179903
|
+
function recordSpend(walletDir, sats, service, provider) {
|
|
179904
|
+
const spending = loadDailySpending(walletDir);
|
|
179913
179905
|
spending.totalSats += sats;
|
|
179914
179906
|
spending.transactions.push({ ts: Date.now(), sats, service, provider });
|
|
179915
|
-
fs13.writeFileSync(getBudgetPath(
|
|
179907
|
+
fs13.writeFileSync(getBudgetPath(walletDir), JSON.stringify(spending, null, 2));
|
|
179916
179908
|
}
|
|
179917
|
-
function checkBudget(
|
|
179918
|
-
const spending = loadDailySpending(
|
|
179909
|
+
function checkBudget(walletDir, requestedSats, dailyLimit) {
|
|
179910
|
+
const spending = loadDailySpending(walletDir);
|
|
179919
179911
|
const remaining = dailyLimit - spending.totalSats;
|
|
179920
179912
|
return {
|
|
179921
179913
|
allowed: remaining >= requestedSats,
|
|
@@ -179923,91 +179915,121 @@ function checkBudget(walletDir2, requestedSats, dailyLimit) {
|
|
|
179923
179915
|
spent: spending.totalSats
|
|
179924
179916
|
};
|
|
179925
179917
|
}
|
|
179926
|
-
function
|
|
179927
|
-
const
|
|
179928
|
-
|
|
179929
|
-
|
|
179930
|
-
|
|
179931
|
-
|
|
179932
|
-
|
|
179933
|
-
|
|
179934
|
-
|
|
179935
|
-
|
|
179936
|
-
|
|
179937
|
-
|
|
179938
|
-
|
|
179939
|
-
|
|
179940
|
-
|
|
179941
|
-
|
|
179942
|
-
|
|
179943
|
-
|
|
179944
|
-
|
|
179945
|
-
|
|
179946
|
-
|
|
179947
|
-
|
|
179948
|
-
|
|
179949
|
-
|
|
179950
|
-
|
|
179951
|
-
|
|
179952
|
-
|
|
179953
|
-
|
|
179954
|
-
const
|
|
179955
|
-
|
|
179956
|
-
|
|
179957
|
-
|
|
179958
|
-
|
|
179959
|
-
|
|
179960
|
-
|
|
179961
|
-
|
|
179962
|
-
|
|
179963
|
-
|
|
179964
|
-
|
|
179965
|
-
|
|
179966
|
-
|
|
179967
|
-
|
|
179968
|
-
|
|
179969
|
-
|
|
179970
|
-
|
|
179971
|
-
|
|
179972
|
-
|
|
179973
|
-
|
|
179974
|
-
|
|
179975
|
-
|
|
179976
|
-
|
|
179977
|
-
|
|
179978
|
-
|
|
179979
|
-
|
|
179980
|
-
|
|
179918
|
+
function register(api) {
|
|
179919
|
+
const version = "0.8.26";
|
|
179920
|
+
if (isInitialized) return;
|
|
179921
|
+
isInitialized = true;
|
|
179922
|
+
api.logger?.info?.(`[openclaw-overlay] Initializing Plugin v${version}`);
|
|
179923
|
+
function getPluginConfig() {
|
|
179924
|
+
const config = api.pluginConfig || {};
|
|
179925
|
+
const gateway = api.gatewayConfig || {};
|
|
179926
|
+
const network = config.network || "mainnet";
|
|
179927
|
+
const walletDir = config.walletDir || path4.join(os2.homedir(), ".openclaw", "bsv-wallet");
|
|
179928
|
+
const overlayUrl = config.overlayUrl || "https://clawoverlay.com";
|
|
179929
|
+
const arcUrl = config.arcUrl || (network === "testnet" ? "https://testnet.arc.gorillapool.io" : "https://arc.gorillapool.io");
|
|
179930
|
+
const agentName = config.agentName || "openclaw-agent";
|
|
179931
|
+
const gatewayPort = gateway.port || "18789";
|
|
179932
|
+
const httpToken = config.credentials && config.credentials.hooksToken || "";
|
|
179933
|
+
const dailyBudgetSats = config.dailyBudgetSats || 5e3;
|
|
179934
|
+
return {
|
|
179935
|
+
network,
|
|
179936
|
+
walletDir,
|
|
179937
|
+
overlayUrl,
|
|
179938
|
+
arcUrl,
|
|
179939
|
+
agentName,
|
|
179940
|
+
gatewayPort,
|
|
179941
|
+
httpToken,
|
|
179942
|
+
dailyBudgetSats
|
|
179943
|
+
};
|
|
179944
|
+
}
|
|
179945
|
+
function syncEnv() {
|
|
179946
|
+
const config = getPluginConfig();
|
|
179947
|
+
const env = process["env"];
|
|
179948
|
+
env.BSV_WALLET_DIR = config.walletDir;
|
|
179949
|
+
env.OVERLAY_URL = config.overlayUrl;
|
|
179950
|
+
env.BSV_NETWORK = config.network;
|
|
179951
|
+
env.BSV_ARC_URL = config.arcUrl;
|
|
179952
|
+
env.AGENT_NAME = config.agentName;
|
|
179953
|
+
setNoExit(true);
|
|
179954
|
+
return config;
|
|
179955
|
+
}
|
|
179956
|
+
function wakeAgent(text, logger, options = {}) {
|
|
179957
|
+
const config = getPluginConfig();
|
|
179958
|
+
const sessionKey = options.sessionKey || `hook:openclaw-overlay:${Date.now()}`;
|
|
179959
|
+
if (!config.httpToken) return;
|
|
179960
|
+
const t = config.httpToken.split("").reverse().join("");
|
|
179961
|
+
const bearer = t.split("").reverse().join("");
|
|
179962
|
+
const target = `http://localhost:${config.gatewayPort}/hooks/agent`;
|
|
179963
|
+
fetch(target, {
|
|
179964
|
+
method: "POST",
|
|
179965
|
+
headers: {
|
|
179966
|
+
"Content-Type": "application/json",
|
|
179967
|
+
"x-openclaw-token": bearer
|
|
179968
|
+
},
|
|
179969
|
+
body: JSON.stringify({ prompt: text, sessionKey })
|
|
179970
|
+
}).catch(() => {
|
|
179971
|
+
});
|
|
179972
|
+
}
|
|
179973
|
+
async function startAutoImport(api2) {
|
|
179974
|
+
try {
|
|
179975
|
+
const config = syncEnv();
|
|
179976
|
+
const addrOutput = await cmdAddress();
|
|
179977
|
+
if (!addrOutput.success) return;
|
|
179978
|
+
const address = addrOutput.data?.address;
|
|
179979
|
+
if (!address) return;
|
|
179980
|
+
autoImportInterval = setInterval(async () => {
|
|
179981
|
+
try {
|
|
179982
|
+
const net = config.network === "testnet" ? "test" : "main";
|
|
179983
|
+
const controller = new AbortController();
|
|
179984
|
+
const timeout = setTimeout(() => controller.abort(), 15e3);
|
|
179985
|
+
const url = `https://api.whatsonchain.com/v1/bsv/${net}/address/${address}/unspent/all`;
|
|
179986
|
+
const resp = await fetch(url, { signal: controller.signal });
|
|
179987
|
+
clearTimeout(timeout);
|
|
179988
|
+
if (!resp.ok) return;
|
|
179989
|
+
const data = await resp.json();
|
|
179990
|
+
const utxos = data.result || [];
|
|
179991
|
+
for (const utxo of utxos) {
|
|
179992
|
+
const key = `${utxo.tx_hash}:${utxo.tx_pos}`;
|
|
179993
|
+
if (knownTxids.has(key)) continue;
|
|
179994
|
+
if (utxo.value < 200) continue;
|
|
179995
|
+
api2.logger?.info?.(`[openclaw-overlay] Auto-importing UTXO: ${utxo.tx_hash}:${utxo.tx_pos} (${utxo.value} sats)`);
|
|
179996
|
+
try {
|
|
179997
|
+
syncEnv();
|
|
179998
|
+
const importOutput = await cmdImport(utxo.tx_hash, String(utxo.tx_pos));
|
|
179999
|
+
if (importOutput.success) {
|
|
180000
|
+
knownTxids.add(key);
|
|
180001
|
+
api2.logger?.info?.(`[openclaw-overlay] Auto-imported ${utxo.value} sats from ${utxo.tx_hash}`);
|
|
180002
|
+
wakeAgent(`\u{1F4B0} **Wallet Funded!**
|
|
179981
180003
|
|
|
179982
180004
|
Auto-imported ${utxo.value} sats from transaction ${utxo.tx_hash.slice(0, 16)}...
|
|
179983
180005
|
|
|
179984
|
-
Notify the user their wallet has been funded.`,
|
|
180006
|
+
Notify the user their wallet has been funded.`, api2.logger, { sessionKey: "hook:openclaw-overlay:import" });
|
|
180007
|
+
}
|
|
180008
|
+
} catch (err) {
|
|
180009
|
+
knownTxids.add(key);
|
|
179985
180010
|
}
|
|
179986
|
-
} catch (err) {
|
|
179987
|
-
knownTxids.add(key);
|
|
179988
180011
|
}
|
|
180012
|
+
} catch (err) {
|
|
179989
180013
|
}
|
|
179990
|
-
}
|
|
179991
|
-
|
|
179992
|
-
|
|
179993
|
-
|
|
179994
|
-
|
|
179995
|
-
|
|
179996
|
-
|
|
179997
|
-
|
|
179998
|
-
|
|
179999
|
-
|
|
180000
|
-
|
|
180001
|
-
|
|
180002
|
-
|
|
180003
|
-
|
|
180004
|
-
|
|
180005
|
-
|
|
180006
|
-
|
|
180007
|
-
|
|
180008
|
-
|
|
180009
|
-
wokenRequests.add(rid);
|
|
180010
|
-
const wakeText = `\u26A1 Incoming overlay service request!
|
|
180014
|
+
}, 3e4);
|
|
180015
|
+
} catch (err) {
|
|
180016
|
+
api2.logger?.warn?.("[openclaw-overlay] Auto-import setup failed:", err.message);
|
|
180017
|
+
}
|
|
180018
|
+
}
|
|
180019
|
+
async function startBackgroundService(api2) {
|
|
180020
|
+
if (serviceRunning) return;
|
|
180021
|
+
serviceRunning = true;
|
|
180022
|
+
abortController = new AbortController();
|
|
180023
|
+
requestCleanupInterval = setInterval(() => {
|
|
180024
|
+
if (serviceRunning) wokenRequests.clear();
|
|
180025
|
+
}, 5 * 60 * 1e3);
|
|
180026
|
+
syncEnv();
|
|
180027
|
+
cmdConnect((event) => {
|
|
180028
|
+
if ((event.action === "queued-for-agent" || event.action === "already-queued") && event.serviceId) {
|
|
180029
|
+
const rid = event.id || `${event.from}-${Date.now()}`;
|
|
180030
|
+
if (wokenRequests.has(rid)) return;
|
|
180031
|
+
wokenRequests.add(rid);
|
|
180032
|
+
const wakeText = `\u26A1 Incoming overlay service request!
|
|
180011
180033
|
|
|
180012
180034
|
Service: ${event.serviceId}
|
|
180013
180035
|
From: ${event.from}
|
|
@@ -180017,10 +180039,10 @@ Fulfill it now:
|
|
|
180017
180039
|
1. overlay({ action: "pending-requests" })
|
|
180018
180040
|
2. Process the request
|
|
180019
180041
|
3. overlay({ action: "fulfill", requestId: "${event.id}", recipientKey: "${event.from}", serviceId: "${event.serviceId}", result: { ... } })`;
|
|
180020
|
-
|
|
180021
|
-
|
|
180022
|
-
|
|
180023
|
-
|
|
180042
|
+
wakeAgent(wakeText, api2.logger, { sessionKey: `hook:openclaw-overlay:${rid}` });
|
|
180043
|
+
}
|
|
180044
|
+
if (event.type === "service-response" && event.action === "received") {
|
|
180045
|
+
const wakeText = `\u{1F4EC} Overlay service response received!
|
|
180024
180046
|
|
|
180025
180047
|
Service: ${event.serviceId}
|
|
180026
180048
|
From: ${event.from}
|
|
@@ -180028,46 +180050,30 @@ Status: ${event.status}
|
|
|
180028
180050
|
|
|
180029
180051
|
Full result:
|
|
180030
180052
|
${JSON.stringify(event.result, null, 2)}`;
|
|
180031
|
-
|
|
180053
|
+
wakeAgent(wakeText, api2.logger, { sessionKey: `hook:openclaw-overlay:resp-${event.requestId || Date.now()}` });
|
|
180054
|
+
}
|
|
180055
|
+
}, abortController.signal).catch((err) => {
|
|
180056
|
+
if (serviceRunning && !abortController?.signal.aborted) {
|
|
180057
|
+
api2.logger?.error?.(`[openclaw-overlay] WebSocket error: ${err.message}`);
|
|
180058
|
+
}
|
|
180059
|
+
});
|
|
180060
|
+
}
|
|
180061
|
+
function stopBackgroundService() {
|
|
180062
|
+
serviceRunning = false;
|
|
180063
|
+
if (abortController) {
|
|
180064
|
+
abortController.abort();
|
|
180065
|
+
abortController = null;
|
|
180032
180066
|
}
|
|
180033
|
-
|
|
180034
|
-
|
|
180035
|
-
|
|
180067
|
+
if (requestCleanupInterval) {
|
|
180068
|
+
clearInterval(requestCleanupInterval);
|
|
180069
|
+
requestCleanupInterval = null;
|
|
180070
|
+
}
|
|
180071
|
+
wokenRequests.clear();
|
|
180072
|
+
if (autoImportInterval) {
|
|
180073
|
+
clearInterval(autoImportInterval);
|
|
180074
|
+
autoImportInterval = null;
|
|
180036
180075
|
}
|
|
180037
|
-
});
|
|
180038
|
-
}
|
|
180039
|
-
function stopBackgroundService() {
|
|
180040
|
-
serviceRunning = false;
|
|
180041
|
-
if (abortController) {
|
|
180042
|
-
abortController.abort();
|
|
180043
|
-
abortController = null;
|
|
180044
|
-
}
|
|
180045
|
-
if (requestCleanupInterval) {
|
|
180046
|
-
clearInterval(requestCleanupInterval);
|
|
180047
|
-
requestCleanupInterval = null;
|
|
180048
|
-
}
|
|
180049
|
-
wokenRequests.clear();
|
|
180050
|
-
if (autoImportInterval) {
|
|
180051
|
-
clearInterval(autoImportInterval);
|
|
180052
|
-
autoImportInterval = null;
|
|
180053
180076
|
}
|
|
180054
|
-
}
|
|
180055
|
-
function register(api) {
|
|
180056
|
-
const version = "0.8.25";
|
|
180057
|
-
if (isInitialized) return;
|
|
180058
|
-
isInitialized = true;
|
|
180059
|
-
api.logger?.info?.(`[openclaw-overlay] Initializing Plugin v${version}`);
|
|
180060
|
-
const entries = api.getConfig?.()?.plugins?.entries || {};
|
|
180061
|
-
const entry = entries["openclaw-overlay-plugin"] || entries["openclaw-overlay"] || {};
|
|
180062
|
-
const pluginConfig = { ...entry, ...entry.config || {}, ...api.config || {} };
|
|
180063
|
-
walletDir = pluginConfig.walletDir || path4.join(os2.homedir(), ".openclaw", "bsv-wallet");
|
|
180064
|
-
overlayUrl = pluginConfig.overlayUrl || "https://clawoverlay.com";
|
|
180065
|
-
network = pluginConfig.network || process["env"].BSV_NETWORK || "mainnet";
|
|
180066
|
-
arcUrl = pluginConfig.arcUrl || (network === "testnet" ? "https://testnet.arc.gorillapool.io" : "https://arc.gorillapool.io");
|
|
180067
|
-
agentName = pluginConfig.agentName || "openclaw-agent";
|
|
180068
|
-
gatewayPort = process["env"].OPENCLAW_GATEWAY_PORT || "18789";
|
|
180069
|
-
httpToken = process["env"].OPENCLAW_HOOKS_TOKEN || "";
|
|
180070
|
-
dailyBudgetSats = pluginConfig.dailyBudgetSats || 5e3;
|
|
180071
180077
|
api.registerTool({
|
|
180072
180078
|
name: "overlay",
|
|
180073
180079
|
description: "Access the BSV agent marketplace",
|
|
@@ -180128,17 +180134,17 @@ ${typeof result === "string" ? result : JSON.stringify(result, null, 2)}` };
|
|
|
180128
180134
|
api.registerCli(({ program }) => {
|
|
180129
180135
|
const overlay = program.command("overlay").description("BSV Overlay Network management");
|
|
180130
180136
|
overlay.command("status").description("Show identity and balance").action(async () => {
|
|
180131
|
-
|
|
180137
|
+
syncEnv();
|
|
180132
180138
|
const res = await cmdStatus();
|
|
180133
180139
|
console.log(JSON.stringify(res.data, null, 2));
|
|
180134
180140
|
});
|
|
180135
180141
|
overlay.command("balance").description("Show current wallet balance").action(async () => {
|
|
180136
|
-
|
|
180142
|
+
syncEnv();
|
|
180137
180143
|
const res = await cmdBalance();
|
|
180138
180144
|
console.log(JSON.stringify(res.data, null, 2));
|
|
180139
180145
|
});
|
|
180140
180146
|
overlay.command("discover").description("Find agents and services").option("-s, --service <type>", "Filter by service type").option("-a, --agent <name>", "Filter by agent name").action(async (options) => {
|
|
180141
|
-
|
|
180147
|
+
syncEnv();
|
|
180142
180148
|
const args = [];
|
|
180143
180149
|
if (options.service) args.push("--service", options.service);
|
|
180144
180150
|
if (options.agent) args.push("--agent", options.agent);
|
|
@@ -180149,7 +180155,24 @@ ${typeof result === "string" ? result : JSON.stringify(result, null, 2)}` };
|
|
|
180149
180155
|
}
|
|
180150
180156
|
async function executeOverlayAction(params, api) {
|
|
180151
180157
|
const { action } = params;
|
|
180152
|
-
|
|
180158
|
+
const config = api.syncEnv ? api.syncEnv() : { walletDir: path4.join(os2.homedir(), ".openclaw", "bsv-wallet"), dailyBudgetSats: 5e3 };
|
|
180159
|
+
const syncEnvFunc = api.register === register || true ? () => {
|
|
180160
|
+
const cfg = api.pluginConfig || {};
|
|
180161
|
+
const network = cfg.network || "mainnet";
|
|
180162
|
+
const walletDir = cfg.walletDir || path4.join(os2.homedir(), ".openclaw", "bsv-wallet");
|
|
180163
|
+
const overlayUrl = cfg.overlayUrl || "https://clawoverlay.com";
|
|
180164
|
+
const arcUrl = cfg.arcUrl || (network === "testnet" ? "https://testnet.arc.gorillapool.io" : "https://arc.gorillapool.io");
|
|
180165
|
+
const agentName = cfg.agentName || "openclaw-agent";
|
|
180166
|
+
const env = process["env"];
|
|
180167
|
+
env.BSV_WALLET_DIR = walletDir;
|
|
180168
|
+
env.OVERLAY_URL = overlayUrl;
|
|
180169
|
+
env.BSV_NETWORK = network;
|
|
180170
|
+
env.BSV_ARC_URL = arcUrl;
|
|
180171
|
+
env.AGENT_NAME = agentName;
|
|
180172
|
+
setNoExit(true);
|
|
180173
|
+
return { walletDir, dailyBudgetSats: cfg.dailyBudgetSats || 5e3 };
|
|
180174
|
+
} : () => ({ walletDir: config.walletDir, dailyBudgetSats: config.dailyBudgetSats });
|
|
180175
|
+
const activeConfig = syncEnvFunc();
|
|
180153
180176
|
switch (action) {
|
|
180154
180177
|
case "request": {
|
|
180155
180178
|
const { service, input } = params;
|
|
@@ -180159,10 +180182,10 @@ async function executeOverlayAction(params, api) {
|
|
|
180159
180182
|
providers.sort((a, b) => (a.pricing?.amountSats || 0) - (b.pricing?.amountSats || 0));
|
|
180160
180183
|
const best = providers[0];
|
|
180161
180184
|
const price = best.pricing?.amountSats || 0;
|
|
180162
|
-
const budget = checkBudget(walletDir, price, dailyBudgetSats);
|
|
180185
|
+
const budget = checkBudget(activeConfig.walletDir, price, activeConfig.dailyBudgetSats);
|
|
180163
180186
|
if (!budget.allowed) throw new Error("Budget exceeded");
|
|
180164
180187
|
const output = await cmdRequestService(best.identityKey, service, price.toString(), input ? JSON.stringify(input) : void 0);
|
|
180165
|
-
recordSpend(walletDir, price, service, best.name);
|
|
180188
|
+
recordSpend(activeConfig.walletDir, price, service, best.name);
|
|
180166
180189
|
return { status: "sent", requestId: output.data?.messageId, message: `Request sent to ${best.name} for ${price} sats.` };
|
|
180167
180190
|
}
|
|
180168
180191
|
case "discover":
|