@secondlayer/stacks 5.1.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -340
- package/dist/src/filters/index.d.cts +3 -3
- package/dist/src/filters/index.d.ts +3 -3
- package/dist/src/index.d.cts +2 -2
- package/dist/src/index.d.ts +2 -2
- package/package.json +4 -24
- package/dist/src/tools/btc/index.cjs +0 -131
- package/dist/src/tools/btc/index.cjs.map +0 -10
- package/dist/src/tools/btc/index.d.cts +0 -10
- package/dist/src/tools/btc/index.d.ts +0 -10
- package/dist/src/tools/btc/index.js +0 -90
- package/dist/src/tools/btc/index.js.map +0 -10
- package/dist/src/tools/index.cjs +0 -3865
- package/dist/src/tools/index.cjs.map +0 -80
- package/dist/src/tools/index.d.cts +0 -206
- package/dist/src/tools/index.d.ts +0 -206
- package/dist/src/tools/index.js +0 -3827
- package/dist/src/tools/index.js.map +0 -80
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
var import_node_module = require("node:module");
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
function __accessProp(key) {
|
|
7
|
-
return this[key];
|
|
8
|
-
}
|
|
9
|
-
var __toCommonJS = (from) => {
|
|
10
|
-
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
11
|
-
if (entry)
|
|
12
|
-
return entry;
|
|
13
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
14
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
-
for (var key of __getOwnPropNames(from))
|
|
16
|
-
if (!__hasOwnProp.call(entry, key))
|
|
17
|
-
__defProp(entry, key, {
|
|
18
|
-
get: __accessProp.bind(from, key),
|
|
19
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
__moduleCache.set(from, entry);
|
|
23
|
-
return entry;
|
|
24
|
-
};
|
|
25
|
-
var __moduleCache;
|
|
26
|
-
var __returnValue = (v) => v;
|
|
27
|
-
function __exportSetter(name, newValue) {
|
|
28
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
29
|
-
}
|
|
30
|
-
var __export = (target, all) => {
|
|
31
|
-
for (var name in all)
|
|
32
|
-
__defProp(target, name, {
|
|
33
|
-
get: all[name],
|
|
34
|
-
enumerable: true,
|
|
35
|
-
configurable: true,
|
|
36
|
-
set: __exportSetter.bind(all, name)
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// src/tools/btc/index.ts
|
|
41
|
-
var exports_btc = {};
|
|
42
|
-
__export(exports_btc, {
|
|
43
|
-
btcUtxos: () => btcUtxos,
|
|
44
|
-
btcFeeEstimate: () => btcFeeEstimate,
|
|
45
|
-
btcConfirmations: () => btcConfirmations,
|
|
46
|
-
btcBlockHeight: () => btcBlockHeight,
|
|
47
|
-
btcBalance: () => btcBalance,
|
|
48
|
-
BTC_ADDRESS: () => BTC_ADDRESS
|
|
49
|
-
});
|
|
50
|
-
module.exports = __toCommonJS(exports_btc);
|
|
51
|
-
var import_ai = require("ai");
|
|
52
|
-
var import_zod = require("zod");
|
|
53
|
-
function baseUrl() {
|
|
54
|
-
return (process.env.BTC_MEMPOOL_URL ?? "https://mempool.space").replace(/\/$/, "");
|
|
55
|
-
}
|
|
56
|
-
async function get(path) {
|
|
57
|
-
const res = await fetch(`${baseUrl()}${path}`, {
|
|
58
|
-
headers: { Accept: "application/json" }
|
|
59
|
-
});
|
|
60
|
-
if (!res.ok) {
|
|
61
|
-
throw new Error(`BTC mempool.space ${path} → ${res.status} ${res.statusText}`);
|
|
62
|
-
}
|
|
63
|
-
const contentType = res.headers.get("content-type") ?? "";
|
|
64
|
-
if (contentType.includes("application/json"))
|
|
65
|
-
return res.json();
|
|
66
|
-
return res.text();
|
|
67
|
-
}
|
|
68
|
-
var BTC_TXID = import_zod.z.string().regex(/^[0-9a-fA-F]{64}$/, "64-character hex BTC txid");
|
|
69
|
-
var BTC_ADDRESS = import_zod.z.string().regex(/^(1[a-zA-HJ-NP-Z0-9]{25,34}|3[a-zA-HJ-NP-Z0-9]{25,34}|bc1[a-zA-HJ-NP-Z0-9]{11,71}|tb1[a-zA-HJ-NP-Z0-9]{11,71})$/, { message: "Invalid Bitcoin address" });
|
|
70
|
-
var btcConfirmations = import_ai.tool({
|
|
71
|
-
description: "Number of confirmations for a Bitcoin transaction. Returns { confirmations, confirmed }.",
|
|
72
|
-
inputSchema: import_zod.z.object({ txid: BTC_TXID }),
|
|
73
|
-
execute: async ({ txid }) => {
|
|
74
|
-
const tx = await get(`/api/tx/${txid}`);
|
|
75
|
-
if (!tx.status.confirmed || tx.status.block_height == null) {
|
|
76
|
-
return { confirmed: false, confirmations: 0 };
|
|
77
|
-
}
|
|
78
|
-
const tip = await get("/api/blocks/tip/height");
|
|
79
|
-
return {
|
|
80
|
-
confirmed: true,
|
|
81
|
-
confirmations: Math.max(0, tip - tx.status.block_height + 1),
|
|
82
|
-
blockHeight: tx.status.block_height
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
var btcBalance = import_ai.tool({
|
|
87
|
-
description: "Bitcoin balance for an address, in satoshis. Returns { confirmedSat, unconfirmedSat }.",
|
|
88
|
-
inputSchema: import_zod.z.object({ address: BTC_ADDRESS }),
|
|
89
|
-
execute: async ({ address }) => {
|
|
90
|
-
const info = await get(`/api/address/${encodeURIComponent(address)}`);
|
|
91
|
-
return {
|
|
92
|
-
confirmedSat: info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum,
|
|
93
|
-
unconfirmedSat: info.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
var btcUtxos = import_ai.tool({
|
|
98
|
-
description: "List of unspent outputs for a Bitcoin address (truncated to `limit`).",
|
|
99
|
-
inputSchema: import_zod.z.object({
|
|
100
|
-
address: BTC_ADDRESS,
|
|
101
|
-
limit: import_zod.z.number().int().min(1).max(50).default(25)
|
|
102
|
-
}),
|
|
103
|
-
execute: async ({ address, limit }) => {
|
|
104
|
-
const utxos = await get(`/api/address/${encodeURIComponent(address)}/utxo`);
|
|
105
|
-
return { utxos: utxos.slice(0, limit) };
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
var btcFeeEstimate = import_ai.tool({
|
|
109
|
-
description: "Current Bitcoin fee estimates in sat/vB across priority tiers (fastest, 30-min, hour, economy).",
|
|
110
|
-
inputSchema: import_zod.z.object({}),
|
|
111
|
-
execute: async () => {
|
|
112
|
-
const fees = await get("/api/v1/fees/recommended");
|
|
113
|
-
return {
|
|
114
|
-
fastestSatVb: fees.fastestFee ?? 0,
|
|
115
|
-
halfHourSatVb: fees.halfHourFee ?? 0,
|
|
116
|
-
hourSatVb: fees.hourFee ?? 0,
|
|
117
|
-
economySatVb: fees.economyFee ?? 0,
|
|
118
|
-
minimumSatVb: fees.minimumFee ?? 0
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
var btcBlockHeight = import_ai.tool({
|
|
123
|
-
description: "Current Bitcoin chain tip height.",
|
|
124
|
-
inputSchema: import_zod.z.object({}),
|
|
125
|
-
execute: async () => ({
|
|
126
|
-
height: await get("/api/blocks/tip/height")
|
|
127
|
-
})
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
//# debugId=A9918581E436E21F64756E2164756E21
|
|
131
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/tools/btc/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Bitcoin read tools for AI SDK tool calls. Useful for sBTC peg-in/peg-out\n * flows, BTC-collateralized lending, and anywhere a Stacks contract's\n * behaviour depends on BTC state.\n *\n * @deprecated Point your agent at `@secondlayer/mcp` instead; this entry\n * stays importable until the next major but gets no new tools. Installing\n * it means installing `ai` and `zod` yourself: both are optional peers of\n * the package, not dependencies.\n *\n * Backed by mempool.space by default. Swap endpoints by setting\n * `BTC_MEMPOOL_URL` in the caller's env. Reads only, no BTC writes.\n *\n * import { generateText } from \"ai\"\n * import { btcConfirmations, btcBalance } from \"@secondlayer/stacks/tools/btc\"\n * await generateText({\n * model: anthropic(\"claude-sonnet-4-6\"),\n * tools: { btcConfirmations, btcBalance },\n * prompt: \"…\",\n * })\n */\n\nimport { type Tool, tool } from \"ai\";\nimport { z } from \"zod\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Tool's input-schema generic too precise for isolated-declarations; AI SDK validates at runtime\ntype LooseTool = Tool<any, any>;\n\nfunction baseUrl(): string {\n\treturn (process.env.BTC_MEMPOOL_URL ?? \"https://mempool.space\").replace(\n\t\t/\\/$/,\n\t\t\"\",\n\t);\n}\n\nasync function get<T>(path: string): Promise<T> {\n\tconst res = await fetch(`${baseUrl()}${path}`, {\n\t\theaders: { Accept: \"application/json\" },\n\t});\n\tif (!res.ok) {\n\t\tthrow new Error(\n\t\t\t`BTC mempool.space ${path} → ${res.status} ${res.statusText}`,\n\t\t);\n\t}\n\tconst contentType = res.headers.get(\"content-type\") ?? \"\";\n\tif (contentType.includes(\"application/json\")) return res.json() as Promise<T>;\n\treturn res.text() as unknown as Promise<T>;\n}\n\nconst BTC_TXID = z\n\t.string()\n\t.regex(/^[0-9a-fA-F]{64}$/, \"64-character hex BTC txid\");\nexport const BTC_ADDRESS: z.ZodString = z\n\t.string()\n\t.regex(\n\t\t/^(1[a-zA-HJ-NP-Z0-9]{25,34}|3[a-zA-HJ-NP-Z0-9]{25,34}|bc1[a-zA-HJ-NP-Z0-9]{11,71}|tb1[a-zA-HJ-NP-Z0-9]{11,71})$/,\n\t\t{ message: \"Invalid Bitcoin address\" },\n\t);\n\nexport const btcConfirmations: LooseTool = tool({\n\tdescription:\n\t\t\"Number of confirmations for a Bitcoin transaction. Returns { confirmations, confirmed }.\",\n\tinputSchema: z.object({ txid: BTC_TXID }),\n\texecute: async ({ txid }) => {\n\t\tconst tx = await get<{\n\t\t\tstatus: { confirmed: boolean; block_height?: number };\n\t\t}>(`/api/tx/${txid}`);\n\t\tif (!tx.status.confirmed || tx.status.block_height == null) {\n\t\t\treturn { confirmed: false, confirmations: 0 };\n\t\t}\n\t\tconst tip = await get<number>(\"/api/blocks/tip/height\");\n\t\treturn {\n\t\t\tconfirmed: true,\n\t\t\tconfirmations: Math.max(0, tip - tx.status.block_height + 1),\n\t\t\tblockHeight: tx.status.block_height,\n\t\t};\n\t},\n});\n\nexport const btcBalance: LooseTool = tool({\n\tdescription:\n\t\t\"Bitcoin balance for an address, in satoshis. Returns { confirmedSat, unconfirmedSat }.\",\n\tinputSchema: z.object({ address: BTC_ADDRESS }),\n\texecute: async ({ address }) => {\n\t\tconst info = await get<{\n\t\t\tchain_stats: { funded_txo_sum: number; spent_txo_sum: number };\n\t\t\tmempool_stats: { funded_txo_sum: number; spent_txo_sum: number };\n\t\t}>(`/api/address/${encodeURIComponent(address)}`);\n\t\treturn {\n\t\t\tconfirmedSat:\n\t\t\t\tinfo.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum,\n\t\t\tunconfirmedSat:\n\t\t\t\tinfo.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum,\n\t\t};\n\t},\n});\n\nexport const btcUtxos: LooseTool = tool({\n\tdescription:\n\t\t\"List of unspent outputs for a Bitcoin address (truncated to `limit`).\",\n\tinputSchema: z.object({\n\t\taddress: BTC_ADDRESS,\n\t\tlimit: z.number().int().min(1).max(50).default(25),\n\t}),\n\texecute: async ({ address, limit }) => {\n\t\tconst utxos = await get<\n\t\t\tArray<{\n\t\t\t\ttxid: string;\n\t\t\t\tvout: number;\n\t\t\t\tvalue: number;\n\t\t\t\tstatus: { confirmed: boolean; block_height?: number };\n\t\t\t}>\n\t\t>(`/api/address/${encodeURIComponent(address)}/utxo`);\n\t\treturn { utxos: utxos.slice(0, limit) };\n\t},\n});\n\nexport const btcFeeEstimate: LooseTool = tool({\n\tdescription:\n\t\t\"Current Bitcoin fee estimates in sat/vB across priority tiers (fastest, 30-min, hour, economy).\",\n\tinputSchema: z.object({}),\n\texecute: async () => {\n\t\tconst fees = await get<Record<string, number>>(\"/api/v1/fees/recommended\");\n\t\treturn {\n\t\t\tfastestSatVb: fees.fastestFee ?? 0,\n\t\t\thalfHourSatVb: fees.halfHourFee ?? 0,\n\t\t\thourSatVb: fees.hourFee ?? 0,\n\t\t\teconomySatVb: fees.economyFee ?? 0,\n\t\t\tminimumSatVb: fees.minimumFee ?? 0,\n\t\t};\n\t},\n});\n\nexport const btcBlockHeight: LooseTool = tool({\n\tdescription: \"Current Bitcoin chain tip height.\",\n\tinputSchema: z.object({}),\n\texecute: async () => ({\n\t\theight: await get<number>(\"/api/blocks/tip/height\"),\n\t}),\n});\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "A9918581E436E21F64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Tool } from "ai";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
type LooseTool = Tool<any, any>;
|
|
4
|
-
declare const BTC_ADDRESS: z.ZodString;
|
|
5
|
-
declare const btcConfirmations: LooseTool;
|
|
6
|
-
declare const btcBalance: LooseTool;
|
|
7
|
-
declare const btcUtxos: LooseTool;
|
|
8
|
-
declare const btcFeeEstimate: LooseTool;
|
|
9
|
-
declare const btcBlockHeight: LooseTool;
|
|
10
|
-
export { btcUtxos, btcFeeEstimate, btcConfirmations, btcBlockHeight, btcBalance, BTC_ADDRESS };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Tool } from "ai";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
type LooseTool = Tool<any, any>;
|
|
4
|
-
declare const BTC_ADDRESS: z.ZodString;
|
|
5
|
-
declare const btcConfirmations: LooseTool;
|
|
6
|
-
declare const btcBalance: LooseTool;
|
|
7
|
-
declare const btcUtxos: LooseTool;
|
|
8
|
-
declare const btcFeeEstimate: LooseTool;
|
|
9
|
-
declare const btcBlockHeight: LooseTool;
|
|
10
|
-
export { btcUtxos, btcFeeEstimate, btcConfirmations, btcBlockHeight, btcBalance, BTC_ADDRESS };
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
// src/tools/btc/index.ts
|
|
2
|
-
import { tool } from "ai";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
function baseUrl() {
|
|
5
|
-
return (process.env.BTC_MEMPOOL_URL ?? "https://mempool.space").replace(/\/$/, "");
|
|
6
|
-
}
|
|
7
|
-
async function get(path) {
|
|
8
|
-
const res = await fetch(`${baseUrl()}${path}`, {
|
|
9
|
-
headers: { Accept: "application/json" }
|
|
10
|
-
});
|
|
11
|
-
if (!res.ok) {
|
|
12
|
-
throw new Error(`BTC mempool.space ${path} → ${res.status} ${res.statusText}`);
|
|
13
|
-
}
|
|
14
|
-
const contentType = res.headers.get("content-type") ?? "";
|
|
15
|
-
if (contentType.includes("application/json"))
|
|
16
|
-
return res.json();
|
|
17
|
-
return res.text();
|
|
18
|
-
}
|
|
19
|
-
var BTC_TXID = z.string().regex(/^[0-9a-fA-F]{64}$/, "64-character hex BTC txid");
|
|
20
|
-
var BTC_ADDRESS = z.string().regex(/^(1[a-zA-HJ-NP-Z0-9]{25,34}|3[a-zA-HJ-NP-Z0-9]{25,34}|bc1[a-zA-HJ-NP-Z0-9]{11,71}|tb1[a-zA-HJ-NP-Z0-9]{11,71})$/, { message: "Invalid Bitcoin address" });
|
|
21
|
-
var btcConfirmations = tool({
|
|
22
|
-
description: "Number of confirmations for a Bitcoin transaction. Returns { confirmations, confirmed }.",
|
|
23
|
-
inputSchema: z.object({ txid: BTC_TXID }),
|
|
24
|
-
execute: async ({ txid }) => {
|
|
25
|
-
const tx = await get(`/api/tx/${txid}`);
|
|
26
|
-
if (!tx.status.confirmed || tx.status.block_height == null) {
|
|
27
|
-
return { confirmed: false, confirmations: 0 };
|
|
28
|
-
}
|
|
29
|
-
const tip = await get("/api/blocks/tip/height");
|
|
30
|
-
return {
|
|
31
|
-
confirmed: true,
|
|
32
|
-
confirmations: Math.max(0, tip - tx.status.block_height + 1),
|
|
33
|
-
blockHeight: tx.status.block_height
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
var btcBalance = tool({
|
|
38
|
-
description: "Bitcoin balance for an address, in satoshis. Returns { confirmedSat, unconfirmedSat }.",
|
|
39
|
-
inputSchema: z.object({ address: BTC_ADDRESS }),
|
|
40
|
-
execute: async ({ address }) => {
|
|
41
|
-
const info = await get(`/api/address/${encodeURIComponent(address)}`);
|
|
42
|
-
return {
|
|
43
|
-
confirmedSat: info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum,
|
|
44
|
-
unconfirmedSat: info.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
var btcUtxos = tool({
|
|
49
|
-
description: "List of unspent outputs for a Bitcoin address (truncated to `limit`).",
|
|
50
|
-
inputSchema: z.object({
|
|
51
|
-
address: BTC_ADDRESS,
|
|
52
|
-
limit: z.number().int().min(1).max(50).default(25)
|
|
53
|
-
}),
|
|
54
|
-
execute: async ({ address, limit }) => {
|
|
55
|
-
const utxos = await get(`/api/address/${encodeURIComponent(address)}/utxo`);
|
|
56
|
-
return { utxos: utxos.slice(0, limit) };
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
var btcFeeEstimate = tool({
|
|
60
|
-
description: "Current Bitcoin fee estimates in sat/vB across priority tiers (fastest, 30-min, hour, economy).",
|
|
61
|
-
inputSchema: z.object({}),
|
|
62
|
-
execute: async () => {
|
|
63
|
-
const fees = await get("/api/v1/fees/recommended");
|
|
64
|
-
return {
|
|
65
|
-
fastestSatVb: fees.fastestFee ?? 0,
|
|
66
|
-
halfHourSatVb: fees.halfHourFee ?? 0,
|
|
67
|
-
hourSatVb: fees.hourFee ?? 0,
|
|
68
|
-
economySatVb: fees.economyFee ?? 0,
|
|
69
|
-
minimumSatVb: fees.minimumFee ?? 0
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
var btcBlockHeight = tool({
|
|
74
|
-
description: "Current Bitcoin chain tip height.",
|
|
75
|
-
inputSchema: z.object({}),
|
|
76
|
-
execute: async () => ({
|
|
77
|
-
height: await get("/api/blocks/tip/height")
|
|
78
|
-
})
|
|
79
|
-
});
|
|
80
|
-
export {
|
|
81
|
-
btcUtxos,
|
|
82
|
-
btcFeeEstimate,
|
|
83
|
-
btcConfirmations,
|
|
84
|
-
btcBlockHeight,
|
|
85
|
-
btcBalance,
|
|
86
|
-
BTC_ADDRESS
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
//# debugId=E811F99F534F2FE364756E2164756E21
|
|
90
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/tools/btc/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Bitcoin read tools for AI SDK tool calls. Useful for sBTC peg-in/peg-out\n * flows, BTC-collateralized lending, and anywhere a Stacks contract's\n * behaviour depends on BTC state.\n *\n * @deprecated Point your agent at `@secondlayer/mcp` instead; this entry\n * stays importable until the next major but gets no new tools. Installing\n * it means installing `ai` and `zod` yourself: both are optional peers of\n * the package, not dependencies.\n *\n * Backed by mempool.space by default. Swap endpoints by setting\n * `BTC_MEMPOOL_URL` in the caller's env. Reads only, no BTC writes.\n *\n * import { generateText } from \"ai\"\n * import { btcConfirmations, btcBalance } from \"@secondlayer/stacks/tools/btc\"\n * await generateText({\n * model: anthropic(\"claude-sonnet-4-6\"),\n * tools: { btcConfirmations, btcBalance },\n * prompt: \"…\",\n * })\n */\n\nimport { type Tool, tool } from \"ai\";\nimport { z } from \"zod\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Tool's input-schema generic too precise for isolated-declarations; AI SDK validates at runtime\ntype LooseTool = Tool<any, any>;\n\nfunction baseUrl(): string {\n\treturn (process.env.BTC_MEMPOOL_URL ?? \"https://mempool.space\").replace(\n\t\t/\\/$/,\n\t\t\"\",\n\t);\n}\n\nasync function get<T>(path: string): Promise<T> {\n\tconst res = await fetch(`${baseUrl()}${path}`, {\n\t\theaders: { Accept: \"application/json\" },\n\t});\n\tif (!res.ok) {\n\t\tthrow new Error(\n\t\t\t`BTC mempool.space ${path} → ${res.status} ${res.statusText}`,\n\t\t);\n\t}\n\tconst contentType = res.headers.get(\"content-type\") ?? \"\";\n\tif (contentType.includes(\"application/json\")) return res.json() as Promise<T>;\n\treturn res.text() as unknown as Promise<T>;\n}\n\nconst BTC_TXID = z\n\t.string()\n\t.regex(/^[0-9a-fA-F]{64}$/, \"64-character hex BTC txid\");\nexport const BTC_ADDRESS: z.ZodString = z\n\t.string()\n\t.regex(\n\t\t/^(1[a-zA-HJ-NP-Z0-9]{25,34}|3[a-zA-HJ-NP-Z0-9]{25,34}|bc1[a-zA-HJ-NP-Z0-9]{11,71}|tb1[a-zA-HJ-NP-Z0-9]{11,71})$/,\n\t\t{ message: \"Invalid Bitcoin address\" },\n\t);\n\nexport const btcConfirmations: LooseTool = tool({\n\tdescription:\n\t\t\"Number of confirmations for a Bitcoin transaction. Returns { confirmations, confirmed }.\",\n\tinputSchema: z.object({ txid: BTC_TXID }),\n\texecute: async ({ txid }) => {\n\t\tconst tx = await get<{\n\t\t\tstatus: { confirmed: boolean; block_height?: number };\n\t\t}>(`/api/tx/${txid}`);\n\t\tif (!tx.status.confirmed || tx.status.block_height == null) {\n\t\t\treturn { confirmed: false, confirmations: 0 };\n\t\t}\n\t\tconst tip = await get<number>(\"/api/blocks/tip/height\");\n\t\treturn {\n\t\t\tconfirmed: true,\n\t\t\tconfirmations: Math.max(0, tip - tx.status.block_height + 1),\n\t\t\tblockHeight: tx.status.block_height,\n\t\t};\n\t},\n});\n\nexport const btcBalance: LooseTool = tool({\n\tdescription:\n\t\t\"Bitcoin balance for an address, in satoshis. Returns { confirmedSat, unconfirmedSat }.\",\n\tinputSchema: z.object({ address: BTC_ADDRESS }),\n\texecute: async ({ address }) => {\n\t\tconst info = await get<{\n\t\t\tchain_stats: { funded_txo_sum: number; spent_txo_sum: number };\n\t\t\tmempool_stats: { funded_txo_sum: number; spent_txo_sum: number };\n\t\t}>(`/api/address/${encodeURIComponent(address)}`);\n\t\treturn {\n\t\t\tconfirmedSat:\n\t\t\t\tinfo.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum,\n\t\t\tunconfirmedSat:\n\t\t\t\tinfo.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum,\n\t\t};\n\t},\n});\n\nexport const btcUtxos: LooseTool = tool({\n\tdescription:\n\t\t\"List of unspent outputs for a Bitcoin address (truncated to `limit`).\",\n\tinputSchema: z.object({\n\t\taddress: BTC_ADDRESS,\n\t\tlimit: z.number().int().min(1).max(50).default(25),\n\t}),\n\texecute: async ({ address, limit }) => {\n\t\tconst utxos = await get<\n\t\t\tArray<{\n\t\t\t\ttxid: string;\n\t\t\t\tvout: number;\n\t\t\t\tvalue: number;\n\t\t\t\tstatus: { confirmed: boolean; block_height?: number };\n\t\t\t}>\n\t\t>(`/api/address/${encodeURIComponent(address)}/utxo`);\n\t\treturn { utxos: utxos.slice(0, limit) };\n\t},\n});\n\nexport const btcFeeEstimate: LooseTool = tool({\n\tdescription:\n\t\t\"Current Bitcoin fee estimates in sat/vB across priority tiers (fastest, 30-min, hour, economy).\",\n\tinputSchema: z.object({}),\n\texecute: async () => {\n\t\tconst fees = await get<Record<string, number>>(\"/api/v1/fees/recommended\");\n\t\treturn {\n\t\t\tfastestSatVb: fees.fastestFee ?? 0,\n\t\t\thalfHourSatVb: fees.halfHourFee ?? 0,\n\t\t\thourSatVb: fees.hourFee ?? 0,\n\t\t\teconomySatVb: fees.economyFee ?? 0,\n\t\t\tminimumSatVb: fees.minimumFee ?? 0,\n\t\t};\n\t},\n});\n\nexport const btcBlockHeight: LooseTool = tool({\n\tdescription: \"Current Bitcoin chain tip height.\",\n\tinputSchema: z.object({}),\n\texecute: async () => ({\n\t\theight: await get<number>(\"/api/blocks/tip/height\"),\n\t}),\n});\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";AAsBA;AACA;AAKA,SAAS,OAAO,GAAW;AAAA,EAC1B,QAAQ,QAAQ,IAAI,mBAAmB,yBAAyB,QAC/D,OACA,EACD;AAAA;AAGD,eAAe,GAAM,CAAC,MAA0B;AAAA,EAC/C,MAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ;AAAA,IAC9C,SAAS,EAAE,QAAQ,mBAAmB;AAAA,EACvC,CAAC;AAAA,EACD,IAAI,CAAC,IAAI,IAAI;AAAA,IACZ,MAAM,IAAI,MACT,qBAAqB,UAAS,IAAI,UAAU,IAAI,YACjD;AAAA,EACD;AAAA,EACA,MAAM,cAAc,IAAI,QAAQ,IAAI,cAAc,KAAK;AAAA,EACvD,IAAI,YAAY,SAAS,kBAAkB;AAAA,IAAG,OAAO,IAAI,KAAK;AAAA,EAC9D,OAAO,IAAI,KAAK;AAAA;AAGjB,IAAM,WAAW,EACf,OAAO,EACP,MAAM,qBAAqB,2BAA2B;AACjD,IAAM,cAA2B,EACtC,OAAO,EACP,MACA,mHACA,EAAE,SAAS,0BAA0B,CACtC;AAEM,IAAM,mBAA8B,KAAK;AAAA,EAC/C,aACC;AAAA,EACD,aAAa,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAAA,EACxC,SAAS,SAAS,WAAW;AAAA,IAC5B,MAAM,KAAK,MAAM,IAEd,WAAW,MAAM;AAAA,IACpB,IAAI,CAAC,GAAG,OAAO,aAAa,GAAG,OAAO,gBAAgB,MAAM;AAAA,MAC3D,OAAO,EAAE,WAAW,OAAO,eAAe,EAAE;AAAA,IAC7C;AAAA,IACA,MAAM,MAAM,MAAM,IAAY,wBAAwB;AAAA,IACtD,OAAO;AAAA,MACN,WAAW;AAAA,MACX,eAAe,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO,eAAe,CAAC;AAAA,MAC3D,aAAa,GAAG,OAAO;AAAA,IACxB;AAAA;AAEF,CAAC;AAEM,IAAM,aAAwB,KAAK;AAAA,EACzC,aACC;AAAA,EACD,aAAa,EAAE,OAAO,EAAE,SAAS,YAAY,CAAC;AAAA,EAC9C,SAAS,SAAS,cAAc;AAAA,IAC/B,MAAM,OAAO,MAAM,IAGhB,gBAAgB,mBAAmB,OAAO,GAAG;AAAA,IAChD,OAAO;AAAA,MACN,cACC,KAAK,YAAY,iBAAiB,KAAK,YAAY;AAAA,MACpD,gBACC,KAAK,cAAc,iBAAiB,KAAK,cAAc;AAAA,IACzD;AAAA;AAEF,CAAC;AAEM,IAAM,WAAsB,KAAK;AAAA,EACvC,aACC;AAAA,EACD,aAAa,EAAE,OAAO;AAAA,IACrB,SAAS;AAAA,IACT,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EAClD,CAAC;AAAA,EACD,SAAS,SAAS,SAAS,YAAY;AAAA,IACtC,MAAM,QAAQ,MAAM,IAOlB,gBAAgB,mBAAmB,OAAO,QAAQ;AAAA,IACpD,OAAO,EAAE,OAAO,MAAM,MAAM,GAAG,KAAK,EAAE;AAAA;AAExC,CAAC;AAEM,IAAM,iBAA4B,KAAK;AAAA,EAC7C,aACC;AAAA,EACD,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,EACxB,SAAS,YAAY;AAAA,IACpB,MAAM,OAAO,MAAM,IAA4B,0BAA0B;AAAA,IACzE,OAAO;AAAA,MACN,cAAc,KAAK,cAAc;AAAA,MACjC,eAAe,KAAK,eAAe;AAAA,MACnC,WAAW,KAAK,WAAW;AAAA,MAC3B,cAAc,KAAK,cAAc;AAAA,MACjC,cAAc,KAAK,cAAc;AAAA,IAClC;AAAA;AAEF,CAAC;AAEM,IAAM,iBAA4B,KAAK;AAAA,EAC7C,aAAa;AAAA,EACb,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,EACxB,SAAS,aAAa;AAAA,IACrB,QAAQ,MAAM,IAAY,wBAAwB;AAAA,EACnD;AACD,CAAC;",
|
|
8
|
-
"debugId": "E811F99F534F2FE364756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|