@lombard.finance/sdk-agent 0.1.0 → 0.2.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 +25 -13
- package/dist/index.cjs +15 -14
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +95 -88
- package/dist/langchain.js +1 -1
- package/dist/prompt.d.ts.map +1 -1
- package/dist/schemas.d.ts +16 -8
- package/dist/schemas.d.ts.map +1 -1
- package/dist/tools.cjs +5 -5
- package/dist/tools.d.ts +17 -14
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +755 -567
- package/dist/validation.d.ts +12 -6
- package/dist/validation.d.ts.map +1 -1
- package/dist/vercel.js +1 -1
- package/package.json +1 -1
package/dist/tools.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { BTCE_VAULT_CONTRACTS as
|
|
2
|
-
import { parseUnits as
|
|
3
|
-
import { baseSepolia as
|
|
1
|
+
import { BTCE_VAULT_CONTRACTS as Me, getLbtcContractAddresses as R, Env as h, ChainId as C, MIN_STAKE_AMOUNT_BTC as ie, MIN_REDEEM_AMOUNT_BTC as B, BTC_DECIMALS as be, makePublicClient as ee, Token as S, getExchangeRatio as Re, getLBTCExchangeRate as De, fromSatoshi as ce, getDepositsByAddress as fe, getDepositStatus as ye, getDepositStatusDisplay as ge, getUnstakesByAddress as Fe, getEarnApy as Ne, getEarnTVL as Ue, getDepositBtcAddress as qe, requiresAutoMintFee as Oe, getNetworkFeeSignature as Ve, getEarnWithdrawals as te, getApy as je, getEarnPosition as He, getPointsByAddress as ze, getPositionsSummary as Ze, getTokenContractInfo as Ye } from "@lombard.finance/sdk";
|
|
2
|
+
import { parseUnits as ae, encodeFunctionData as A, erc20Abi as we, formatUnits as v } from "viem";
|
|
3
|
+
import { baseSepolia as de, base as le, sepolia as pe, mainnet as ue } from "viem/chains";
|
|
4
4
|
import { z as c } from "zod";
|
|
5
|
-
import { zodToJsonSchema as
|
|
6
|
-
function
|
|
5
|
+
import { zodToJsonSchema as We } from "zod-to-json-schema";
|
|
6
|
+
function Ge() {
|
|
7
7
|
return {
|
|
8
|
-
...R(
|
|
9
|
-
...R(
|
|
8
|
+
...R(h.testnet),
|
|
9
|
+
...R(h.prod)
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
const
|
|
12
|
+
const E = [
|
|
13
13
|
{
|
|
14
14
|
symbol: "LBTC",
|
|
15
15
|
aliases: ["Lombard BTC", "Lombard staked Bitcoin", "lbtc"],
|
|
@@ -18,7 +18,7 @@ const L = [
|
|
|
18
18
|
isLombardIssued: !0,
|
|
19
19
|
isYieldBearing: !0,
|
|
20
20
|
decimals: 8,
|
|
21
|
-
addresses:
|
|
21
|
+
addresses: Ge()
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
symbol: "BTC.b",
|
|
@@ -39,31 +39,31 @@ const L = [
|
|
|
39
39
|
isLombardIssued: !0,
|
|
40
40
|
isYieldBearing: !0,
|
|
41
41
|
decimals: 8,
|
|
42
|
-
addresses: { ...
|
|
42
|
+
addresses: { ...Me },
|
|
43
43
|
notes: "BTCe wraps the underlying Veda share (LBTCv) 1:1 today; convertToAssets() is the authoritative conversion if the ratio ever changes."
|
|
44
44
|
}
|
|
45
45
|
];
|
|
46
|
-
function
|
|
46
|
+
function Ke(t) {
|
|
47
47
|
if (!t) return;
|
|
48
48
|
const e = t.trim().toLowerCase();
|
|
49
|
-
for (const a of
|
|
49
|
+
for (const a of E)
|
|
50
50
|
if (a.symbol.toLowerCase() === e || a.aliases.some((s) => s.toLowerCase() === e)) return a;
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function Je(t, e) {
|
|
53
53
|
if (!e) return;
|
|
54
54
|
const a = e.toLowerCase();
|
|
55
|
-
for (const s of
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
55
|
+
for (const s of E) {
|
|
56
|
+
const o = s.addresses[t];
|
|
57
|
+
if (o && o.toLowerCase() === a) return s;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
function
|
|
60
|
+
function Xe() {
|
|
61
61
|
return [
|
|
62
62
|
"# Lombard asset glossary",
|
|
63
63
|
"",
|
|
64
64
|
"These are the canonical Lombard-related assets. Use these names verbatim. If a user asks about an asset not listed here, call get_token_info to look it up before saying you don't know.",
|
|
65
65
|
"",
|
|
66
|
-
...
|
|
66
|
+
...E.map((e) => {
|
|
67
67
|
const a = [
|
|
68
68
|
e.isLombardIssued ? "Lombard-issued" : "third-party",
|
|
69
69
|
e.isYieldBearing ? "yield-bearing" : "not yield-bearing"
|
|
@@ -73,60 +73,64 @@ function Ze() {
|
|
|
73
73
|
].join(`
|
|
74
74
|
`);
|
|
75
75
|
}
|
|
76
|
-
const
|
|
77
|
-
[
|
|
78
|
-
[
|
|
79
|
-
[
|
|
80
|
-
[
|
|
76
|
+
const _a = Xe(), he = {
|
|
77
|
+
[ue.id]: { chain: ue, chainId: C.ethereum, env: h.prod, name: "Ethereum" },
|
|
78
|
+
[pe.id]: { chain: pe, chainId: C.sepolia, env: h.testnet, name: "Sepolia" },
|
|
79
|
+
[le.id]: { chain: le, chainId: C.base, env: h.prod, name: "Base" },
|
|
80
|
+
[de.id]: { chain: de, chainId: C.baseSepoliaTestnet, env: h.testnet, name: "Base Sepolia" }
|
|
81
81
|
};
|
|
82
|
-
function
|
|
83
|
-
const e =
|
|
82
|
+
function p(t) {
|
|
83
|
+
const e = he[t];
|
|
84
84
|
if (!e) {
|
|
85
|
-
const a = Object.keys(
|
|
85
|
+
const a = Object.keys(he).join(", ");
|
|
86
86
|
throw new Error(`Unsupported chain ID: ${t}. Supported: ${a}`);
|
|
87
87
|
}
|
|
88
88
|
return e;
|
|
89
89
|
}
|
|
90
|
-
const
|
|
90
|
+
const b = c.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address"), g = c.string().regex(/^\d+(\.\d+)?$/, "Must be a numeric string").refine(
|
|
91
91
|
(t) => parseFloat(t) > 0 && parseFloat(t) < 1e3,
|
|
92
92
|
"Amount must be positive and under 1000"
|
|
93
|
-
),
|
|
94
|
-
address:
|
|
95
|
-
chainId:
|
|
96
|
-
}), P = c.object({
|
|
97
|
-
chainId: c.number().optional().describe("Chain ID for environment resolution (optional)")
|
|
93
|
+
), Qe = "Chain ID. Default to the user's connected chain (provided in your wallet context) unless they specify a different one. Supported: 1=Ethereum, 11155111=Sepolia, 8453=Base, 84532=Base Sepolia.", y = c.number().describe(Qe), u = c.object({
|
|
94
|
+
address: b.describe("EVM wallet address (0x...)"),
|
|
95
|
+
chainId: y
|
|
98
96
|
}), D = c.object({
|
|
99
|
-
|
|
100
|
-
chainId: b
|
|
97
|
+
chainId: c.number().optional().describe("Chain ID for environment resolution (optional)")
|
|
101
98
|
}), F = c.object({
|
|
102
|
-
amount:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
amount: g.describe("Amount of BTC.b to stake (e.g. '0.1')"),
|
|
100
|
+
chainId: y
|
|
101
|
+
}), N = c.object({
|
|
102
|
+
amount: g.describe("Amount of LBTC to convert to native BTC"),
|
|
103
|
+
recipient: c.string().describe(
|
|
104
|
+
"Bitcoin destination address. MUST be a valid Bitcoin address for the network (bc1.../1.../3... mainnet; tb1.../m.../n.../2... testnet). Ask the user for this explicitly, never infer from prior context."
|
|
105
|
+
),
|
|
106
|
+
chainId: y
|
|
107
|
+
}), U = c.object({
|
|
108
|
+
amount: g.describe("Amount of LBTC to convert to BTC.b on the same chain"),
|
|
109
|
+
chainId: y
|
|
110
|
+
}), q = u, O = c.object({
|
|
107
111
|
chainId: c.number().optional().describe(
|
|
108
112
|
"Chain ID to filter strategies (optional, returns all if omitted)"
|
|
109
113
|
)
|
|
110
|
-
}),
|
|
111
|
-
amount:
|
|
112
|
-
chainId:
|
|
113
|
-
}),
|
|
114
|
-
amount:
|
|
115
|
-
address:
|
|
114
|
+
}), V = u, j = c.object({
|
|
115
|
+
amount: g.describe("Amount of LBTC to deploy"),
|
|
116
|
+
chainId: y
|
|
117
|
+
}), Be = c.object({}), H = c.object({
|
|
118
|
+
amount: g.describe("Amount of vault shares to withdraw"),
|
|
119
|
+
address: b.describe(
|
|
116
120
|
"EVM wallet address requesting the withdrawal. Used to check for an existing active withdrawal (only one is allowed per user per vault)."
|
|
117
121
|
),
|
|
118
|
-
chainId:
|
|
119
|
-
}),
|
|
122
|
+
chainId: y
|
|
123
|
+
}), z = c.object({
|
|
120
124
|
depositTxHash: c.string().min(1).describe("The BTC deposit transaction hash to claim"),
|
|
121
|
-
address:
|
|
122
|
-
chainId:
|
|
123
|
-
}),
|
|
124
|
-
amount:
|
|
125
|
+
address: b.describe("EVM wallet address that owns the deposit"),
|
|
126
|
+
chainId: y
|
|
127
|
+
}), Z = c.object({
|
|
128
|
+
amount: g.describe("Amount of BTC.b to redeem for native BTC"),
|
|
125
129
|
recipient: c.string().describe(
|
|
126
130
|
"Bitcoin destination address for the redeemed BTC. MUST be a valid Bitcoin address for the network (bc1.../1.../3... mainnet; tb1.../m.../n.../2... testnet). Ask the user for this explicitly — never infer from prior context."
|
|
127
131
|
),
|
|
128
|
-
chainId:
|
|
129
|
-
}),
|
|
132
|
+
chainId: y
|
|
133
|
+
}), Te = c.object({
|
|
130
134
|
query: c.string().optional().describe(
|
|
131
135
|
"Free-text token name or symbol (e.g. 'BTCe', 'LBTC', 'Bitcoin Earn vault share')."
|
|
132
136
|
),
|
|
@@ -134,82 +138,78 @@ const f = c.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address"), y = c.
|
|
|
134
138
|
"Optional contract address (0x...). When provided, chainId is required too."
|
|
135
139
|
),
|
|
136
140
|
chainId: c.number().optional().describe("Chain ID for an address-based lookup.")
|
|
137
|
-
}),
|
|
138
|
-
address:
|
|
141
|
+
}), Y = c.object({
|
|
142
|
+
address: b.describe(
|
|
139
143
|
"EVM wallet address that owns the active withdrawal being cancelled."
|
|
140
144
|
),
|
|
141
|
-
chainId:
|
|
142
|
-
}),
|
|
143
|
-
address:
|
|
144
|
-
}),
|
|
145
|
+
chainId: y
|
|
146
|
+
}), k = c.object({
|
|
147
|
+
address: b.describe("EVM wallet address (0x...)")
|
|
148
|
+
}), W = c.object({
|
|
145
149
|
category: c.string().optional().describe(
|
|
146
150
|
"Filter by category: automated-strategy, borrow-stables, looping, dex-lp, other"
|
|
147
151
|
),
|
|
148
152
|
chain: c.string().optional().describe("Filter by chain (e.g. Ethereum, Base, Solana)"),
|
|
149
153
|
protocol: c.string().optional().describe("Filter by protocol (e.g. Morpho, Aave, Uniswap)")
|
|
150
|
-
}),
|
|
151
|
-
tokenAddress:
|
|
154
|
+
}), G = c.object({
|
|
155
|
+
tokenAddress: b.describe(
|
|
152
156
|
"ERC-20 token contract address (0x...). Get this from tool results like get_morpho_lbtc_markets, not from memory."
|
|
153
157
|
),
|
|
154
|
-
address:
|
|
155
|
-
chainId:
|
|
156
|
-
}),
|
|
158
|
+
address: b.describe("EVM wallet address to check balance for"),
|
|
159
|
+
chainId: y
|
|
160
|
+
}), ve = c.object({}), $ = c.string().regex(
|
|
157
161
|
/^0x[a-fA-F0-9]{64}$/,
|
|
158
162
|
"Invalid Morpho market ID (must be 0x + 64 hex chars)"
|
|
159
|
-
).describe("Morpho Blue market ID (from get_morpho_lbtc_markets)"),
|
|
163
|
+
).describe("Morpho Blue market ID (from get_morpho_lbtc_markets)"), K = c.object({
|
|
160
164
|
marketId: $,
|
|
161
|
-
amount:
|
|
165
|
+
amount: g.describe(
|
|
162
166
|
"Amount of LBTC to supply as collateral (e.g. '0.1')"
|
|
163
167
|
),
|
|
164
|
-
address:
|
|
165
|
-
}),
|
|
168
|
+
address: b.describe("EVM wallet address supplying the collateral")
|
|
169
|
+
}), J = c.object({
|
|
166
170
|
marketId: $,
|
|
167
|
-
amount:
|
|
171
|
+
amount: g.describe(
|
|
168
172
|
"Amount of loan asset to borrow (e.g. '100' for 100 USDC)"
|
|
169
173
|
),
|
|
170
|
-
address:
|
|
171
|
-
}),
|
|
174
|
+
address: b.describe("EVM wallet address borrowing the asset")
|
|
175
|
+
}), X = c.object({
|
|
172
176
|
marketId: $,
|
|
173
|
-
amount:
|
|
177
|
+
amount: g.describe(
|
|
174
178
|
"Amount of loan asset to repay (e.g. '1' for 1 USDC)"
|
|
175
179
|
),
|
|
176
|
-
address:
|
|
177
|
-
}),
|
|
180
|
+
address: b.describe("EVM wallet address repaying the debt")
|
|
181
|
+
}), Q = c.object({
|
|
178
182
|
marketId: $,
|
|
179
|
-
address:
|
|
183
|
+
address: b.describe("EVM wallet address to check position for")
|
|
180
184
|
});
|
|
181
185
|
function l(t) {
|
|
182
|
-
return
|
|
186
|
+
return We(t, { target: "openAi" });
|
|
183
187
|
}
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
W
|
|
188
|
-
), ht = l(K), mt = l(G), ft = l(J), bt = /* @__PURE__ */ new Set([
|
|
188
|
+
const et = l(Y), Ce = l(k), w = l(u), tt = l(D), at = l(F), st = l(N), rt = l(U), ot = l(q), nt = l(O), it = l(V), ct = l(j), dt = l(Be), lt = l(H), pt = l(z), ut = l(W), ht = l(G), mt = l(Te), bt = l(Z), ft = l(ve), yt = l(
|
|
189
|
+
K
|
|
190
|
+
), gt = l(J), wt = l(X), Bt = l(Q), Tt = /* @__PURE__ */ new Set([
|
|
189
191
|
11155111,
|
|
190
192
|
// ethereum sepolia
|
|
191
193
|
84532
|
|
192
194
|
// base sepolia
|
|
193
|
-
]),
|
|
194
|
-
function
|
|
195
|
+
]), vt = /^(bc1[a-z0-9]{39,87}|[13][a-km-zA-HJ-NP-Z1-9]{25,34})$/, Ct = /^(tb1[a-z0-9]{39,87}|[mn2][a-km-zA-HJ-NP-Z1-9]{25,34})$/;
|
|
196
|
+
function Ae(t, e) {
|
|
195
197
|
if (typeof t != "string") return !1;
|
|
196
198
|
const a = t.trim();
|
|
197
|
-
return a.length === 0 ? !1 :
|
|
199
|
+
return a.length === 0 ? !1 : Tt.has(e) ? Ct.test(a) : vt.test(a);
|
|
198
200
|
}
|
|
199
|
-
function
|
|
201
|
+
function _(t) {
|
|
200
202
|
if (typeof t != "string" || !/^\d+(\.\d+)?$/.test(t)) return !1;
|
|
201
203
|
const e = Number(t);
|
|
202
204
|
return Number.isFinite(e) && e > 0;
|
|
203
205
|
}
|
|
204
|
-
function
|
|
206
|
+
function At(t) {
|
|
205
207
|
const e = [], a = [];
|
|
206
|
-
if (
|
|
207
|
-
`amount ${t.amount} is below the protocol minimum of ${
|
|
208
|
-
) : a.push(
|
|
209
|
-
"amount must be a positive numeric string (e.g. '0.5')"
|
|
210
|
-
), t.outputAsset !== "BTC" && t.outputAsset !== "BTCb" && a.push("outputAsset must be either 'BTC' or 'BTCb'"), t.outputAsset === "BTC" && (typeof t.recipient != "string" || t.recipient.length === 0 ? e.push("recipient") : ve(t.recipient, t.chainId) || a.push(
|
|
208
|
+
if (_(t.amount) ? Number(t.amount) < B && a.push(
|
|
209
|
+
`amount ${t.amount} is below the protocol minimum of ${B} LBTC. Network fees may push the practical minimum higher; ask the user to confirm a value at or above ${B}.`
|
|
210
|
+
) : a.push("amount must be a positive numeric string (e.g. '0.5')"), typeof t.recipient != "string" || t.recipient.length === 0 ? e.push("recipient") : Ae(t.recipient, t.chainId) || a.push(
|
|
211
211
|
"recipient is not a valid Bitcoin address for this network. Mainnet: bc1.../1.../3...; Sepolia/testnet: tb1.../m.../n.../2..."
|
|
212
|
-
)
|
|
212
|
+
), e.length === 0 && a.length === 0)
|
|
213
213
|
return { valid: !0 };
|
|
214
214
|
const s = [];
|
|
215
215
|
return e.length > 0 && s.push(
|
|
@@ -223,10 +223,10 @@ function wt(t) {
|
|
|
223
223
|
note: s.join(" ")
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
|
-
function
|
|
226
|
+
function kt(t) {
|
|
227
227
|
const e = [];
|
|
228
|
-
return
|
|
229
|
-
`amount ${t.amount} is below the protocol minimum of ${
|
|
228
|
+
return _(t.amount) ? Number(t.amount) < B && e.push(
|
|
229
|
+
`amount ${t.amount} is below the protocol minimum of ${B} LBTC.`
|
|
230
230
|
) : e.push("amount must be a positive numeric string (e.g. '0.5')"), e.length === 0 ? { valid: !0 } : {
|
|
231
231
|
valid: !1,
|
|
232
232
|
missing: [],
|
|
@@ -234,11 +234,22 @@ function Bt(t) {
|
|
|
234
234
|
note: "Surface the listed errors to the user and re-prompt; do not retry the tool with the same arguments."
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
|
-
function
|
|
237
|
+
function _t(t) {
|
|
238
|
+
const e = [];
|
|
239
|
+
return _(t.amount) ? Number(t.amount) < ie && e.push(
|
|
240
|
+
`amount ${t.amount} is below the protocol minimum of ${ie} BTC.`
|
|
241
|
+
) : e.push("amount must be a positive numeric string (e.g. '0.5')"), e.length === 0 ? { valid: !0 } : {
|
|
242
|
+
valid: !1,
|
|
243
|
+
missing: [],
|
|
244
|
+
errors: e,
|
|
245
|
+
note: "Surface the listed errors to the user and re-prompt; do not retry the tool with the same arguments."
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function Lt(t) {
|
|
238
249
|
const e = [], a = [];
|
|
239
|
-
if (
|
|
240
|
-
`amount ${t.amount} is below the protocol minimum of ${
|
|
241
|
-
) : a.push("amount must be a positive numeric string (e.g. '0.001')"), typeof t.recipient != "string" || t.recipient.length === 0 ? e.push("recipient") :
|
|
250
|
+
if (_(t.amount) ? Number(t.amount) < B && a.push(
|
|
251
|
+
`amount ${t.amount} is below the protocol minimum of ${B} BTC. Network fees may push the practical minimum higher.`
|
|
252
|
+
) : a.push("amount must be a positive numeric string (e.g. '0.001')"), typeof t.recipient != "string" || t.recipient.length === 0 ? e.push("recipient") : Ae(t.recipient, t.chainId) || a.push(
|
|
242
253
|
"recipient is not a valid Bitcoin address for this network. Mainnet: bc1.../1.../3...; Sepolia/testnet: tb1.../m.../n.../2..."
|
|
243
254
|
), e.length === 0 && a.length === 0) return { valid: !0 };
|
|
244
255
|
const s = [];
|
|
@@ -253,19 +264,19 @@ function vt(t) {
|
|
|
253
264
|
note: s.join(" ")
|
|
254
265
|
};
|
|
255
266
|
}
|
|
256
|
-
function
|
|
257
|
-
return
|
|
267
|
+
function ke(t) {
|
|
268
|
+
return _(t.amount) ? { valid: !0 } : {
|
|
258
269
|
valid: !1,
|
|
259
270
|
missing: [],
|
|
260
271
|
errors: ["amount must be a positive numeric string (e.g. '0.5')"],
|
|
261
272
|
note: "Surface the listed errors to the user and re-prompt; do not retry the tool with the same arguments."
|
|
262
273
|
};
|
|
263
274
|
}
|
|
264
|
-
function
|
|
275
|
+
function St(t, e) {
|
|
265
276
|
const a = (e == null ? void 0 : e.mainnet) ?? process.env.LOMBARD_PARTNER_ID ?? "lombardtest1", s = (e == null ? void 0 : e.testnet) ?? process.env.LOMBARD_TESTNET_PARTNER_ID ?? "test1";
|
|
266
|
-
return t ===
|
|
277
|
+
return t === h.testnet ? s : a;
|
|
267
278
|
}
|
|
268
|
-
const
|
|
279
|
+
const T = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(h.prod)[C.ethereum], It = "https://api.morpho.org/graphql", xt = 1e4, se = {
|
|
269
280
|
name: "marketParams",
|
|
270
281
|
type: "tuple",
|
|
271
282
|
components: [
|
|
@@ -275,26 +286,26 @@ const w = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(m.prod)[T.ethereum
|
|
|
275
286
|
{ name: "irm", type: "address" },
|
|
276
287
|
{ name: "lltv", type: "uint256" }
|
|
277
288
|
]
|
|
278
|
-
},
|
|
289
|
+
}, Et = [
|
|
279
290
|
{
|
|
280
291
|
name: "supplyCollateral",
|
|
281
292
|
type: "function",
|
|
282
293
|
stateMutability: "nonpayable",
|
|
283
294
|
inputs: [
|
|
284
|
-
|
|
295
|
+
se,
|
|
285
296
|
{ name: "assets", type: "uint256" },
|
|
286
297
|
{ name: "onBehalf", type: "address" },
|
|
287
298
|
{ name: "data", type: "bytes" }
|
|
288
299
|
],
|
|
289
300
|
outputs: []
|
|
290
301
|
}
|
|
291
|
-
],
|
|
302
|
+
], $t = [
|
|
292
303
|
{
|
|
293
304
|
name: "borrow",
|
|
294
305
|
type: "function",
|
|
295
306
|
stateMutability: "nonpayable",
|
|
296
307
|
inputs: [
|
|
297
|
-
|
|
308
|
+
se,
|
|
298
309
|
{ name: "assets", type: "uint256" },
|
|
299
310
|
{ name: "shares", type: "uint256" },
|
|
300
311
|
{ name: "onBehalf", type: "address" },
|
|
@@ -305,7 +316,7 @@ const w = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(m.prod)[T.ethereum
|
|
|
305
316
|
{ name: "sharesBorrowed", type: "uint256" }
|
|
306
317
|
]
|
|
307
318
|
}
|
|
308
|
-
],
|
|
319
|
+
], me = [
|
|
309
320
|
{
|
|
310
321
|
name: "position",
|
|
311
322
|
type: "function",
|
|
@@ -334,13 +345,13 @@ const w = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(m.prod)[T.ethereum
|
|
|
334
345
|
{ name: "fee", type: "uint128" }
|
|
335
346
|
]
|
|
336
347
|
}
|
|
337
|
-
],
|
|
348
|
+
], Pt = [
|
|
338
349
|
{
|
|
339
350
|
name: "repay",
|
|
340
351
|
type: "function",
|
|
341
352
|
stateMutability: "nonpayable",
|
|
342
353
|
inputs: [
|
|
343
|
-
|
|
354
|
+
se,
|
|
344
355
|
{ name: "assets", type: "uint256" },
|
|
345
356
|
{ name: "shares", type: "uint256" },
|
|
346
357
|
{ name: "onBehalf", type: "address" },
|
|
@@ -351,7 +362,7 @@ const w = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(m.prod)[T.ethereum
|
|
|
351
362
|
{ name: "sharesRepaid", type: "uint256" }
|
|
352
363
|
]
|
|
353
364
|
}
|
|
354
|
-
],
|
|
365
|
+
], Mt = [
|
|
355
366
|
{
|
|
356
367
|
name: "price",
|
|
357
368
|
type: "function",
|
|
@@ -359,37 +370,37 @@ const w = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb", I = R(m.prod)[T.ethereum
|
|
|
359
370
|
inputs: [],
|
|
360
371
|
outputs: [{ name: "", type: "uint256" }]
|
|
361
372
|
}
|
|
362
|
-
],
|
|
363
|
-
function
|
|
373
|
+
], Rt = 10n ** 36n, Dt = 10n ** 18n, Ft = 0.8;
|
|
374
|
+
function Nt({
|
|
364
375
|
collateralRaw: t,
|
|
365
376
|
borrowAssetsRaw: e,
|
|
366
377
|
oraclePrice: a,
|
|
367
378
|
lltvRaw: s
|
|
368
379
|
}) {
|
|
369
|
-
const
|
|
380
|
+
const o = Number(v(s, 18));
|
|
370
381
|
if (t === 0n)
|
|
371
382
|
return {
|
|
372
383
|
currentLtv: 0,
|
|
373
|
-
lltv:
|
|
384
|
+
lltv: o,
|
|
374
385
|
healthStatus: e > 0n ? "Bad debt" : "Empty"
|
|
375
386
|
};
|
|
376
387
|
if (e === 0n)
|
|
377
388
|
return {
|
|
378
389
|
currentLtv: 0,
|
|
379
|
-
lltv:
|
|
390
|
+
lltv: o,
|
|
380
391
|
healthStatus: "Collateral only (no borrows)"
|
|
381
392
|
};
|
|
382
393
|
if (a === 0n)
|
|
383
394
|
return {
|
|
384
395
|
currentLtv: 0,
|
|
385
|
-
lltv:
|
|
396
|
+
lltv: o,
|
|
386
397
|
healthStatus: "Unknown (oracle unavailable)"
|
|
387
398
|
};
|
|
388
|
-
const
|
|
389
|
-
let
|
|
390
|
-
return i < d ?
|
|
399
|
+
const r = t * a / Rt, n = e * Dt / r, i = Number(v(n, 18)), d = o * Ft;
|
|
400
|
+
let m;
|
|
401
|
+
return i < d ? m = "Healthy" : i < o ? m = "At risk" : m = "Liquidatable", { currentLtv: i, lltv: o, healthStatus: m };
|
|
391
402
|
}
|
|
392
|
-
const
|
|
403
|
+
const Ut = `{
|
|
393
404
|
markets(where: {
|
|
394
405
|
collateralAssetAddress_in: ["${I}"],
|
|
395
406
|
chainId_in: [1]
|
|
@@ -411,7 +422,7 @@ const Mt = `{
|
|
|
411
422
|
}
|
|
412
423
|
}
|
|
413
424
|
}`;
|
|
414
|
-
function
|
|
425
|
+
function P(t) {
|
|
415
426
|
return `{
|
|
416
427
|
marketByUniqueKey(uniqueKey: "${t}", chainId: 1) {
|
|
417
428
|
marketId: uniqueKey
|
|
@@ -430,9 +441,9 @@ function E(t) {
|
|
|
430
441
|
}
|
|
431
442
|
}`;
|
|
432
443
|
}
|
|
433
|
-
async function
|
|
444
|
+
async function L(t) {
|
|
434
445
|
var s;
|
|
435
|
-
const e = await fetch(
|
|
446
|
+
const e = await fetch(It, {
|
|
436
447
|
method: "POST",
|
|
437
448
|
headers: { "Content-Type": "application/json" },
|
|
438
449
|
body: JSON.stringify({ query: t })
|
|
@@ -444,7 +455,7 @@ async function k(t) {
|
|
|
444
455
|
throw new Error(`Morpho API error: ${a.errors[0].message}`);
|
|
445
456
|
return a.data;
|
|
446
457
|
}
|
|
447
|
-
function
|
|
458
|
+
function qt(t) {
|
|
448
459
|
const e = t.state.supplyAssetsUsd;
|
|
449
460
|
return {
|
|
450
461
|
marketId: t.marketId,
|
|
@@ -460,14 +471,14 @@ function Rt(t) {
|
|
|
460
471
|
description: `Borrow ${t.loanAsset.symbol} against LBTC collateral (${(t.state.supplyApy * 100).toFixed(2)}% supply APY, ${(Number(t.lltv) / 1e18 * 100).toFixed(0)}% LLTV)`
|
|
461
472
|
};
|
|
462
473
|
}
|
|
463
|
-
const
|
|
474
|
+
const Ot = {
|
|
464
475
|
name: "get_morpho_lbtc_markets",
|
|
465
476
|
description: "List Morpho Blue lending markets where LBTC is used as collateral. Returns market IDs, loan assets, supply/borrow APYs, TVL, and utilization. Use this to find markets where users can supply LBTC as collateral to borrow other assets.",
|
|
466
|
-
parameters:
|
|
467
|
-
schema:
|
|
477
|
+
parameters: ft,
|
|
478
|
+
schema: ve,
|
|
468
479
|
execute: async (t) => {
|
|
469
480
|
try {
|
|
470
|
-
const a = (await
|
|
481
|
+
const a = (await L(Ut)).markets.items.filter((s) => s.state.supplyAssetsUsd >= xt).sort((s, o) => o.state.supplyAssetsUsd - s.state.supplyAssetsUsd).map(qt);
|
|
471
482
|
return {
|
|
472
483
|
markets: a,
|
|
473
484
|
note: a.length > 0 ? `Found ${a.length} active Morpho markets with LBTC collateral on Ethereum mainnet. Supply LBTC as collateral to borrow the loan asset.` : "No active Morpho markets found for LBTC."
|
|
@@ -480,41 +491,41 @@ const Pt = {
|
|
|
480
491
|
};
|
|
481
492
|
}
|
|
482
493
|
}
|
|
483
|
-
},
|
|
494
|
+
}, Vt = {
|
|
484
495
|
name: "prepare_morpho_supply_collateral",
|
|
485
496
|
description: "Prepare transactions to supply LBTC as collateral to a Morpho Blue market. Returns two unsigned transactions: (1) ERC-20 approve for the Morpho contract, and (2) supplyCollateral call. The user's wallet signs both.",
|
|
486
|
-
parameters:
|
|
487
|
-
schema:
|
|
497
|
+
parameters: yt,
|
|
498
|
+
schema: K,
|
|
488
499
|
execute: async (t) => {
|
|
489
|
-
const { marketId: e, amount: a, address: s } =
|
|
500
|
+
const { marketId: e, amount: a, address: s } = K.parse(t);
|
|
490
501
|
try {
|
|
491
|
-
const
|
|
492
|
-
if (!
|
|
502
|
+
const r = (await L(P(e))).marketByUniqueKey;
|
|
503
|
+
if (!r)
|
|
493
504
|
return {
|
|
494
505
|
action: "error",
|
|
495
506
|
marketId: e,
|
|
496
507
|
description: "",
|
|
497
508
|
error: `Market ${e} not found on Morpho.`
|
|
498
509
|
};
|
|
499
|
-
if (
|
|
510
|
+
if (r.collateralAsset.address.toLowerCase() !== I.toLowerCase())
|
|
500
511
|
return {
|
|
501
512
|
action: "error",
|
|
502
513
|
marketId: e,
|
|
503
514
|
description: "",
|
|
504
|
-
error: `This market uses ${
|
|
515
|
+
error: `This market uses ${r.collateralAsset.symbol} as collateral, not LBTC.`
|
|
505
516
|
};
|
|
506
|
-
const n =
|
|
507
|
-
abi:
|
|
517
|
+
const n = ae(a, be), i = A({
|
|
518
|
+
abi: we,
|
|
508
519
|
functionName: "approve",
|
|
509
|
-
args: [
|
|
520
|
+
args: [T, n]
|
|
510
521
|
}), d = {
|
|
511
|
-
loanToken:
|
|
512
|
-
collateralToken:
|
|
513
|
-
oracle:
|
|
514
|
-
irm:
|
|
515
|
-
lltv: BigInt(
|
|
516
|
-
},
|
|
517
|
-
abi:
|
|
522
|
+
loanToken: r.loanAsset.address,
|
|
523
|
+
collateralToken: r.collateralAsset.address,
|
|
524
|
+
oracle: r.oracleAddress,
|
|
525
|
+
irm: r.irmAddress,
|
|
526
|
+
lltv: BigInt(r.lltv)
|
|
527
|
+
}, m = A({
|
|
528
|
+
abi: Et,
|
|
518
529
|
functionName: "supplyCollateral",
|
|
519
530
|
args: [
|
|
520
531
|
d,
|
|
@@ -536,48 +547,48 @@ const Pt = {
|
|
|
536
547
|
label: `Approve Morpho to spend ${a} LBTC`
|
|
537
548
|
},
|
|
538
549
|
{
|
|
539
|
-
to:
|
|
540
|
-
data:
|
|
541
|
-
label: `Supply ${a} LBTC as collateral to ${
|
|
550
|
+
to: T,
|
|
551
|
+
data: m,
|
|
552
|
+
label: `Supply ${a} LBTC as collateral to ${r.loanAsset.symbol}/LBTC market`
|
|
542
553
|
}
|
|
543
554
|
]
|
|
544
555
|
},
|
|
545
556
|
marketId: e,
|
|
546
|
-
description: `Supply ${a} LBTC as collateral to the ${
|
|
557
|
+
description: `Supply ${a} LBTC as collateral to the ${r.loanAsset.symbol}/LBTC Morpho market (${(Number(r.lltv) / 1e18 * 100).toFixed(0)}% LLTV, ${(r.state.supplyApy * 100).toFixed(2)}% supply APY). This requires two transactions: approve + supply.`
|
|
547
558
|
};
|
|
548
|
-
} catch (
|
|
559
|
+
} catch (o) {
|
|
549
560
|
return {
|
|
550
561
|
action: "error",
|
|
551
562
|
marketId: e,
|
|
552
563
|
description: "",
|
|
553
|
-
error:
|
|
564
|
+
error: o instanceof Error ? o.message : "Failed to prepare Morpho supply"
|
|
554
565
|
};
|
|
555
566
|
}
|
|
556
567
|
}
|
|
557
|
-
},
|
|
568
|
+
}, jt = {
|
|
558
569
|
name: "prepare_morpho_borrow",
|
|
559
570
|
description: "Prepare a transaction to borrow from a Morpho Blue market where the user has LBTC collateral. The user must have already supplied LBTC as collateral to this market. Returns an unsigned borrow transaction for the user's wallet to sign.",
|
|
560
|
-
parameters:
|
|
561
|
-
schema:
|
|
571
|
+
parameters: gt,
|
|
572
|
+
schema: J,
|
|
562
573
|
execute: async (t) => {
|
|
563
|
-
const { marketId: e, amount: a, address: s } =
|
|
574
|
+
const { marketId: e, amount: a, address: s } = J.parse(t);
|
|
564
575
|
try {
|
|
565
|
-
const
|
|
566
|
-
if (!
|
|
576
|
+
const r = (await L(P(e))).marketByUniqueKey;
|
|
577
|
+
if (!r)
|
|
567
578
|
return {
|
|
568
579
|
action: "error",
|
|
569
580
|
marketId: e,
|
|
570
581
|
description: "",
|
|
571
582
|
error: `Market ${e} not found on Morpho.`
|
|
572
583
|
};
|
|
573
|
-
const n =
|
|
574
|
-
loanToken:
|
|
575
|
-
collateralToken:
|
|
576
|
-
oracle:
|
|
577
|
-
irm:
|
|
578
|
-
lltv: BigInt(
|
|
584
|
+
const n = ae(a, r.loanAsset.decimals), i = {
|
|
585
|
+
loanToken: r.loanAsset.address,
|
|
586
|
+
collateralToken: r.collateralAsset.address,
|
|
587
|
+
oracle: r.oracleAddress,
|
|
588
|
+
irm: r.irmAddress,
|
|
589
|
+
lltv: BigInt(r.lltv)
|
|
579
590
|
}, d = A({
|
|
580
|
-
abi:
|
|
591
|
+
abi: $t,
|
|
581
592
|
functionName: "borrow",
|
|
582
593
|
args: [
|
|
583
594
|
i,
|
|
@@ -597,52 +608,52 @@ const Pt = {
|
|
|
597
608
|
chainId: 1,
|
|
598
609
|
transactions: [
|
|
599
610
|
{
|
|
600
|
-
to:
|
|
611
|
+
to: T,
|
|
601
612
|
data: d,
|
|
602
|
-
label: `Borrow ${a} ${
|
|
613
|
+
label: `Borrow ${a} ${r.loanAsset.symbol} from ${r.loanAsset.symbol}/LBTC market`
|
|
603
614
|
}
|
|
604
615
|
]
|
|
605
616
|
},
|
|
606
617
|
marketId: e,
|
|
607
|
-
description: `Borrow ${a} ${
|
|
618
|
+
description: `Borrow ${a} ${r.loanAsset.symbol} against your LBTC collateral on the ${r.loanAsset.symbol}/LBTC Morpho market (${(r.state.borrowApy * 100).toFixed(2)}% borrow APY).`
|
|
608
619
|
};
|
|
609
|
-
} catch (
|
|
620
|
+
} catch (o) {
|
|
610
621
|
return {
|
|
611
622
|
action: "error",
|
|
612
623
|
marketId: e,
|
|
613
624
|
description: "",
|
|
614
|
-
error:
|
|
625
|
+
error: o instanceof Error ? o.message : "Failed to prepare Morpho borrow"
|
|
615
626
|
};
|
|
616
627
|
}
|
|
617
628
|
}
|
|
618
|
-
},
|
|
629
|
+
}, Ht = {
|
|
619
630
|
name: "prepare_morpho_repay",
|
|
620
631
|
description: "Prepare transactions to repay borrowed assets on a Morpho Blue market. Returns two unsigned transactions: (1) ERC-20 approve for the Morpho contract, and (2) repay call. The user must have the loan asset in their wallet.",
|
|
621
|
-
parameters:
|
|
622
|
-
schema:
|
|
632
|
+
parameters: wt,
|
|
633
|
+
schema: X,
|
|
623
634
|
execute: async (t) => {
|
|
624
|
-
const { marketId: e, amount: a, address: s } =
|
|
635
|
+
const { marketId: e, amount: a, address: s } = X.parse(t);
|
|
625
636
|
try {
|
|
626
|
-
const
|
|
627
|
-
if (!
|
|
637
|
+
const r = (await L(P(e))).marketByUniqueKey;
|
|
638
|
+
if (!r)
|
|
628
639
|
return {
|
|
629
640
|
action: "error",
|
|
630
641
|
marketId: e,
|
|
631
642
|
description: "",
|
|
632
643
|
error: `Market ${e} not found on Morpho.`
|
|
633
644
|
};
|
|
634
|
-
const n =
|
|
635
|
-
abi:
|
|
645
|
+
const n = ae(a, r.loanAsset.decimals), i = A({
|
|
646
|
+
abi: we,
|
|
636
647
|
functionName: "approve",
|
|
637
|
-
args: [
|
|
648
|
+
args: [T, n]
|
|
638
649
|
}), d = {
|
|
639
|
-
loanToken:
|
|
640
|
-
collateralToken:
|
|
641
|
-
oracle:
|
|
642
|
-
irm:
|
|
643
|
-
lltv: BigInt(
|
|
644
|
-
},
|
|
645
|
-
abi:
|
|
650
|
+
loanToken: r.loanAsset.address,
|
|
651
|
+
collateralToken: r.collateralAsset.address,
|
|
652
|
+
oracle: r.oracleAddress,
|
|
653
|
+
irm: r.irmAddress,
|
|
654
|
+
lltv: BigInt(r.lltv)
|
|
655
|
+
}, m = A({
|
|
656
|
+
abi: Pt,
|
|
646
657
|
functionName: "repay",
|
|
647
658
|
args: [
|
|
648
659
|
d,
|
|
@@ -662,36 +673,36 @@ const Pt = {
|
|
|
662
673
|
chainId: 1,
|
|
663
674
|
transactions: [
|
|
664
675
|
{
|
|
665
|
-
to:
|
|
676
|
+
to: r.loanAsset.address,
|
|
666
677
|
data: i,
|
|
667
|
-
label: `Approve Morpho to spend ${a} ${
|
|
678
|
+
label: `Approve Morpho to spend ${a} ${r.loanAsset.symbol}`
|
|
668
679
|
},
|
|
669
680
|
{
|
|
670
|
-
to:
|
|
671
|
-
data:
|
|
672
|
-
label: `Repay ${a} ${
|
|
681
|
+
to: T,
|
|
682
|
+
data: m,
|
|
683
|
+
label: `Repay ${a} ${r.loanAsset.symbol} on ${r.loanAsset.symbol}/LBTC market`
|
|
673
684
|
}
|
|
674
685
|
]
|
|
675
686
|
},
|
|
676
687
|
marketId: e,
|
|
677
|
-
description: `Repay ${a} ${
|
|
688
|
+
description: `Repay ${a} ${r.loanAsset.symbol} on the ${r.loanAsset.symbol}/${r.collateralAsset.symbol} Morpho market. This requires two transactions: approve + repay.`
|
|
678
689
|
};
|
|
679
|
-
} catch (
|
|
690
|
+
} catch (o) {
|
|
680
691
|
return {
|
|
681
692
|
action: "error",
|
|
682
693
|
marketId: e,
|
|
683
694
|
description: "",
|
|
684
|
-
error:
|
|
695
|
+
error: o instanceof Error ? o.message : "Failed to prepare Morpho repay"
|
|
685
696
|
};
|
|
686
697
|
}
|
|
687
698
|
}
|
|
688
|
-
},
|
|
699
|
+
}, zt = {
|
|
689
700
|
name: "get_morpho_position",
|
|
690
701
|
description: "Get the user's position in a Morpho Blue market: collateral deposited, amount borrowed, current LTV, and health status. Returns token addresses for use with get_token_balance.",
|
|
691
|
-
parameters:
|
|
692
|
-
schema:
|
|
702
|
+
parameters: Bt,
|
|
703
|
+
schema: Q,
|
|
693
704
|
execute: async (t) => {
|
|
694
|
-
const { marketId: e, address: a } =
|
|
705
|
+
const { marketId: e, address: a } = Q.parse(t), s = {
|
|
695
706
|
collateral: "0",
|
|
696
707
|
borrowAssets: "0",
|
|
697
708
|
loanAsset: "",
|
|
@@ -703,80 +714,80 @@ const Pt = {
|
|
|
703
714
|
healthStatus: "No position"
|
|
704
715
|
};
|
|
705
716
|
try {
|
|
706
|
-
const
|
|
707
|
-
if (!
|
|
717
|
+
const r = (await L(P(e))).marketByUniqueKey;
|
|
718
|
+
if (!r)
|
|
708
719
|
return { ...s, error: `Market ${e} not found.` };
|
|
709
|
-
const n =
|
|
720
|
+
const n = p(1), i = ee({
|
|
710
721
|
chainId: n.chainId,
|
|
711
722
|
env: n.env
|
|
712
|
-
}), [d,
|
|
723
|
+
}), [d, m, _e] = await Promise.all([
|
|
713
724
|
i.readContract({
|
|
714
|
-
address:
|
|
715
|
-
abi:
|
|
725
|
+
address: T,
|
|
726
|
+
abi: me,
|
|
716
727
|
functionName: "position",
|
|
717
728
|
args: [e, a]
|
|
718
729
|
}),
|
|
719
730
|
i.readContract({
|
|
720
|
-
address:
|
|
721
|
-
abi:
|
|
731
|
+
address: T,
|
|
732
|
+
abi: me,
|
|
722
733
|
functionName: "market",
|
|
723
734
|
args: [e]
|
|
724
735
|
}),
|
|
725
736
|
i.readContract({
|
|
726
|
-
address:
|
|
727
|
-
abi:
|
|
737
|
+
address: r.oracleAddress,
|
|
738
|
+
abi: Mt,
|
|
728
739
|
functionName: "price"
|
|
729
740
|
})
|
|
730
|
-
]),
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
), { currentLtv:
|
|
734
|
-
collateralRaw:
|
|
735
|
-
borrowAssetsRaw:
|
|
736
|
-
oraclePrice:
|
|
737
|
-
lltvRaw: BigInt(
|
|
741
|
+
]), re = d[2], Le = d[1], Se = m[2], oe = m[3], ne = oe > 0n ? Le * Se / oe : 0n, Ie = v(re, be), xe = v(
|
|
742
|
+
ne,
|
|
743
|
+
r.loanAsset.decimals
|
|
744
|
+
), { currentLtv: Ee, lltv: $e, healthStatus: Pe } = Nt({
|
|
745
|
+
collateralRaw: re,
|
|
746
|
+
borrowAssetsRaw: ne,
|
|
747
|
+
oraclePrice: _e,
|
|
748
|
+
lltvRaw: BigInt(r.lltv)
|
|
738
749
|
});
|
|
739
750
|
return {
|
|
740
|
-
collateral:
|
|
741
|
-
borrowAssets:
|
|
742
|
-
loanAsset:
|
|
743
|
-
loanAssetAddress:
|
|
744
|
-
collateralAsset:
|
|
745
|
-
collateralAssetAddress:
|
|
746
|
-
lltv: `${(
|
|
747
|
-
currentLtv: `${(
|
|
748
|
-
healthStatus:
|
|
751
|
+
collateral: Ie,
|
|
752
|
+
borrowAssets: xe,
|
|
753
|
+
loanAsset: r.loanAsset.symbol,
|
|
754
|
+
loanAssetAddress: r.loanAsset.address,
|
|
755
|
+
collateralAsset: r.collateralAsset.symbol,
|
|
756
|
+
collateralAssetAddress: r.collateralAsset.address,
|
|
757
|
+
lltv: `${($e * 100).toFixed(0)}%`,
|
|
758
|
+
currentLtv: `${(Ee * 100).toFixed(1)}%`,
|
|
759
|
+
healthStatus: Pe
|
|
749
760
|
};
|
|
750
|
-
} catch (
|
|
761
|
+
} catch (o) {
|
|
751
762
|
return {
|
|
752
763
|
...s,
|
|
753
|
-
error:
|
|
764
|
+
error: o instanceof Error ? o.message : "Failed to fetch Morpho position"
|
|
754
765
|
};
|
|
755
766
|
}
|
|
756
767
|
}
|
|
757
768
|
};
|
|
758
|
-
function
|
|
769
|
+
function f(t, e, a) {
|
|
759
770
|
return Promise.race([
|
|
760
771
|
t,
|
|
761
772
|
new Promise(
|
|
762
|
-
(s,
|
|
763
|
-
() =>
|
|
773
|
+
(s, o) => setTimeout(
|
|
774
|
+
() => o(new Error(`${a} timed out after ${e}ms`)),
|
|
764
775
|
e
|
|
765
776
|
)
|
|
766
777
|
)
|
|
767
778
|
]);
|
|
768
779
|
}
|
|
769
|
-
async function
|
|
770
|
-
const s =
|
|
771
|
-
|
|
780
|
+
async function x(t, e, a) {
|
|
781
|
+
const s = p(a), o = await f(
|
|
782
|
+
Ye(t, s.chainId, s.env),
|
|
772
783
|
1e4,
|
|
773
784
|
"getTokenContractInfo"
|
|
774
|
-
),
|
|
785
|
+
), r = ee({
|
|
775
786
|
chainId: s.chainId,
|
|
776
787
|
env: s.env
|
|
777
|
-
}), n = await
|
|
778
|
-
|
|
779
|
-
address:
|
|
788
|
+
}), n = await f(
|
|
789
|
+
r.readContract({
|
|
790
|
+
address: o.address,
|
|
780
791
|
abi: [
|
|
781
792
|
{
|
|
782
793
|
name: "balanceOf",
|
|
@@ -791,67 +802,67 @@ async function S(t, e, a) {
|
|
|
791
802
|
}),
|
|
792
803
|
1e4,
|
|
793
804
|
`${t}.balanceOf on ${s.name}`
|
|
794
|
-
), i = "decimals" in
|
|
805
|
+
), i = "decimals" in o && typeof o.decimals == "number" ? o.decimals : 8;
|
|
795
806
|
return v(n, i);
|
|
796
807
|
}
|
|
797
|
-
const
|
|
808
|
+
const Zt = {
|
|
798
809
|
name: "get_lbtc_balance",
|
|
799
810
|
description: "Check the LBTC balance for a wallet address on a given chain.",
|
|
800
|
-
parameters:
|
|
801
|
-
schema:
|
|
811
|
+
parameters: w,
|
|
812
|
+
schema: u,
|
|
802
813
|
execute: async (t) => {
|
|
803
|
-
const { address: e, chainId: a } =
|
|
814
|
+
const { address: e, chainId: a } = u.parse(t), { name: s } = p(a);
|
|
804
815
|
try {
|
|
805
|
-
return { balance: await S
|
|
806
|
-
} catch (
|
|
816
|
+
return { balance: await x(S.LBTC, e, a), token: "LBTC", chain: s, address: e };
|
|
817
|
+
} catch (o) {
|
|
807
818
|
return {
|
|
808
819
|
balance: "",
|
|
809
820
|
token: "LBTC",
|
|
810
821
|
chain: s,
|
|
811
822
|
address: e,
|
|
812
|
-
error:
|
|
823
|
+
error: o instanceof Error ? o.message : "Failed to fetch LBTC balance"
|
|
813
824
|
};
|
|
814
825
|
}
|
|
815
826
|
}
|
|
816
|
-
},
|
|
827
|
+
}, Yt = {
|
|
817
828
|
name: "get_btcb_balance",
|
|
818
829
|
description: "Check the BTC.b (cross-chain Bitcoin) balance for a wallet address on a given chain.",
|
|
819
|
-
parameters:
|
|
820
|
-
schema:
|
|
830
|
+
parameters: w,
|
|
831
|
+
schema: u,
|
|
821
832
|
execute: async (t) => {
|
|
822
|
-
const { address: e, chainId: a } =
|
|
833
|
+
const { address: e, chainId: a } = u.parse(t), { name: s } = p(a);
|
|
823
834
|
try {
|
|
824
|
-
return { balance: await S
|
|
825
|
-
} catch (
|
|
835
|
+
return { balance: await x(S.BTCb, e, a), token: "BTC.b", chain: s, address: e };
|
|
836
|
+
} catch (o) {
|
|
826
837
|
return {
|
|
827
838
|
balance: "",
|
|
828
839
|
token: "BTC.b",
|
|
829
840
|
chain: s,
|
|
830
841
|
address: e,
|
|
831
|
-
error:
|
|
842
|
+
error: o instanceof Error ? o.message : "Failed to fetch BTC.b balance"
|
|
832
843
|
};
|
|
833
844
|
}
|
|
834
845
|
}
|
|
835
|
-
},
|
|
846
|
+
}, Wt = {
|
|
836
847
|
name: "get_exchange_rate",
|
|
837
848
|
description: "Get the current LBTC/BTC exchange rate and minimum stake amount. LBTC accrues staking yield over time, so 1 LBTC is worth slightly more than 1 BTC.",
|
|
838
|
-
parameters:
|
|
839
|
-
schema:
|
|
849
|
+
parameters: tt,
|
|
850
|
+
schema: D,
|
|
840
851
|
execute: async (t) => {
|
|
841
|
-
const { chainId: e } =
|
|
852
|
+
const { chainId: e } = D.parse(t);
|
|
842
853
|
try {
|
|
843
|
-
const a =
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
]),
|
|
847
|
-
if (!(
|
|
854
|
+
const a = h.prod, [s, o] = await Promise.all([
|
|
855
|
+
Re({ env: a }),
|
|
856
|
+
De({ env: a })
|
|
857
|
+
]), r = s.LBTC;
|
|
858
|
+
if (!(r != null && r.BTCTokenRatio) || !(r != null && r.tokenBTCRatio))
|
|
848
859
|
throw new Error("Exchange ratio data unavailable");
|
|
849
|
-
const n = String(
|
|
860
|
+
const n = String(r.BTCTokenRatio), i = String(r.tokenBTCRatio);
|
|
850
861
|
return {
|
|
851
862
|
lbtcToBtc: n,
|
|
852
863
|
btcToLbtc: i,
|
|
853
|
-
minStakeAmountBtc:
|
|
854
|
-
description: `1 LBTC = ${n} BTC. 1 BTC = ${i} LBTC. Min stake: ${
|
|
864
|
+
minStakeAmountBtc: ce(o.minAmount).toString(),
|
|
865
|
+
description: `1 LBTC = ${n} BTC. 1 BTC = ${i} LBTC. Min stake: ${ce(o.minAmount)} BTC.`
|
|
855
866
|
};
|
|
856
867
|
} catch (a) {
|
|
857
868
|
return {
|
|
@@ -863,72 +874,72 @@ const qt = {
|
|
|
863
874
|
};
|
|
864
875
|
}
|
|
865
876
|
}
|
|
866
|
-
},
|
|
877
|
+
}, Gt = {
|
|
867
878
|
name: "get_deposit_status",
|
|
868
879
|
description: "Check the status of all deposits for an address. Shows pending, claimable, and claimed deposits.",
|
|
869
|
-
parameters:
|
|
870
|
-
schema:
|
|
880
|
+
parameters: w,
|
|
881
|
+
schema: u,
|
|
871
882
|
execute: async (t) => {
|
|
872
|
-
const { address: e, chainId: a } =
|
|
883
|
+
const { address: e, chainId: a } = u.parse(t), { env: s } = p(a), o = await fe({
|
|
873
884
|
address: e,
|
|
874
885
|
env: s
|
|
875
886
|
});
|
|
876
|
-
return
|
|
877
|
-
totalDeposits:
|
|
878
|
-
deposits:
|
|
887
|
+
return o.length === 0 ? { deposits: [], message: "No deposits found" } : {
|
|
888
|
+
totalDeposits: o.length,
|
|
889
|
+
deposits: o.map((r) => {
|
|
879
890
|
var d;
|
|
880
|
-
const n =
|
|
891
|
+
const n = ye(r), i = ge(n);
|
|
881
892
|
return {
|
|
882
|
-
txHash:
|
|
883
|
-
amount: (d =
|
|
893
|
+
txHash: r.txHash,
|
|
894
|
+
amount: (d = r.amount) == null ? void 0 : d.toString(),
|
|
884
895
|
status: n,
|
|
885
896
|
statusLabel: i.label,
|
|
886
897
|
description: i.description,
|
|
887
898
|
requiresAction: i.requiresAction,
|
|
888
|
-
rawPayload:
|
|
889
|
-
proofSignature:
|
|
899
|
+
rawPayload: r.rawPayload || null,
|
|
900
|
+
proofSignature: r.proof || null
|
|
890
901
|
};
|
|
891
902
|
})
|
|
892
903
|
};
|
|
893
904
|
}
|
|
894
|
-
},
|
|
895
|
-
name: "
|
|
905
|
+
}, Kt = {
|
|
906
|
+
name: "get_redemption_status",
|
|
896
907
|
description: "Check the status of all unstake/redeem operations for an address.",
|
|
897
|
-
parameters:
|
|
898
|
-
schema:
|
|
908
|
+
parameters: w,
|
|
909
|
+
schema: u,
|
|
899
910
|
execute: async (t) => {
|
|
900
|
-
const { address: e, chainId: a } =
|
|
911
|
+
const { address: e, chainId: a } = u.parse(t), { env: s } = p(a), o = await Fe({
|
|
901
912
|
address: e,
|
|
902
913
|
env: s
|
|
903
914
|
});
|
|
904
|
-
return
|
|
905
|
-
totalUnstakes:
|
|
906
|
-
unstakes:
|
|
915
|
+
return o.length === 0 ? { unstakes: [], message: "No unstakes found" } : {
|
|
916
|
+
totalUnstakes: o.length,
|
|
917
|
+
unstakes: o.map((r) => {
|
|
907
918
|
var n;
|
|
908
919
|
return {
|
|
909
|
-
txHash:
|
|
910
|
-
amount: (n =
|
|
911
|
-
payoutStatus:
|
|
912
|
-
payoutTxHash:
|
|
920
|
+
txHash: r.txHash,
|
|
921
|
+
amount: (n = r.amount) == null ? void 0 : n.toString(),
|
|
922
|
+
payoutStatus: r.payoutTxStatus,
|
|
923
|
+
payoutTxHash: r.payoutTxHash || null
|
|
913
924
|
};
|
|
914
925
|
})
|
|
915
926
|
};
|
|
916
927
|
}
|
|
917
|
-
},
|
|
928
|
+
}, Jt = {
|
|
918
929
|
name: "get_balance",
|
|
919
930
|
description: "Check both LBTC and BTC.b balances for a wallet on a given chain in a single call.",
|
|
920
|
-
parameters:
|
|
921
|
-
schema:
|
|
931
|
+
parameters: ot,
|
|
932
|
+
schema: q,
|
|
922
933
|
execute: async (t) => {
|
|
923
|
-
const { address: e, chainId: a } =
|
|
924
|
-
S
|
|
934
|
+
const { address: e, chainId: a } = q.parse(t), s = p(a), [o, r] = await Promise.all([
|
|
935
|
+
x(S.LBTC, e, a).catch(
|
|
925
936
|
(n) => n instanceof Error ? `error: ${n.message}` : "error"
|
|
926
937
|
),
|
|
927
|
-
S
|
|
938
|
+
x(S.BTCb, e, a).catch(
|
|
928
939
|
(n) => n instanceof Error ? `error: ${n.message}` : "error"
|
|
929
940
|
)
|
|
930
941
|
]);
|
|
931
|
-
return { lbtc:
|
|
942
|
+
return { lbtc: o, btcb: r, chain: s.name, address: e };
|
|
932
943
|
}
|
|
933
944
|
}, M = [
|
|
934
945
|
{
|
|
@@ -952,16 +963,16 @@ const qt = {
|
|
|
952
963
|
inputs: [],
|
|
953
964
|
outputs: [{ name: "", type: "string" }]
|
|
954
965
|
}
|
|
955
|
-
],
|
|
966
|
+
], Xt = {
|
|
956
967
|
name: "get_token_info",
|
|
957
968
|
description: "Look up a Lombard-related asset by symbol, alias, or contract address. Returns the canonical name, description, decimals, and per-chain contract addresses. Use this whenever the user mentions a token you're not sure about (BTCe, LBTCv, etc.) before telling them you don't recognize it.",
|
|
958
|
-
parameters:
|
|
959
|
-
schema:
|
|
969
|
+
parameters: mt,
|
|
970
|
+
schema: Te,
|
|
960
971
|
execute: async (t) => {
|
|
961
|
-
const e =
|
|
962
|
-
const
|
|
963
|
-
for (const [
|
|
964
|
-
n && (r
|
|
972
|
+
const e = E.map((s) => s.symbol), a = (s) => {
|
|
973
|
+
const o = {};
|
|
974
|
+
for (const [r, n] of Object.entries(s.addresses))
|
|
975
|
+
n && (o[r] = n);
|
|
965
976
|
return {
|
|
966
977
|
symbol: s.symbol,
|
|
967
978
|
name: s.name,
|
|
@@ -969,12 +980,12 @@ const qt = {
|
|
|
969
980
|
decimals: s.decimals,
|
|
970
981
|
isLombardIssued: s.isLombardIssued,
|
|
971
982
|
isYieldBearing: s.isYieldBearing,
|
|
972
|
-
addresses:
|
|
983
|
+
addresses: o,
|
|
973
984
|
...s.notes ? { notes: s.notes } : {}
|
|
974
985
|
};
|
|
975
986
|
};
|
|
976
987
|
if (t.address && typeof t.chainId == "number") {
|
|
977
|
-
const s =
|
|
988
|
+
const s = Je(t.chainId, t.address);
|
|
978
989
|
return s ? {
|
|
979
990
|
found: !0,
|
|
980
991
|
asset: a(s),
|
|
@@ -986,7 +997,7 @@ const qt = {
|
|
|
986
997
|
};
|
|
987
998
|
}
|
|
988
999
|
if (t.query) {
|
|
989
|
-
const s =
|
|
1000
|
+
const s = Ke(t.query);
|
|
990
1001
|
return s ? {
|
|
991
1002
|
found: !0,
|
|
992
1003
|
asset: a(s),
|
|
@@ -1003,30 +1014,30 @@ const qt = {
|
|
|
1003
1014
|
note: "Provide a `query` (symbol/name) or both `address` and `chainId`."
|
|
1004
1015
|
};
|
|
1005
1016
|
}
|
|
1006
|
-
},
|
|
1017
|
+
}, Qt = {
|
|
1007
1018
|
name: "get_token_balance",
|
|
1008
1019
|
description: "Check the balance of any ERC-20 token for a wallet address. Requires the token contract address (0x...). Get addresses from other tool results (e.g. loanAsset.address from get_morpho_lbtc_markets). Reads symbol and decimals directly from the contract. Use this for tokens beyond LBTC and BTC.b.",
|
|
1009
|
-
parameters:
|
|
1010
|
-
schema:
|
|
1020
|
+
parameters: ht,
|
|
1021
|
+
schema: G,
|
|
1011
1022
|
execute: async (t) => {
|
|
1012
|
-
const { tokenAddress: e, address: a, chainId: s } =
|
|
1013
|
-
chainId:
|
|
1014
|
-
env:
|
|
1023
|
+
const { tokenAddress: e, address: a, chainId: s } = G.parse(t), o = p(s), r = ee({
|
|
1024
|
+
chainId: o.chainId,
|
|
1025
|
+
env: o.env
|
|
1015
1026
|
});
|
|
1016
1027
|
try {
|
|
1017
1028
|
const [n, i, d] = await Promise.all([
|
|
1018
|
-
|
|
1029
|
+
r.readContract({
|
|
1019
1030
|
address: e,
|
|
1020
1031
|
abi: M,
|
|
1021
1032
|
functionName: "balanceOf",
|
|
1022
1033
|
args: [a]
|
|
1023
1034
|
}),
|
|
1024
|
-
|
|
1035
|
+
r.readContract({
|
|
1025
1036
|
address: e,
|
|
1026
1037
|
abi: M,
|
|
1027
1038
|
functionName: "decimals"
|
|
1028
1039
|
}),
|
|
1029
|
-
|
|
1040
|
+
r.readContract({
|
|
1030
1041
|
address: e,
|
|
1031
1042
|
abi: M,
|
|
1032
1043
|
functionName: "symbol"
|
|
@@ -1036,38 +1047,38 @@ const qt = {
|
|
|
1036
1047
|
balance: v(n, i),
|
|
1037
1048
|
symbol: d,
|
|
1038
1049
|
tokenAddress: e,
|
|
1039
|
-
chain:
|
|
1050
|
+
chain: o.name
|
|
1040
1051
|
};
|
|
1041
1052
|
} catch (n) {
|
|
1042
1053
|
return {
|
|
1043
1054
|
balance: "",
|
|
1044
1055
|
symbol: "",
|
|
1045
1056
|
tokenAddress: e,
|
|
1046
|
-
chain:
|
|
1057
|
+
chain: o.name,
|
|
1047
1058
|
error: n instanceof Error ? n.message : "Failed to read token balance"
|
|
1048
1059
|
};
|
|
1049
1060
|
}
|
|
1050
1061
|
}
|
|
1051
|
-
},
|
|
1052
|
-
name: "
|
|
1062
|
+
}, ea = {
|
|
1063
|
+
name: "get_earn_strategies",
|
|
1053
1064
|
description: "List available yield strategies where LBTC can be deployed for additional yield. Currently includes Bitcoin Earn (passive vault yield). Returns name, chain, APY, and TVL.",
|
|
1054
|
-
parameters:
|
|
1055
|
-
schema:
|
|
1065
|
+
parameters: nt,
|
|
1066
|
+
schema: O,
|
|
1056
1067
|
// Vault data is mainnet-only regardless of chainId
|
|
1057
1068
|
execute: async (t) => {
|
|
1058
|
-
const { chainId: e } =
|
|
1069
|
+
const { chainId: e } = O.parse(t), a = h.prod;
|
|
1059
1070
|
try {
|
|
1060
|
-
const [s,
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
]),
|
|
1071
|
+
const [s, o] = await Promise.all([
|
|
1072
|
+
Ne({ env: a }),
|
|
1073
|
+
Ue({ env: a })
|
|
1074
|
+
]), r = s.length > 0 ? s[s.length - 1] : null;
|
|
1064
1075
|
return {
|
|
1065
1076
|
strategies: [
|
|
1066
1077
|
{
|
|
1067
1078
|
vault: "Bitcoin Earn",
|
|
1068
1079
|
chain: "Ethereum",
|
|
1069
|
-
apy:
|
|
1070
|
-
tvlBtc:
|
|
1080
|
+
apy: r ? `${(parseFloat(String(r.apy)) * 100).toFixed(2)}%` : "N/A",
|
|
1081
|
+
tvlBtc: o.btcBalance.toFixed(4)
|
|
1071
1082
|
}
|
|
1072
1083
|
]
|
|
1073
1084
|
};
|
|
@@ -1075,44 +1086,44 @@ const qt = {
|
|
|
1075
1086
|
return { strategies: [], error: "Unable to fetch vault data" };
|
|
1076
1087
|
}
|
|
1077
1088
|
}
|
|
1078
|
-
},
|
|
1079
|
-
name: "
|
|
1089
|
+
}, ta = process.env.LOMBARD_BFF_URL || "https://bff.prod.lombard-fi.com", aa = {
|
|
1090
|
+
name: "get_lbtc_defi_opportunities",
|
|
1080
1091
|
description: "List LBTC and BTC.b DeFi opportunities across protocols and chains. Includes borrow-stables, looping, DEX LP, automated strategies, and more. Filter by category (borrow-stables, looping, dex-lp, automated-strategy, other), chain, or protocol.",
|
|
1081
|
-
parameters:
|
|
1082
|
-
schema:
|
|
1092
|
+
parameters: ut,
|
|
1093
|
+
schema: W,
|
|
1083
1094
|
execute: async (t) => {
|
|
1084
|
-
const { category: e, chain: a, protocol: s } =
|
|
1095
|
+
const { category: e, chain: a, protocol: s } = W.parse(t);
|
|
1085
1096
|
try {
|
|
1086
|
-
const
|
|
1087
|
-
e &&
|
|
1088
|
-
const
|
|
1097
|
+
const o = [];
|
|
1098
|
+
e && o.push(`category=${encodeURIComponent(e)}`), a && o.push(`chain=${encodeURIComponent(a)}`), s && o.push(`protocol=${encodeURIComponent(s)}`);
|
|
1099
|
+
const r = o.length > 0 ? `?${o.join("&")}` : "", n = await fetch(`${ta}/opportunities-api${r}`);
|
|
1089
1100
|
if (!n.ok)
|
|
1090
1101
|
throw new Error(`BFF returned ${n.status}`);
|
|
1091
1102
|
return {
|
|
1092
1103
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1093
1104
|
opportunities: (await n.json()).opportunities
|
|
1094
1105
|
};
|
|
1095
|
-
} catch (
|
|
1106
|
+
} catch (o) {
|
|
1096
1107
|
return {
|
|
1097
1108
|
opportunities: [],
|
|
1098
|
-
error:
|
|
1109
|
+
error: o instanceof Error ? o.message : "Failed to fetch opportunities"
|
|
1099
1110
|
};
|
|
1100
1111
|
}
|
|
1101
1112
|
}
|
|
1102
|
-
},
|
|
1113
|
+
}, sa = {
|
|
1103
1114
|
name: "get_deposit_btc_address",
|
|
1104
1115
|
description: "Get or generate a BTC deposit address for a wallet. Users send native BTC to this address to receive LBTC on the specified EVM chain. If no address exists yet, returns instructions to generate one (requires a wallet signature).",
|
|
1105
|
-
parameters:
|
|
1106
|
-
schema:
|
|
1116
|
+
parameters: it,
|
|
1117
|
+
schema: V,
|
|
1107
1118
|
execute: async (t) => {
|
|
1108
|
-
const { address: e, chainId: a } =
|
|
1119
|
+
const { address: e, chainId: a } = V.parse(t), s = p(a);
|
|
1109
1120
|
try {
|
|
1110
1121
|
return {
|
|
1111
|
-
btcAddress: await
|
|
1122
|
+
btcAddress: await qe({
|
|
1112
1123
|
address: e,
|
|
1113
1124
|
chainId: s.chainId,
|
|
1114
1125
|
env: s.env,
|
|
1115
|
-
partnerId:
|
|
1126
|
+
partnerId: St(s.env)
|
|
1116
1127
|
}),
|
|
1117
1128
|
chain: s.name,
|
|
1118
1129
|
note: "Send BTC to this address. Once confirmed and notarized, use get_deposit_status to track progress and claim your LBTC."
|
|
@@ -1126,29 +1137,29 @@ const qt = {
|
|
|
1126
1137
|
};
|
|
1127
1138
|
}
|
|
1128
1139
|
}
|
|
1129
|
-
},
|
|
1140
|
+
}, ra = {
|
|
1130
1141
|
name: "check_fee_authorization",
|
|
1131
1142
|
description: "Check if a valid fee authorization signature exists for staking. On Ethereum/Sepolia, fee auth (EIP-712) is required before generating a BTC deposit address. On other chains, an address confirmation is required instead.",
|
|
1132
|
-
parameters:
|
|
1133
|
-
schema:
|
|
1143
|
+
parameters: w,
|
|
1144
|
+
schema: u,
|
|
1134
1145
|
execute: async (t) => {
|
|
1135
|
-
const { address: e, chainId: a } =
|
|
1136
|
-
if (
|
|
1146
|
+
const { address: e, chainId: a } = u.parse(t), s = p(a);
|
|
1147
|
+
if (Oe(s.chainId))
|
|
1137
1148
|
try {
|
|
1138
|
-
const
|
|
1139
|
-
|
|
1149
|
+
const r = await f(
|
|
1150
|
+
Ve({
|
|
1140
1151
|
address: e,
|
|
1141
1152
|
chainId: s.chainId,
|
|
1142
1153
|
env: s.env
|
|
1143
1154
|
}),
|
|
1144
1155
|
1e4,
|
|
1145
1156
|
"getNetworkFeeSignature"
|
|
1146
|
-
), n =
|
|
1157
|
+
), n = r.hasSignature && new Date(r.expirationDate).getTime() > Date.now();
|
|
1147
1158
|
return {
|
|
1148
1159
|
chain: s.name,
|
|
1149
1160
|
requiresFeeAuth: !0,
|
|
1150
1161
|
hasValidSignature: n,
|
|
1151
|
-
expirationDate:
|
|
1162
|
+
expirationDate: r.hasSignature ? r.expirationDate : null,
|
|
1152
1163
|
note: n ? "Fee authorization is valid. Ready to generate deposit address." : "Fee authorization is needed before generating a deposit address."
|
|
1153
1164
|
};
|
|
1154
1165
|
} catch {
|
|
@@ -1168,27 +1179,27 @@ const qt = {
|
|
|
1168
1179
|
note: "This chain requires an address confirmation signature (not fee auth). The signing will happen when generating the deposit address."
|
|
1169
1180
|
};
|
|
1170
1181
|
}
|
|
1171
|
-
},
|
|
1172
|
-
name: "
|
|
1182
|
+
}, oa = {
|
|
1183
|
+
name: "prepare_btc_to_lbtc_deposit",
|
|
1173
1184
|
description: "Prepare a native BTC -> LBTC deposit address. Use this when the user wants LBTC (yield-bearing). The wallet will prompt for fee authorization (Ethereum/Sepolia) or an address confirmation (other chains), then a unique BTC deposit address is generated.",
|
|
1174
|
-
parameters:
|
|
1175
|
-
schema:
|
|
1185
|
+
parameters: w,
|
|
1186
|
+
schema: u,
|
|
1176
1187
|
execute: async (t) => {
|
|
1177
|
-
const { address: e, chainId: a } =
|
|
1188
|
+
const { address: e, chainId: a } = u.parse(t), s = p(a);
|
|
1178
1189
|
return {
|
|
1179
1190
|
action: "sdk_execute",
|
|
1180
|
-
method: "btc.
|
|
1191
|
+
method: "btc.generateLbtcDepositAddress",
|
|
1181
1192
|
params: { address: e, chainId: s.chainId },
|
|
1182
1193
|
description: `Generate a BTC deposit address for ${e} on ${s.name}. The deposit will mint LBTC. Your wallet will prompt you to sign an authorization.`
|
|
1183
1194
|
};
|
|
1184
1195
|
}
|
|
1185
|
-
},
|
|
1196
|
+
}, na = {
|
|
1186
1197
|
name: "prepare_btc_to_btcb_deposit",
|
|
1187
|
-
description: "Prepare a native BTC -> BTC.b deposit address. Use this when the user wants BTC.b (cross-chain wrapped Bitcoin, NOT yield-bearing). Distinct flow from
|
|
1188
|
-
parameters:
|
|
1189
|
-
schema:
|
|
1198
|
+
description: "Prepare a native BTC -> BTC.b deposit address. Use this when the user wants BTC.b (cross-chain wrapped Bitcoin, NOT yield-bearing). Distinct flow from prepare_btc_to_lbtc_deposit (which produces LBTC). The wallet will prompt for the required authorization, then a unique BTC deposit address is generated that mints BTC.b on the destination EVM chain.",
|
|
1199
|
+
parameters: w,
|
|
1200
|
+
schema: u,
|
|
1190
1201
|
execute: async (t) => {
|
|
1191
|
-
const { address: e, chainId: a } =
|
|
1202
|
+
const { address: e, chainId: a } = u.parse(t), s = p(a);
|
|
1192
1203
|
return {
|
|
1193
1204
|
action: "sdk_execute",
|
|
1194
1205
|
method: "btc.generateBtcbDepositAddress",
|
|
@@ -1196,13 +1207,13 @@ const qt = {
|
|
|
1196
1207
|
description: `Generate a BTC -> BTC.b deposit address for ${e} on ${s.name}. The deposit will mint BTC.b on the destination EVM chain. Your wallet will prompt you to sign an authorization.`
|
|
1197
1208
|
};
|
|
1198
1209
|
}
|
|
1199
|
-
},
|
|
1200
|
-
name: "
|
|
1210
|
+
}, ia = {
|
|
1211
|
+
name: "prepare_btcb_to_lbtc_stake",
|
|
1201
1212
|
description: "Prepare a BTC.b → LBTC stake. Returns transaction parameters for the user's wallet to sign, or a validation failure listing what to ask the user for.",
|
|
1202
|
-
parameters:
|
|
1203
|
-
schema:
|
|
1213
|
+
parameters: at,
|
|
1214
|
+
schema: F,
|
|
1204
1215
|
execute: async (t) => {
|
|
1205
|
-
const e =
|
|
1216
|
+
const e = F.safeParse(t);
|
|
1206
1217
|
if (!e.success)
|
|
1207
1218
|
return {
|
|
1208
1219
|
valid: !1,
|
|
@@ -1210,59 +1221,86 @@ const qt = {
|
|
|
1210
1221
|
errors: e.error.issues.map((n) => n.message),
|
|
1211
1222
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1212
1223
|
};
|
|
1213
|
-
const a =
|
|
1224
|
+
const a = _t(e.data);
|
|
1214
1225
|
if (!a.valid) return a;
|
|
1215
|
-
const { amount: s, chainId:
|
|
1226
|
+
const { amount: s, chainId: o } = e.data, r = p(o);
|
|
1216
1227
|
return {
|
|
1217
1228
|
valid: !0,
|
|
1218
1229
|
action: "sdk_execute",
|
|
1219
|
-
method: "evm.
|
|
1230
|
+
method: "evm.btcbToLbtc",
|
|
1220
1231
|
params: {
|
|
1221
1232
|
amount: s,
|
|
1222
|
-
chainId:
|
|
1233
|
+
chainId: r.chainId,
|
|
1223
1234
|
assetIn: "BTCb",
|
|
1224
1235
|
assetOut: "LBTC"
|
|
1225
1236
|
},
|
|
1226
|
-
description: `Stake ${s} BTC.b to receive LBTC on ${
|
|
1237
|
+
description: `Stake ${s} BTC.b to receive LBTC on ${r.name}`
|
|
1227
1238
|
};
|
|
1228
1239
|
}
|
|
1229
|
-
},
|
|
1230
|
-
name: "
|
|
1231
|
-
description: "Prepare
|
|
1232
|
-
parameters:
|
|
1233
|
-
schema:
|
|
1240
|
+
}, ca = {
|
|
1241
|
+
name: "prepare_lbtc_to_btc",
|
|
1242
|
+
description: "Prepare a cross-chain LBTC redemption to native Bitcoin. The user MUST supply a Bitcoin destination address — do not infer or fill it from prior context. Returns either prepared transaction parameters or a validation failure listing what to ask the user for. For LBTC → BTC.b on the same EVM chain, use prepare_lbtc_to_btcb instead.",
|
|
1243
|
+
parameters: st,
|
|
1244
|
+
schema: N,
|
|
1234
1245
|
execute: async (t) => {
|
|
1235
|
-
const e =
|
|
1246
|
+
const e = N.safeParse(t);
|
|
1236
1247
|
if (!e.success)
|
|
1237
1248
|
return {
|
|
1238
1249
|
valid: !1,
|
|
1239
1250
|
missing: [],
|
|
1240
|
-
errors: e.error.issues.map((
|
|
1251
|
+
errors: e.error.issues.map((i) => i.message),
|
|
1241
1252
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1242
1253
|
};
|
|
1243
|
-
const a =
|
|
1254
|
+
const a = At(e.data);
|
|
1244
1255
|
if (!a.valid) return a;
|
|
1245
|
-
const { amount: s,
|
|
1256
|
+
const { amount: s, recipient: o, chainId: r } = e.data, n = p(r);
|
|
1246
1257
|
return {
|
|
1247
1258
|
valid: !0,
|
|
1248
1259
|
action: "sdk_execute",
|
|
1249
|
-
method: "evm.
|
|
1260
|
+
method: "evm.lbtcToBtc",
|
|
1250
1261
|
params: {
|
|
1251
1262
|
amount: s,
|
|
1252
|
-
outputAsset: r,
|
|
1253
1263
|
recipient: o,
|
|
1254
|
-
chainId:
|
|
1264
|
+
chainId: n.chainId
|
|
1255
1265
|
},
|
|
1256
|
-
description: `
|
|
1266
|
+
description: `Redeem ${s} LBTC to native BTC on ${n.name}. Destination: ${o}.`
|
|
1257
1267
|
};
|
|
1258
1268
|
}
|
|
1259
|
-
},
|
|
1269
|
+
}, da = {
|
|
1270
|
+
name: "prepare_lbtc_to_btcb",
|
|
1271
|
+
description: "Prepare a same-chain LBTC → BTC.b redemption. No Bitcoin recipient address is needed; the BTC.b is credited to the caller's wallet on the same EVM chain. For LBTC → native BTC, use prepare_lbtc_to_btc.",
|
|
1272
|
+
parameters: rt,
|
|
1273
|
+
schema: U,
|
|
1274
|
+
execute: async (t) => {
|
|
1275
|
+
const e = U.safeParse(t);
|
|
1276
|
+
if (!e.success)
|
|
1277
|
+
return {
|
|
1278
|
+
valid: !1,
|
|
1279
|
+
missing: [],
|
|
1280
|
+
errors: e.error.issues.map((n) => n.message),
|
|
1281
|
+
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1282
|
+
};
|
|
1283
|
+
const a = kt(e.data);
|
|
1284
|
+
if (!a.valid) return a;
|
|
1285
|
+
const { amount: s, chainId: o } = e.data, r = p(o);
|
|
1286
|
+
return {
|
|
1287
|
+
valid: !0,
|
|
1288
|
+
action: "sdk_execute",
|
|
1289
|
+
method: "evm.lbtcToBtcb",
|
|
1290
|
+
params: {
|
|
1291
|
+
amount: s,
|
|
1292
|
+
chainId: r.chainId
|
|
1293
|
+
},
|
|
1294
|
+
description: `Redeem ${s} LBTC to BTC.b on ${r.name} (same chain).`
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
}, la = {
|
|
1260
1298
|
name: "prepare_redeem_btcb",
|
|
1261
1299
|
description: "Prepare a redemption of BTC.b for native BTC. Distinct from prepare_unstake (which operates on LBTC). The user MUST supply a Bitcoin destination address — do not infer or fill it from prior context. Returns either prepared transaction parameters or a validation failure listing what to ask the user for.",
|
|
1262
|
-
parameters:
|
|
1263
|
-
schema:
|
|
1300
|
+
parameters: bt,
|
|
1301
|
+
schema: Z,
|
|
1264
1302
|
execute: async (t) => {
|
|
1265
|
-
const e =
|
|
1303
|
+
const e = Z.safeParse(t);
|
|
1266
1304
|
if (!e.success)
|
|
1267
1305
|
return {
|
|
1268
1306
|
valid: !1,
|
|
@@ -1270,28 +1308,28 @@ const qt = {
|
|
|
1270
1308
|
errors: e.error.issues.map((i) => i.message),
|
|
1271
1309
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1272
1310
|
};
|
|
1273
|
-
const a =
|
|
1311
|
+
const a = Lt(e.data);
|
|
1274
1312
|
if (!a.valid) return a;
|
|
1275
|
-
const { amount: s, recipient:
|
|
1313
|
+
const { amount: s, recipient: o, chainId: r } = e.data, n = p(r);
|
|
1276
1314
|
return {
|
|
1277
1315
|
valid: !0,
|
|
1278
1316
|
action: "sdk_execute",
|
|
1279
|
-
method: "evm.
|
|
1317
|
+
method: "evm.btcbToBtc",
|
|
1280
1318
|
params: {
|
|
1281
1319
|
amount: s,
|
|
1282
|
-
recipient:
|
|
1320
|
+
recipient: o,
|
|
1283
1321
|
chainId: n.chainId
|
|
1284
1322
|
},
|
|
1285
|
-
description: `Redeem ${s} BTC.b to native BTC on ${n.name}. Destination: ${
|
|
1323
|
+
description: `Redeem ${s} BTC.b to native BTC on ${n.name}. Destination: ${o}.`
|
|
1286
1324
|
};
|
|
1287
1325
|
}
|
|
1288
|
-
},
|
|
1289
|
-
name: "
|
|
1326
|
+
}, pa = {
|
|
1327
|
+
name: "prepare_earn_deposit",
|
|
1290
1328
|
description: "Prepare a transaction to deploy LBTC into Bitcoin Earn. Returns prepared transaction parameters or a validation failure.",
|
|
1291
|
-
parameters:
|
|
1292
|
-
schema:
|
|
1329
|
+
parameters: ct,
|
|
1330
|
+
schema: j,
|
|
1293
1331
|
execute: async (t) => {
|
|
1294
|
-
const e =
|
|
1332
|
+
const e = j.safeParse(t);
|
|
1295
1333
|
if (!e.success)
|
|
1296
1334
|
return {
|
|
1297
1335
|
valid: !1,
|
|
@@ -1299,24 +1337,24 @@ const qt = {
|
|
|
1299
1337
|
errors: e.error.issues.map((n) => n.message),
|
|
1300
1338
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1301
1339
|
};
|
|
1302
|
-
const a =
|
|
1340
|
+
const a = ke(e.data);
|
|
1303
1341
|
if (!a.valid) return a;
|
|
1304
|
-
const { amount: s, chainId:
|
|
1342
|
+
const { amount: s, chainId: o } = e.data, r = p(o);
|
|
1305
1343
|
return {
|
|
1306
1344
|
valid: !0,
|
|
1307
1345
|
action: "sdk_execute",
|
|
1308
|
-
method: "evm.
|
|
1309
|
-
params: { amount: s, chainId:
|
|
1310
|
-
description: `Deploy ${s} LBTC to Bitcoin Earn on ${
|
|
1346
|
+
method: "evm.earnDeposit",
|
|
1347
|
+
params: { amount: s, chainId: r.chainId, token: "LBTC" },
|
|
1348
|
+
description: `Deploy ${s} LBTC to Bitcoin Earn on ${r.name}`
|
|
1311
1349
|
};
|
|
1312
1350
|
}
|
|
1313
|
-
},
|
|
1314
|
-
name: "
|
|
1315
|
-
description: "Prepare a withdrawal from Bitcoin Earn. Only one active withdrawal is allowed per user per vault — this tool checks first and refuses if one is already queued, returning its details so you can offer the user
|
|
1316
|
-
parameters:
|
|
1317
|
-
schema:
|
|
1351
|
+
}, ua = {
|
|
1352
|
+
name: "prepare_earn_withdrawal",
|
|
1353
|
+
description: "Prepare a withdrawal from Bitcoin Earn. Only one active withdrawal is allowed per user per vault — this tool checks first and refuses if one is already queued, returning its details so you can offer the user prepare_cancel_earn_withdrawal. On success, returns prepared transaction parameters.",
|
|
1354
|
+
parameters: lt,
|
|
1355
|
+
schema: H,
|
|
1318
1356
|
execute: async (t) => {
|
|
1319
|
-
const e =
|
|
1357
|
+
const e = H.safeParse(t);
|
|
1320
1358
|
if (!e.success)
|
|
1321
1359
|
return {
|
|
1322
1360
|
valid: !1,
|
|
@@ -1324,13 +1362,13 @@ const qt = {
|
|
|
1324
1362
|
errors: e.error.issues.map((i) => i.message),
|
|
1325
1363
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1326
1364
|
};
|
|
1327
|
-
const a =
|
|
1365
|
+
const a = ke(e.data);
|
|
1328
1366
|
if (!a.valid) return a;
|
|
1329
|
-
const { amount: s, address:
|
|
1367
|
+
const { amount: s, address: o, chainId: r } = e.data, n = p(r);
|
|
1330
1368
|
try {
|
|
1331
|
-
const d = (await
|
|
1332
|
-
|
|
1333
|
-
account:
|
|
1369
|
+
const d = (await f(
|
|
1370
|
+
te({
|
|
1371
|
+
account: o,
|
|
1334
1372
|
chainId: n.chainId,
|
|
1335
1373
|
env: n.env
|
|
1336
1374
|
}),
|
|
@@ -1342,9 +1380,9 @@ const qt = {
|
|
|
1342
1380
|
valid: !1,
|
|
1343
1381
|
missing: [],
|
|
1344
1382
|
errors: [
|
|
1345
|
-
`An active withdrawal already exists for ${
|
|
1383
|
+
`An active withdrawal already exists for ${o} on ${n.name}: ${d.shareAmount.toString()} shares queued (request tx ${d.txHash}). Only one active withdrawal is allowed per vault.`
|
|
1346
1384
|
],
|
|
1347
|
-
note: `Tell the user about the existing withdrawal (shareAmount=${d.shareAmount.toString()}, txHash=${d.txHash}, deadline=${d.deadline}) and ask whether they want to cancel it via
|
|
1385
|
+
note: `Tell the user about the existing withdrawal (shareAmount=${d.shareAmount.toString()}, txHash=${d.txHash}, deadline=${d.deadline}) and ask whether they want to cancel it via prepare_cancel_earn_withdrawal before queuing a new one. Do not retry prepare_earn_withdrawal until they confirm.`
|
|
1348
1386
|
};
|
|
1349
1387
|
} catch (i) {
|
|
1350
1388
|
return {
|
|
@@ -1353,26 +1391,26 @@ const qt = {
|
|
|
1353
1391
|
errors: [
|
|
1354
1392
|
i instanceof Error ? `Could not verify active withdrawals: ${i.message}` : "Could not verify active withdrawals."
|
|
1355
1393
|
],
|
|
1356
|
-
note: "The active-withdrawal check failed. Tell the user this is a backend issue, suggest they run
|
|
1394
|
+
note: "The active-withdrawal check failed. Tell the user this is a backend issue, suggest they run get_earn_withdrawals manually to confirm no active withdrawal exists, and only proceed with prepare_earn_withdrawal after they confirm."
|
|
1357
1395
|
};
|
|
1358
1396
|
}
|
|
1359
1397
|
return {
|
|
1360
1398
|
valid: !0,
|
|
1361
1399
|
action: "sdk_execute",
|
|
1362
|
-
method: "evm.
|
|
1400
|
+
method: "evm.earnWithdrawal",
|
|
1363
1401
|
params: { amount: s, chainId: n.chainId },
|
|
1364
1402
|
description: `Withdraw ${s} shares from Bitcoin Earn on ${n.name}. Withdrawals are queued and may take time to process.`
|
|
1365
1403
|
};
|
|
1366
1404
|
}
|
|
1367
|
-
},
|
|
1405
|
+
}, ha = {
|
|
1368
1406
|
name: "get_lbtc_apy",
|
|
1369
1407
|
description: "Get the current LBTC base staking APY (annual percentage yield). Returns both the base and effective APY for LBTC staking.",
|
|
1370
|
-
parameters:
|
|
1371
|
-
schema:
|
|
1408
|
+
parameters: dt,
|
|
1409
|
+
schema: Be,
|
|
1372
1410
|
execute: async () => {
|
|
1373
1411
|
try {
|
|
1374
|
-
const t = await
|
|
1375
|
-
|
|
1412
|
+
const t = await f(
|
|
1413
|
+
je({ env: h.prod }),
|
|
1376
1414
|
1e4,
|
|
1377
1415
|
"getApy"
|
|
1378
1416
|
), e = t.baseApy.multipliedBy(100).toFixed(2), a = t.effectiveApy.multipliedBy(100).toFixed(2);
|
|
@@ -1390,46 +1428,46 @@ const qt = {
|
|
|
1390
1428
|
};
|
|
1391
1429
|
}
|
|
1392
1430
|
}
|
|
1393
|
-
},
|
|
1394
|
-
name: "
|
|
1431
|
+
}, ma = {
|
|
1432
|
+
name: "get_earn_positions",
|
|
1395
1433
|
description: "Get a user's Bitcoin Earn positions including shares held and their estimated LBTC value. Currently supports Bitcoin Earn on Ethereum mainnet.",
|
|
1396
|
-
parameters:
|
|
1397
|
-
schema:
|
|
1434
|
+
parameters: w,
|
|
1435
|
+
schema: u,
|
|
1398
1436
|
execute: async (t) => {
|
|
1399
|
-
const { address: e, chainId: a } =
|
|
1437
|
+
const { address: e, chainId: a } = u.parse(t), s = p(a);
|
|
1400
1438
|
try {
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1439
|
+
const o = await f(
|
|
1440
|
+
He({ address: e, chainId: s.chainId }),
|
|
1403
1441
|
1e4,
|
|
1404
1442
|
"getEarnPosition"
|
|
1405
1443
|
);
|
|
1406
1444
|
return {
|
|
1407
|
-
shares:
|
|
1408
|
-
shareValue:
|
|
1409
|
-
estimatedLbtcValue:
|
|
1445
|
+
shares: o.totalShares.toString(),
|
|
1446
|
+
shareValue: o.exchangeRate.toString(),
|
|
1447
|
+
estimatedLbtcValue: o.position.toString(),
|
|
1410
1448
|
vault: "Bitcoin Earn",
|
|
1411
1449
|
chain: s.name
|
|
1412
1450
|
};
|
|
1413
|
-
} catch (
|
|
1451
|
+
} catch (o) {
|
|
1414
1452
|
return {
|
|
1415
1453
|
shares: "",
|
|
1416
1454
|
shareValue: "",
|
|
1417
1455
|
estimatedLbtcValue: "",
|
|
1418
1456
|
vault: "Bitcoin Earn",
|
|
1419
1457
|
chain: s.name,
|
|
1420
|
-
error:
|
|
1458
|
+
error: o instanceof Error ? o.message : "Failed to fetch vault positions"
|
|
1421
1459
|
};
|
|
1422
1460
|
}
|
|
1423
1461
|
}
|
|
1424
|
-
},
|
|
1425
|
-
name: "
|
|
1462
|
+
}, ba = {
|
|
1463
|
+
name: "prepare_claim_lbtc_deposit",
|
|
1426
1464
|
description: "Prepare a transaction to claim (mint) LBTC from a notarized BTC deposit. Checks if the deposit is claimable and returns the transaction parameters for wallet signing.",
|
|
1427
|
-
parameters:
|
|
1428
|
-
schema:
|
|
1465
|
+
parameters: pt,
|
|
1466
|
+
schema: z,
|
|
1429
1467
|
execute: async (t) => {
|
|
1430
|
-
const { depositTxHash: e, address: a, chainId: s } =
|
|
1468
|
+
const { depositTxHash: e, address: a, chainId: s } = z.parse(t), o = p(s), n = (await fe({
|
|
1431
1469
|
address: a,
|
|
1432
|
-
env:
|
|
1470
|
+
env: o.env
|
|
1433
1471
|
})).find((d) => d.txHash === e);
|
|
1434
1472
|
if (!n)
|
|
1435
1473
|
return {
|
|
@@ -1439,14 +1477,14 @@ const qt = {
|
|
|
1439
1477
|
depositTxHash: e,
|
|
1440
1478
|
rawPayload: "",
|
|
1441
1479
|
proofSignature: "",
|
|
1442
|
-
chainId:
|
|
1480
|
+
chainId: o.chainId
|
|
1443
1481
|
},
|
|
1444
1482
|
description: "",
|
|
1445
1483
|
error: "Could not find a deposit with this transaction hash for the given address. Use get_deposit_status to verify the transaction hash."
|
|
1446
1484
|
};
|
|
1447
|
-
const i =
|
|
1485
|
+
const i = ye(n);
|
|
1448
1486
|
if (i !== "claimable") {
|
|
1449
|
-
const d =
|
|
1487
|
+
const d = ge(i);
|
|
1450
1488
|
return {
|
|
1451
1489
|
action: "error",
|
|
1452
1490
|
method: "",
|
|
@@ -1454,7 +1492,7 @@ const qt = {
|
|
|
1454
1492
|
depositTxHash: e,
|
|
1455
1493
|
rawPayload: "",
|
|
1456
1494
|
proofSignature: "",
|
|
1457
|
-
chainId:
|
|
1495
|
+
chainId: o.chainId
|
|
1458
1496
|
},
|
|
1459
1497
|
description: "",
|
|
1460
1498
|
error: `Deposit is not claimable. Current status: ${d.label}. ${d.description}`
|
|
@@ -1462,23 +1500,23 @@ const qt = {
|
|
|
1462
1500
|
}
|
|
1463
1501
|
return {
|
|
1464
1502
|
action: "sdk_execute",
|
|
1465
|
-
method: "evm.
|
|
1503
|
+
method: "evm.claimLbtcDeposit",
|
|
1466
1504
|
params: {
|
|
1467
1505
|
depositTxHash: e,
|
|
1468
1506
|
rawPayload: n.rawPayload,
|
|
1469
1507
|
proofSignature: n.proof,
|
|
1470
|
-
chainId:
|
|
1508
|
+
chainId: o.chainId
|
|
1471
1509
|
},
|
|
1472
|
-
description: `Claim LBTC from deposit ${e.slice(0, 10)}... on ${
|
|
1510
|
+
description: `Claim LBTC from deposit ${e.slice(0, 10)}... on ${o.name}. Your wallet will prompt you to sign the mint transaction.`
|
|
1473
1511
|
};
|
|
1474
1512
|
}
|
|
1475
|
-
},
|
|
1476
|
-
name: "
|
|
1513
|
+
}, fa = {
|
|
1514
|
+
name: "prepare_cancel_earn_withdrawal",
|
|
1477
1515
|
description: "Cancel an active Bitcoin Earn withdrawal that has not yet been processed. Looks up the user's active withdrawal first; refuses if none exists, includes its details in the description if one does, then returns the cancel transaction parameters.",
|
|
1478
|
-
parameters:
|
|
1479
|
-
schema:
|
|
1516
|
+
parameters: et,
|
|
1517
|
+
schema: Y,
|
|
1480
1518
|
execute: async (t) => {
|
|
1481
|
-
const e =
|
|
1519
|
+
const e = Y.safeParse(t);
|
|
1482
1520
|
if (!e.success)
|
|
1483
1521
|
return {
|
|
1484
1522
|
valid: !1,
|
|
@@ -1486,14 +1524,14 @@ const qt = {
|
|
|
1486
1524
|
errors: e.error.issues.map((n) => n.message),
|
|
1487
1525
|
note: "Surface the listed errors to the user and re-prompt with valid input."
|
|
1488
1526
|
};
|
|
1489
|
-
const { address: a, chainId: s } = e.data,
|
|
1490
|
-
let
|
|
1527
|
+
const { address: a, chainId: s } = e.data, o = p(s);
|
|
1528
|
+
let r = "";
|
|
1491
1529
|
try {
|
|
1492
|
-
const i = (await
|
|
1493
|
-
|
|
1530
|
+
const i = (await f(
|
|
1531
|
+
te({
|
|
1494
1532
|
account: a,
|
|
1495
|
-
chainId:
|
|
1496
|
-
env:
|
|
1533
|
+
chainId: o.chainId,
|
|
1534
|
+
env: o.env
|
|
1497
1535
|
}),
|
|
1498
1536
|
15e3,
|
|
1499
1537
|
"getEarnWithdrawals"
|
|
@@ -1503,11 +1541,11 @@ const qt = {
|
|
|
1503
1541
|
valid: !1,
|
|
1504
1542
|
missing: [],
|
|
1505
1543
|
errors: [
|
|
1506
|
-
`No active withdrawal found for ${a} on ${
|
|
1544
|
+
`No active withdrawal found for ${a} on ${o.name}. There is nothing to cancel.`
|
|
1507
1545
|
],
|
|
1508
|
-
note: "Tell the user there is no active withdrawal to cancel. If they think there should be, suggest
|
|
1546
|
+
note: "Tell the user there is no active withdrawal to cancel. If they think there should be, suggest get_earn_withdrawals to inspect their full withdrawal history."
|
|
1509
1547
|
};
|
|
1510
|
-
|
|
1548
|
+
r = ` Active withdrawal: ${i.shareAmount.toString()} shares (request tx ${i.txHash}, deadline ${i.deadline}).`;
|
|
1511
1549
|
} catch (n) {
|
|
1512
1550
|
return {
|
|
1513
1551
|
valid: !1,
|
|
@@ -1515,127 +1553,277 @@ const qt = {
|
|
|
1515
1553
|
errors: [
|
|
1516
1554
|
n instanceof Error ? `Could not verify active withdrawals before cancelling: ${n.message}` : "Could not verify active withdrawals before cancelling."
|
|
1517
1555
|
],
|
|
1518
|
-
note: "Backend issue. Ask the user to retry in a moment, or to verify via
|
|
1556
|
+
note: "Backend issue. Ask the user to retry in a moment, or to verify via get_earn_withdrawals first."
|
|
1519
1557
|
};
|
|
1520
1558
|
}
|
|
1521
1559
|
return {
|
|
1522
1560
|
valid: !0,
|
|
1523
1561
|
action: "sdk_execute",
|
|
1524
|
-
method: "evm.
|
|
1525
|
-
params: { chainId:
|
|
1526
|
-
description: `Cancel pending Bitcoin Earn withdrawal on ${
|
|
1562
|
+
method: "evm.cancelEarnWithdrawal",
|
|
1563
|
+
params: { chainId: o.chainId },
|
|
1564
|
+
description: `Cancel pending Bitcoin Earn withdrawal on ${o.name}.${r} Your wallet will prompt you to sign the cancellation transaction.`
|
|
1527
1565
|
};
|
|
1528
1566
|
}
|
|
1529
|
-
},
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1567
|
+
}, ya = {
|
|
1568
|
+
name: "get_earn_withdrawals",
|
|
1569
|
+
description: "Get all vault withdrawals for an address, including open (pending), fulfilled, cancelled, and expired withdrawals.",
|
|
1570
|
+
parameters: w,
|
|
1571
|
+
schema: u,
|
|
1572
|
+
execute: async (t) => {
|
|
1573
|
+
const { address: e, chainId: a } = u.parse(t), s = p(a);
|
|
1574
|
+
try {
|
|
1575
|
+
const o = await f(
|
|
1576
|
+
te({
|
|
1577
|
+
account: e,
|
|
1578
|
+
chainId: s.chainId,
|
|
1579
|
+
env: s.env
|
|
1580
|
+
}),
|
|
1581
|
+
15e3,
|
|
1582
|
+
"getEarnWithdrawals"
|
|
1583
|
+
);
|
|
1584
|
+
return {
|
|
1585
|
+
withdrawals: {
|
|
1586
|
+
open: o.open.map((r) => ({
|
|
1587
|
+
txHash: r.txHash,
|
|
1588
|
+
shareAmount: r.shareAmount.toString(),
|
|
1589
|
+
deadline: r.deadline,
|
|
1590
|
+
timestamp: r.timestamp
|
|
1591
|
+
})),
|
|
1592
|
+
fulfilled: o.fulfilled.map((r) => {
|
|
1593
|
+
var n;
|
|
1594
|
+
return {
|
|
1595
|
+
txHash: r.txHash,
|
|
1596
|
+
shareAmount: r.shareAmount.toString(),
|
|
1597
|
+
amount: ((n = r.amount) == null ? void 0 : n.toString()) ?? "unknown",
|
|
1598
|
+
fulfilledTxHash: r.fulfilledTxHash ?? null
|
|
1599
|
+
};
|
|
1600
|
+
}),
|
|
1601
|
+
cancelled: o.cancelled.map((r) => ({
|
|
1602
|
+
txHash: r.txHash,
|
|
1603
|
+
shareAmount: r.shareAmount.toString(),
|
|
1604
|
+
timestamp: r.timestamp
|
|
1605
|
+
})),
|
|
1606
|
+
expired: o.expired.map((r) => ({
|
|
1607
|
+
txHash: r.txHash,
|
|
1608
|
+
shareAmount: r.shareAmount.toString(),
|
|
1609
|
+
timestamp: r.timestamp
|
|
1610
|
+
}))
|
|
1611
|
+
},
|
|
1612
|
+
chain: s.name
|
|
1613
|
+
};
|
|
1614
|
+
} catch (o) {
|
|
1615
|
+
return {
|
|
1616
|
+
withdrawals: { open: [], fulfilled: [], cancelled: [], expired: [] },
|
|
1617
|
+
chain: s.name,
|
|
1618
|
+
error: o instanceof Error ? o.message : "Failed to fetch vault withdrawals"
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
}, ga = {
|
|
1623
|
+
name: "get_lux_points",
|
|
1624
|
+
description: "Get the Lux reward points for a wallet address. Returns the current season's points including holding, protocol, referral, and badge points.",
|
|
1625
|
+
parameters: Ce,
|
|
1626
|
+
schema: k,
|
|
1627
|
+
execute: async (t) => {
|
|
1628
|
+
const { address: e } = k.parse(t);
|
|
1629
|
+
try {
|
|
1630
|
+
const a = await f(
|
|
1631
|
+
ze({
|
|
1632
|
+
address: e,
|
|
1633
|
+
env: h.prod,
|
|
1634
|
+
season: 2
|
|
1635
|
+
}),
|
|
1636
|
+
1e4,
|
|
1637
|
+
"getPointsByAddress"
|
|
1638
|
+
);
|
|
1639
|
+
return {
|
|
1640
|
+
points: {
|
|
1641
|
+
totalPoints: a.totalPoints,
|
|
1642
|
+
holdingPoints: a.holdingPoints,
|
|
1643
|
+
protocolPoints: a.protocolPoints,
|
|
1644
|
+
referralPoints: a.referralPoints,
|
|
1645
|
+
badgesPoints: a.badgesPoints,
|
|
1646
|
+
protocolPointsBreakdown: a.protocolPointsBreakdown
|
|
1647
|
+
},
|
|
1648
|
+
season: 2
|
|
1649
|
+
};
|
|
1650
|
+
} catch (a) {
|
|
1651
|
+
return {
|
|
1652
|
+
points: {
|
|
1653
|
+
totalPoints: 0,
|
|
1654
|
+
holdingPoints: 0,
|
|
1655
|
+
protocolPoints: 0,
|
|
1656
|
+
referralPoints: 0,
|
|
1657
|
+
badgesPoints: 0,
|
|
1658
|
+
protocolPointsBreakdown: {}
|
|
1659
|
+
},
|
|
1660
|
+
season: 2,
|
|
1661
|
+
error: a instanceof Error ? a.message : "Failed to fetch Lux points"
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
}, wa = {
|
|
1666
|
+
name: "get_positions_summary",
|
|
1667
|
+
description: "Get an aggregated portfolio summary for a wallet address, including total BTC value, profit/loss, and a breakdown of individual positions (holdings and DeFi).",
|
|
1668
|
+
parameters: Ce,
|
|
1669
|
+
schema: k,
|
|
1670
|
+
execute: async (t) => {
|
|
1671
|
+
const { address: e } = k.parse(t);
|
|
1672
|
+
try {
|
|
1673
|
+
const a = await f(
|
|
1674
|
+
Ze({
|
|
1675
|
+
account: e,
|
|
1676
|
+
env: h.prod
|
|
1677
|
+
}),
|
|
1678
|
+
1e4,
|
|
1679
|
+
"getPositionsSummary"
|
|
1680
|
+
);
|
|
1681
|
+
return {
|
|
1682
|
+
btcPriceUsd: a.btcPrice.price.toString(),
|
|
1683
|
+
btcValue: a.btcValue.toString(),
|
|
1684
|
+
btcPnl: a.btcPnl.toString(),
|
|
1685
|
+
positions: a.snapshot.map((s) => ({
|
|
1686
|
+
token: s.token,
|
|
1687
|
+
type: s.type,
|
|
1688
|
+
balance: s.balance.toString(),
|
|
1689
|
+
pnl: s.pnl.toString(),
|
|
1690
|
+
rate: s.rate.toString()
|
|
1691
|
+
})),
|
|
1692
|
+
lastUpdated: a.lastUpdated.toISOString(),
|
|
1693
|
+
inProgress: a.inProgress
|
|
1694
|
+
};
|
|
1695
|
+
} catch (a) {
|
|
1696
|
+
return {
|
|
1697
|
+
btcPriceUsd: "",
|
|
1698
|
+
btcValue: "",
|
|
1699
|
+
btcPnl: "",
|
|
1700
|
+
positions: [],
|
|
1701
|
+
lastUpdated: "",
|
|
1702
|
+
inProgress: !1,
|
|
1703
|
+
error: a instanceof Error ? a.message : "Failed to fetch positions summary"
|
|
1704
|
+
};
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}, Ba = [
|
|
1533
1708
|
Zt,
|
|
1534
1709
|
Yt,
|
|
1535
|
-
Vt,
|
|
1536
|
-
jt,
|
|
1537
|
-
Ht,
|
|
1538
|
-
Wt,
|
|
1539
|
-
Gt,
|
|
1540
1710
|
Jt,
|
|
1541
|
-
Xt,
|
|
1542
1711
|
Qt,
|
|
1712
|
+
Xt,
|
|
1713
|
+
Wt,
|
|
1714
|
+
Gt,
|
|
1715
|
+
Kt,
|
|
1543
1716
|
ea,
|
|
1544
|
-
ta,
|
|
1545
1717
|
aa,
|
|
1546
1718
|
sa,
|
|
1547
1719
|
ra,
|
|
1548
1720
|
oa,
|
|
1549
|
-
da,
|
|
1550
1721
|
na,
|
|
1551
1722
|
ia,
|
|
1552
1723
|
ca,
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1724
|
+
da,
|
|
1725
|
+
la,
|
|
1726
|
+
pa,
|
|
1727
|
+
ua,
|
|
1728
|
+
fa,
|
|
1729
|
+
ha,
|
|
1730
|
+
ma,
|
|
1731
|
+
ba,
|
|
1732
|
+
Ot,
|
|
1733
|
+
Vt,
|
|
1734
|
+
jt,
|
|
1735
|
+
Ht,
|
|
1736
|
+
zt,
|
|
1737
|
+
ya,
|
|
1738
|
+
ga,
|
|
1739
|
+
wa
|
|
1740
|
+
], La = Object.fromEntries(Ba.map((t) => [t.name, t]));
|
|
1559
1741
|
export {
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1742
|
+
Yt as $,
|
|
1743
|
+
w as A,
|
|
1744
|
+
ot as B,
|
|
1745
|
+
Qe as C,
|
|
1746
|
+
ct as D,
|
|
1747
|
+
tt as E,
|
|
1748
|
+
at as F,
|
|
1749
|
+
F as G,
|
|
1750
|
+
nt as H,
|
|
1751
|
+
O as I,
|
|
1752
|
+
G as J,
|
|
1753
|
+
mt as K,
|
|
1754
|
+
_a as L,
|
|
1755
|
+
gt as M,
|
|
1756
|
+
Te as N,
|
|
1757
|
+
ut as O,
|
|
1758
|
+
H as P,
|
|
1759
|
+
Ba as Q,
|
|
1760
|
+
bt as R,
|
|
1761
|
+
he as S,
|
|
1762
|
+
ht as T,
|
|
1763
|
+
g as U,
|
|
1764
|
+
lt as V,
|
|
1765
|
+
Xe as W,
|
|
1766
|
+
y as X,
|
|
1767
|
+
ra as Y,
|
|
1768
|
+
b as Z,
|
|
1769
|
+
Jt as _,
|
|
1770
|
+
u as a,
|
|
1771
|
+
p as a0,
|
|
1772
|
+
sa as a1,
|
|
1773
|
+
Gt as a2,
|
|
1774
|
+
ma as a3,
|
|
1775
|
+
ea as a4,
|
|
1776
|
+
ya as a5,
|
|
1777
|
+
Wt as a6,
|
|
1778
|
+
ha as a7,
|
|
1597
1779
|
Zt as a8,
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1780
|
+
aa as a9,
|
|
1781
|
+
ga as aa,
|
|
1782
|
+
Ot as ab,
|
|
1783
|
+
zt as ac,
|
|
1784
|
+
wa as ad,
|
|
1785
|
+
Kt as ae,
|
|
1786
|
+
Qt as af,
|
|
1787
|
+
Xt as ag,
|
|
1788
|
+
na as ah,
|
|
1789
|
+
oa as ai,
|
|
1790
|
+
ia as aj,
|
|
1791
|
+
fa as ak,
|
|
1792
|
+
ba as al,
|
|
1793
|
+
pa as am,
|
|
1794
|
+
ua as an,
|
|
1795
|
+
ca as ao,
|
|
1796
|
+
da as ap,
|
|
1797
|
+
jt as aq,
|
|
1798
|
+
Ht as ar,
|
|
1799
|
+
Vt as as,
|
|
1800
|
+
la as at,
|
|
1801
|
+
Je as au,
|
|
1802
|
+
Ke as av,
|
|
1803
|
+
La as aw,
|
|
1804
|
+
q as b,
|
|
1805
|
+
pt as c,
|
|
1806
|
+
z as d,
|
|
1807
|
+
j as e,
|
|
1808
|
+
it as f,
|
|
1809
|
+
V as g,
|
|
1810
|
+
D as h,
|
|
1811
|
+
E as i,
|
|
1812
|
+
dt as j,
|
|
1813
|
+
Be as k,
|
|
1814
|
+
st as l,
|
|
1815
|
+
N as m,
|
|
1816
|
+
rt as n,
|
|
1817
|
+
U as o,
|
|
1630
1818
|
J as p,
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1819
|
+
ft as q,
|
|
1820
|
+
ve as r,
|
|
1821
|
+
Bt as s,
|
|
1822
|
+
Q as t,
|
|
1823
|
+
wt as u,
|
|
1824
|
+
X as v,
|
|
1825
|
+
yt as w,
|
|
1826
|
+
K as x,
|
|
1827
|
+
W as y,
|
|
1828
|
+
Z as z
|
|
1641
1829
|
};
|