@moonpay/cli 0.4.2 → 0.5.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/dist/chunk-AH5VMN63.js +6608 -0
- package/dist/chunk-AH5VMN63.js.map +1 -0
- package/dist/chunk-V7MA7WNX.js +441 -0
- package/dist/chunk-V7MA7WNX.js.map +1 -0
- package/dist/index.js +145 -51
- package/dist/index.js.map +1 -1
- package/dist/{mcp-QLBMU7OH.js → mcp-VOEHXIOY.js} +66 -46
- package/dist/mcp-VOEHXIOY.js.map +1 -0
- package/dist/store-HCN56E6A.js +22 -0
- package/package.json +4 -2
- package/skills/moonpay-auth/SKILL.md +19 -28
- package/skills/moonpay-missions/SKILL.md +31 -38
- package/skills/moonpay-swap-tokens/SKILL.md +52 -42
- package/skills/moonpay-virtual-account/SKILL.md +18 -81
- package/dist/chains-R754DQM5.js +0 -13
- package/dist/chunk-AGDVU2O5.js +0 -168
- package/dist/chunk-AGDVU2O5.js.map +0 -1
- package/dist/chunk-DAQDHLPY.js +0 -2444
- package/dist/chunk-DAQDHLPY.js.map +0 -1
- package/dist/chunk-EEBB5MQP.js +0 -12
- package/dist/chunk-EEBB5MQP.js.map +0 -1
- package/dist/chunk-Z33PSOPD.js +0 -128
- package/dist/chunk-Z33PSOPD.js.map +0 -1
- package/dist/mcp-QLBMU7OH.js.map +0 -1
- package/dist/server-IUOCZFT7.js +0 -21
- package/dist/server-IUOCZFT7.js.map +0 -1
- /package/dist/{chains-R754DQM5.js.map → store-HCN56E6A.js.map} +0 -0
package/dist/chunk-DAQDHLPY.js
DELETED
|
@@ -1,2444 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
KEY_CHAIN_MAP,
|
|
4
|
-
chainSchema,
|
|
5
|
-
deleteWalletFile,
|
|
6
|
-
keyChainSchema,
|
|
7
|
-
loadAllWallets,
|
|
8
|
-
loadWallet,
|
|
9
|
-
lockedVaultDataSchema,
|
|
10
|
-
saveWalletMetadata,
|
|
11
|
-
vaultDataSchema,
|
|
12
|
-
walletInfoSchema
|
|
13
|
-
} from "./chunk-AGDVU2O5.js";
|
|
14
|
-
import {
|
|
15
|
-
deriveAllAddresses,
|
|
16
|
-
deriveKeyForChain
|
|
17
|
-
} from "./chunk-Z33PSOPD.js";
|
|
18
|
-
import {
|
|
19
|
-
__require
|
|
20
|
-
} from "./chunk-EEBB5MQP.js";
|
|
21
|
-
|
|
22
|
-
// src/auth.ts
|
|
23
|
-
import { spawn } from "child_process";
|
|
24
|
-
import * as crypto from "crypto";
|
|
25
|
-
import * as fs from "fs";
|
|
26
|
-
import * as os from "os";
|
|
27
|
-
import * as path from "path";
|
|
28
|
-
import { createInterface } from "readline";
|
|
29
|
-
function generateCodeVerifier() {
|
|
30
|
-
return crypto.randomBytes(32).toString("base64url");
|
|
31
|
-
}
|
|
32
|
-
function generateCodeChallenge(verifier) {
|
|
33
|
-
return crypto.createHash("sha256").update(verifier).digest("base64url");
|
|
34
|
-
}
|
|
35
|
-
var CONFIG_DIR = path.join(os.homedir(), ".config", "moonpay");
|
|
36
|
-
var CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
37
|
-
var CREDENTIALS_PATH = path.join(CONFIG_DIR, "credentials.json");
|
|
38
|
-
var LOCK_PATH = path.join(CONFIG_DIR, ".credentials.lock");
|
|
39
|
-
var DEFAULT_CONFIG = {
|
|
40
|
-
baseUrl: "https://agents.moonpay.com",
|
|
41
|
-
clientId: "mooniq_zin3s5jz3olzkdfxpmbeaogv"
|
|
42
|
-
};
|
|
43
|
-
function ensureConfigDir() {
|
|
44
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
45
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function atomicWriteFileSync(filePath, data, mode) {
|
|
49
|
-
const tmp = filePath + `.tmp.${process.pid}`;
|
|
50
|
-
fs.writeFileSync(tmp, data, { encoding: "utf-8", mode });
|
|
51
|
-
fs.renameSync(tmp, filePath);
|
|
52
|
-
}
|
|
53
|
-
var LOCK_STALE_MS = 3e4;
|
|
54
|
-
function acquireLock() {
|
|
55
|
-
ensureConfigDir();
|
|
56
|
-
try {
|
|
57
|
-
const fd = fs.openSync(LOCK_PATH, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY, 384);
|
|
58
|
-
fs.writeSync(fd, JSON.stringify({ pid: process.pid, ts: Date.now() }));
|
|
59
|
-
fs.closeSync(fd);
|
|
60
|
-
} catch (err) {
|
|
61
|
-
if (err.code !== "EEXIST") throw err;
|
|
62
|
-
try {
|
|
63
|
-
const lockData = JSON.parse(fs.readFileSync(LOCK_PATH, "utf-8"));
|
|
64
|
-
if (Date.now() - lockData.ts < LOCK_STALE_MS) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
} catch {
|
|
68
|
-
}
|
|
69
|
-
try {
|
|
70
|
-
fs.unlinkSync(LOCK_PATH);
|
|
71
|
-
} catch {
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
const fd = fs.openSync(LOCK_PATH, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY, 384);
|
|
75
|
-
fs.writeSync(fd, JSON.stringify({ pid: process.pid, ts: Date.now() }));
|
|
76
|
-
fs.closeSync(fd);
|
|
77
|
-
} catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return () => {
|
|
82
|
-
try {
|
|
83
|
-
fs.unlinkSync(LOCK_PATH);
|
|
84
|
-
} catch {
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function getConfig() {
|
|
89
|
-
if (!fs.existsSync(CONFIG_PATH)) return null;
|
|
90
|
-
try {
|
|
91
|
-
const data = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
|
|
92
|
-
if (!data.baseUrl || !data.clientId) return null;
|
|
93
|
-
return data;
|
|
94
|
-
} catch {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function getConfigOrDefault() {
|
|
99
|
-
const fromFile = getConfig();
|
|
100
|
-
if (fromFile) return fromFile;
|
|
101
|
-
saveConfig(DEFAULT_CONFIG);
|
|
102
|
-
return DEFAULT_CONFIG;
|
|
103
|
-
}
|
|
104
|
-
function getCredentials() {
|
|
105
|
-
if (!fs.existsSync(CREDENTIALS_PATH)) return null;
|
|
106
|
-
try {
|
|
107
|
-
const data = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, "utf-8"));
|
|
108
|
-
if (!data.accessToken || !data.baseUrl) return null;
|
|
109
|
-
return data;
|
|
110
|
-
} catch {
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function saveCredentials(creds) {
|
|
115
|
-
ensureConfigDir();
|
|
116
|
-
atomicWriteFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), 384);
|
|
117
|
-
}
|
|
118
|
-
function saveConfig(config) {
|
|
119
|
-
ensureConfigDir();
|
|
120
|
-
atomicWriteFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 384);
|
|
121
|
-
}
|
|
122
|
-
function clearCredentials() {
|
|
123
|
-
if (fs.existsSync(CREDENTIALS_PATH)) {
|
|
124
|
-
fs.unlinkSync(CREDENTIALS_PATH);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
function resolveBaseUrl() {
|
|
128
|
-
const config = getConfig();
|
|
129
|
-
const creds = getCredentials();
|
|
130
|
-
return config?.baseUrl ?? creds?.baseUrl ?? DEFAULT_CONFIG.baseUrl;
|
|
131
|
-
}
|
|
132
|
-
function openBrowser(url) {
|
|
133
|
-
const platform = process.platform;
|
|
134
|
-
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
135
|
-
const args = platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
136
|
-
try {
|
|
137
|
-
spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
|
|
138
|
-
return true;
|
|
139
|
-
} catch {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
function promptLine(prompt) {
|
|
144
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
145
|
-
return new Promise((resolve) => {
|
|
146
|
-
rl.question(prompt, (answer) => {
|
|
147
|
-
rl.close();
|
|
148
|
-
resolve(answer.trim());
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
var LOGIN_STATE_PATH = path.join(CONFIG_DIR, ".login-state.json");
|
|
153
|
-
async function login(config, options = {}) {
|
|
154
|
-
const callbackUrl = `${config.baseUrl}/callback`;
|
|
155
|
-
if (options.code) {
|
|
156
|
-
const stateData = loadLoginState();
|
|
157
|
-
if (!stateData) {
|
|
158
|
-
throw new Error("No pending login found. Run `mp login --no-browser` first.");
|
|
159
|
-
}
|
|
160
|
-
return exchangeCode(config, options.code, callbackUrl, stateData.codeVerifier);
|
|
161
|
-
}
|
|
162
|
-
const state = crypto.randomUUID();
|
|
163
|
-
const usePkce = !config.clientSecret;
|
|
164
|
-
let codeVerifier;
|
|
165
|
-
if (usePkce) {
|
|
166
|
-
codeVerifier = generateCodeVerifier();
|
|
167
|
-
}
|
|
168
|
-
const authorizeParams = new URLSearchParams({
|
|
169
|
-
client_id: config.clientId,
|
|
170
|
-
redirect_uri: callbackUrl,
|
|
171
|
-
response_type: "code",
|
|
172
|
-
scope: "profile email",
|
|
173
|
-
state
|
|
174
|
-
});
|
|
175
|
-
if (usePkce && codeVerifier) {
|
|
176
|
-
authorizeParams.set("code_challenge", generateCodeChallenge(codeVerifier));
|
|
177
|
-
authorizeParams.set("code_challenge_method", "S256");
|
|
178
|
-
}
|
|
179
|
-
const authorizeUrl = `${config.baseUrl}/authorize?${authorizeParams.toString()}`;
|
|
180
|
-
saveLoginState({ state, codeVerifier: codeVerifier ?? null });
|
|
181
|
-
const opened = options.noBrowser ? false : openBrowser(authorizeUrl);
|
|
182
|
-
console.log("Open this URL in your browser to log in:\n");
|
|
183
|
-
console.log(` ${authorizeUrl}
|
|
184
|
-
`);
|
|
185
|
-
if (options.noBrowser) {
|
|
186
|
-
console.log("Tip: you can run `open <url>` to open it directly.");
|
|
187
|
-
console.log("After authorizing, copy the code and run:\n");
|
|
188
|
-
console.log(" mp login --code <paste-code-here>\n");
|
|
189
|
-
process.exit(0);
|
|
190
|
-
}
|
|
191
|
-
const code = await promptLine("Paste code: ");
|
|
192
|
-
if (!code) {
|
|
193
|
-
throw new Error("No authorization code provided.");
|
|
194
|
-
}
|
|
195
|
-
return exchangeCode(config, code, callbackUrl, codeVerifier ?? null);
|
|
196
|
-
}
|
|
197
|
-
function saveLoginState(state) {
|
|
198
|
-
ensureConfigDir();
|
|
199
|
-
atomicWriteFileSync(LOGIN_STATE_PATH, JSON.stringify(state), 384);
|
|
200
|
-
}
|
|
201
|
-
function loadLoginState() {
|
|
202
|
-
if (!fs.existsSync(LOGIN_STATE_PATH)) return null;
|
|
203
|
-
try {
|
|
204
|
-
const data = JSON.parse(fs.readFileSync(LOGIN_STATE_PATH, "utf-8"));
|
|
205
|
-
fs.unlinkSync(LOGIN_STATE_PATH);
|
|
206
|
-
return data;
|
|
207
|
-
} catch {
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
async function exchangeCode(config, code, callbackUrl, codeVerifier) {
|
|
212
|
-
const tokenParams = {
|
|
213
|
-
grant_type: "authorization_code",
|
|
214
|
-
code,
|
|
215
|
-
client_id: config.clientId,
|
|
216
|
-
redirect_uri: callbackUrl
|
|
217
|
-
};
|
|
218
|
-
if (config.clientSecret) {
|
|
219
|
-
tokenParams.client_secret = config.clientSecret;
|
|
220
|
-
}
|
|
221
|
-
if (codeVerifier) {
|
|
222
|
-
tokenParams.code_verifier = codeVerifier;
|
|
223
|
-
}
|
|
224
|
-
const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {
|
|
225
|
-
method: "POST",
|
|
226
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
227
|
-
body: new URLSearchParams(tokenParams)
|
|
228
|
-
});
|
|
229
|
-
if (!tokenResponse.ok) {
|
|
230
|
-
const err = await tokenResponse.json().catch(() => ({}));
|
|
231
|
-
const msg = err.error_description ?? err.error ?? tokenResponse.statusText;
|
|
232
|
-
throw new Error(`Token exchange failed: ${msg}`);
|
|
233
|
-
}
|
|
234
|
-
const tokens = await tokenResponse.json();
|
|
235
|
-
const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1e3;
|
|
236
|
-
const creds = {
|
|
237
|
-
accessToken: tokens.access_token,
|
|
238
|
-
refreshToken: tokens.refresh_token ?? null,
|
|
239
|
-
expiresAt,
|
|
240
|
-
baseUrl: config.baseUrl
|
|
241
|
-
};
|
|
242
|
-
saveCredentials(creds);
|
|
243
|
-
return creds;
|
|
244
|
-
}
|
|
245
|
-
async function refreshCredentials(creds, config) {
|
|
246
|
-
if (!creds.refreshToken) {
|
|
247
|
-
throw new Error("No refresh token available");
|
|
248
|
-
}
|
|
249
|
-
const unlock = acquireLock();
|
|
250
|
-
if (!unlock) {
|
|
251
|
-
await new Promise((r) => setTimeout(r, 2e3));
|
|
252
|
-
const fresh = getCredentials();
|
|
253
|
-
if (fresh && fresh.expiresAt > Date.now()) {
|
|
254
|
-
return fresh;
|
|
255
|
-
}
|
|
256
|
-
throw new Error("Token refresh failed (concurrent refresh in progress)");
|
|
257
|
-
}
|
|
258
|
-
try {
|
|
259
|
-
const latest = getCredentials();
|
|
260
|
-
if (latest && latest.expiresAt > Date.now() + 6e4) {
|
|
261
|
-
return latest;
|
|
262
|
-
}
|
|
263
|
-
const refreshParams = {
|
|
264
|
-
grant_type: "refresh_token",
|
|
265
|
-
refresh_token: creds.refreshToken,
|
|
266
|
-
client_id: config.clientId
|
|
267
|
-
};
|
|
268
|
-
if (config.clientSecret) {
|
|
269
|
-
refreshParams.client_secret = config.clientSecret;
|
|
270
|
-
}
|
|
271
|
-
const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {
|
|
272
|
-
method: "POST",
|
|
273
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
274
|
-
body: new URLSearchParams(refreshParams)
|
|
275
|
-
});
|
|
276
|
-
if (!tokenResponse.ok) {
|
|
277
|
-
throw new Error("Token refresh failed");
|
|
278
|
-
}
|
|
279
|
-
const tokens = await tokenResponse.json();
|
|
280
|
-
const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1e3;
|
|
281
|
-
const newCreds = {
|
|
282
|
-
accessToken: tokens.access_token,
|
|
283
|
-
refreshToken: tokens.refresh_token ?? creds.refreshToken,
|
|
284
|
-
expiresAt,
|
|
285
|
-
baseUrl: config.baseUrl
|
|
286
|
-
};
|
|
287
|
-
saveCredentials(newCreds);
|
|
288
|
-
return newCreds;
|
|
289
|
-
} finally {
|
|
290
|
-
unlock();
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
var TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1e3;
|
|
294
|
-
async function getValidToken() {
|
|
295
|
-
const creds = getCredentials();
|
|
296
|
-
if (!creds) return null;
|
|
297
|
-
const config = getConfig();
|
|
298
|
-
if (!config || config.baseUrl !== creds.baseUrl) return null;
|
|
299
|
-
if (Date.now() >= creds.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {
|
|
300
|
-
if (creds.refreshToken) {
|
|
301
|
-
try {
|
|
302
|
-
const newCreds = await refreshCredentials(creds, config);
|
|
303
|
-
return newCreds.accessToken;
|
|
304
|
-
} catch {
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
return creds.accessToken;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// src/client.ts
|
|
314
|
-
async function callTool(baseUrl, toolName, params) {
|
|
315
|
-
const token = await getValidToken();
|
|
316
|
-
const headers = {
|
|
317
|
-
"Content-Type": "application/json"
|
|
318
|
-
};
|
|
319
|
-
if (token) {
|
|
320
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
321
|
-
}
|
|
322
|
-
let res = await fetch(`${baseUrl}/api/tools/${toolName}`, {
|
|
323
|
-
method: "POST",
|
|
324
|
-
headers,
|
|
325
|
-
body: JSON.stringify(params)
|
|
326
|
-
});
|
|
327
|
-
if (res.status === 401 && token) {
|
|
328
|
-
const creds = getCredentials();
|
|
329
|
-
const config = getConfig();
|
|
330
|
-
if (creds?.refreshToken && config && config.baseUrl === creds.baseUrl) {
|
|
331
|
-
try {
|
|
332
|
-
const newCreds = await refreshCredentials(creds, config);
|
|
333
|
-
res = await fetch(`${baseUrl}/api/tools/${toolName}`, {
|
|
334
|
-
method: "POST",
|
|
335
|
-
headers: {
|
|
336
|
-
"Content-Type": "application/json",
|
|
337
|
-
Authorization: `Bearer ${newCreds.accessToken}`
|
|
338
|
-
},
|
|
339
|
-
body: JSON.stringify(params)
|
|
340
|
-
});
|
|
341
|
-
} catch {
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
const data = await res.json();
|
|
346
|
-
if (res.status === 401) {
|
|
347
|
-
throw new Error("This command requires a MoonPay Agents account. Run `moonpay login` first.");
|
|
348
|
-
}
|
|
349
|
-
if (res.status < 200 || res.status >= 300) {
|
|
350
|
-
const err = data;
|
|
351
|
-
throw new Error(err?.error ?? `Tool call failed (${res.status})`);
|
|
352
|
-
}
|
|
353
|
-
return data;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// src/generated/schemas.json
|
|
357
|
-
var schemas_default = [
|
|
358
|
-
{
|
|
359
|
-
name: "buy",
|
|
360
|
-
description: "Buy crypto with fiat via MoonPay. Returns a checkout URL to complete the purchase.",
|
|
361
|
-
inputSchema: {
|
|
362
|
-
$ref: "#/definitions/buy_input",
|
|
363
|
-
definitions: {
|
|
364
|
-
buy_input: {
|
|
365
|
-
type: "object",
|
|
366
|
-
properties: {
|
|
367
|
-
token: {
|
|
368
|
-
type: "string",
|
|
369
|
-
enum: [
|
|
370
|
-
"sol",
|
|
371
|
-
"usdc",
|
|
372
|
-
"usdc_arbitrum",
|
|
373
|
-
"usdc_base",
|
|
374
|
-
"usdc_optimism",
|
|
375
|
-
"usdc_sol",
|
|
376
|
-
"usdc_polygon",
|
|
377
|
-
"eth",
|
|
378
|
-
"eth_polygon",
|
|
379
|
-
"eth_optimism",
|
|
380
|
-
"eth_base",
|
|
381
|
-
"eth_arbitrum"
|
|
382
|
-
],
|
|
383
|
-
description: "MoonPay currency code: sol (Solana), usdc_sol (USDC on Solana), eth (Ethereum), usdc (USDC on Ethereum), usdc_base (USDC on Base), etc."
|
|
384
|
-
},
|
|
385
|
-
amount: {
|
|
386
|
-
type: "number",
|
|
387
|
-
description: "Amount of the token to buy, in token units \u2014 not fiat. For example, 1.5 means 1.5 SOL, not $1.50."
|
|
388
|
-
},
|
|
389
|
-
wallet: {
|
|
390
|
-
type: "string",
|
|
391
|
-
description: "Destination wallet address to receive the tokens"
|
|
392
|
-
},
|
|
393
|
-
email: {
|
|
394
|
-
type: [
|
|
395
|
-
"string",
|
|
396
|
-
"null"
|
|
397
|
-
],
|
|
398
|
-
description: "Buyer email to pre-fill on the checkout page"
|
|
399
|
-
}
|
|
400
|
-
},
|
|
401
|
-
required: [
|
|
402
|
-
"token",
|
|
403
|
-
"amount",
|
|
404
|
-
"wallet",
|
|
405
|
-
"email"
|
|
406
|
-
],
|
|
407
|
-
additionalProperties: false
|
|
408
|
-
}
|
|
409
|
-
},
|
|
410
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
411
|
-
}
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
name: "token_balance_list",
|
|
415
|
-
description: "List all token balances held in a wallet, including amount owned, current value in USD, and token details. Shows the complete token portfolio.",
|
|
416
|
-
inputSchema: {
|
|
417
|
-
$ref: "#/definitions/token_balance_list_input",
|
|
418
|
-
definitions: {
|
|
419
|
-
token_balance_list_input: {
|
|
420
|
-
type: "object",
|
|
421
|
-
properties: {
|
|
422
|
-
wallet: {
|
|
423
|
-
type: "string",
|
|
424
|
-
description: "Wallet address to check token balances for"
|
|
425
|
-
},
|
|
426
|
-
chain: {
|
|
427
|
-
type: "string",
|
|
428
|
-
enum: [
|
|
429
|
-
"solana",
|
|
430
|
-
"ethereum",
|
|
431
|
-
"base",
|
|
432
|
-
"polygon",
|
|
433
|
-
"arbitrum",
|
|
434
|
-
"optimism"
|
|
435
|
-
],
|
|
436
|
-
description: "Blockchain to check balances on (e.g. 'solana', 'ethereum', 'base')"
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
required: [
|
|
440
|
-
"wallet",
|
|
441
|
-
"chain"
|
|
442
|
-
],
|
|
443
|
-
additionalProperties: false
|
|
444
|
-
}
|
|
445
|
-
},
|
|
446
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
{
|
|
450
|
-
name: "token_retrieve",
|
|
451
|
-
description: "Get detailed token information including market data, price changes, volume, trades, and holder statistics by token address",
|
|
452
|
-
inputSchema: {
|
|
453
|
-
$ref: "#/definitions/token_retrieve_input",
|
|
454
|
-
definitions: {
|
|
455
|
-
token_retrieve_input: {
|
|
456
|
-
type: "object",
|
|
457
|
-
properties: {
|
|
458
|
-
token: {
|
|
459
|
-
type: "string",
|
|
460
|
-
description: "Address of the token to retrieve"
|
|
461
|
-
},
|
|
462
|
-
chain: {
|
|
463
|
-
type: "string",
|
|
464
|
-
enum: [
|
|
465
|
-
"solana",
|
|
466
|
-
"ethereum",
|
|
467
|
-
"base",
|
|
468
|
-
"polygon",
|
|
469
|
-
"arbitrum",
|
|
470
|
-
"optimism"
|
|
471
|
-
],
|
|
472
|
-
description: "Blockchain network where the token exists"
|
|
473
|
-
}
|
|
474
|
-
},
|
|
475
|
-
required: [
|
|
476
|
-
"token",
|
|
477
|
-
"chain"
|
|
478
|
-
],
|
|
479
|
-
additionalProperties: false
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
483
|
-
}
|
|
484
|
-
},
|
|
485
|
-
{
|
|
486
|
-
name: "token_search",
|
|
487
|
-
description: "Search for tokens by name, symbol, or address. Returns matching tokens with their market data including price, volume, and liquidity.",
|
|
488
|
-
inputSchema: {
|
|
489
|
-
$ref: "#/definitions/token_search_input",
|
|
490
|
-
definitions: {
|
|
491
|
-
token_search_input: {
|
|
492
|
-
type: "object",
|
|
493
|
-
properties: {
|
|
494
|
-
query: {
|
|
495
|
-
type: "string",
|
|
496
|
-
description: "Search term - can be token name (e.g. 'Bitcoin'), symbol (e.g. 'BTC'), or partial match"
|
|
497
|
-
},
|
|
498
|
-
chain: {
|
|
499
|
-
type: "string",
|
|
500
|
-
enum: [
|
|
501
|
-
"solana",
|
|
502
|
-
"ethereum",
|
|
503
|
-
"base",
|
|
504
|
-
"polygon",
|
|
505
|
-
"arbitrum",
|
|
506
|
-
"optimism"
|
|
507
|
-
],
|
|
508
|
-
description: "Blockchain to search on (e.g. 'solana', 'ethereum', 'base')"
|
|
509
|
-
},
|
|
510
|
-
limit: {
|
|
511
|
-
type: [
|
|
512
|
-
"number",
|
|
513
|
-
"null"
|
|
514
|
-
],
|
|
515
|
-
description: "Maximum number of results to return (optional, defaults to 5)"
|
|
516
|
-
}
|
|
517
|
-
},
|
|
518
|
-
required: [
|
|
519
|
-
"query",
|
|
520
|
-
"chain",
|
|
521
|
-
"limit"
|
|
522
|
-
],
|
|
523
|
-
additionalProperties: false
|
|
524
|
-
}
|
|
525
|
-
},
|
|
526
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
527
|
-
}
|
|
528
|
-
},
|
|
529
|
-
{
|
|
530
|
-
name: "token_swap_build",
|
|
531
|
-
description: "Build an unsigned swap transaction. Returns a base64-encoded transaction ready for signing.",
|
|
532
|
-
inputSchema: {
|
|
533
|
-
$ref: "#/definitions/token_swap_build_input",
|
|
534
|
-
definitions: {
|
|
535
|
-
token_swap_build_input: {
|
|
536
|
-
type: "object",
|
|
537
|
-
properties: {
|
|
538
|
-
input: {
|
|
539
|
-
type: "string",
|
|
540
|
-
description: "Mint address of the input token"
|
|
541
|
-
},
|
|
542
|
-
output: {
|
|
543
|
-
type: "string",
|
|
544
|
-
description: "Mint address of the output token"
|
|
545
|
-
},
|
|
546
|
-
amount: {
|
|
547
|
-
type: "number",
|
|
548
|
-
description: "Amount of the input token to swap"
|
|
549
|
-
},
|
|
550
|
-
wallet: {
|
|
551
|
-
type: "string",
|
|
552
|
-
description: "Wallet address that will execute the swap"
|
|
553
|
-
}
|
|
554
|
-
},
|
|
555
|
-
required: [
|
|
556
|
-
"input",
|
|
557
|
-
"output",
|
|
558
|
-
"amount",
|
|
559
|
-
"wallet"
|
|
560
|
-
],
|
|
561
|
-
additionalProperties: false
|
|
562
|
-
}
|
|
563
|
-
},
|
|
564
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
565
|
-
}
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
name: "token_swap_execute",
|
|
569
|
-
description: "Execute a signed swap transaction. Pass the signed transaction and requestId from token_swap_build.",
|
|
570
|
-
inputSchema: {
|
|
571
|
-
$ref: "#/definitions/token_swap_execute_input",
|
|
572
|
-
definitions: {
|
|
573
|
-
token_swap_execute_input: {
|
|
574
|
-
type: "object",
|
|
575
|
-
properties: {
|
|
576
|
-
transaction: {
|
|
577
|
-
type: "string",
|
|
578
|
-
description: "Base64-encoded signed transaction"
|
|
579
|
-
},
|
|
580
|
-
requestId: {
|
|
581
|
-
type: "string",
|
|
582
|
-
description: "Request ID from token_swap_build"
|
|
583
|
-
}
|
|
584
|
-
},
|
|
585
|
-
required: [
|
|
586
|
-
"transaction",
|
|
587
|
-
"requestId"
|
|
588
|
-
],
|
|
589
|
-
additionalProperties: false
|
|
590
|
-
}
|
|
591
|
-
},
|
|
592
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
593
|
-
}
|
|
594
|
-
},
|
|
595
|
-
{
|
|
596
|
-
name: "token_transfer_build",
|
|
597
|
-
description: "Build an unsigned transfer transaction. Returns a base64-encoded transaction ready for signing. Handles both native SOL and SPL tokens.",
|
|
598
|
-
inputSchema: {
|
|
599
|
-
$ref: "#/definitions/token_transfer_build_input",
|
|
600
|
-
definitions: {
|
|
601
|
-
token_transfer_build_input: {
|
|
602
|
-
type: "object",
|
|
603
|
-
properties: {
|
|
604
|
-
wallet: {
|
|
605
|
-
type: "string",
|
|
606
|
-
description: "Wallet address to transfer from"
|
|
607
|
-
},
|
|
608
|
-
token: {
|
|
609
|
-
type: "string",
|
|
610
|
-
description: "Mint address of the token to transfer"
|
|
611
|
-
},
|
|
612
|
-
to: {
|
|
613
|
-
type: "string",
|
|
614
|
-
description: "Recipient wallet address"
|
|
615
|
-
},
|
|
616
|
-
amount: {
|
|
617
|
-
type: "number",
|
|
618
|
-
description: "Amount to transfer in human-readable units (e.g. 1.5)"
|
|
619
|
-
}
|
|
620
|
-
},
|
|
621
|
-
required: [
|
|
622
|
-
"wallet",
|
|
623
|
-
"token",
|
|
624
|
-
"to",
|
|
625
|
-
"amount"
|
|
626
|
-
],
|
|
627
|
-
additionalProperties: false
|
|
628
|
-
}
|
|
629
|
-
},
|
|
630
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
|
-
{
|
|
634
|
-
name: "token_trending_list",
|
|
635
|
-
description: "Get currently trending tokens on a blockchain. Perfect for discovering what's hot right now.",
|
|
636
|
-
inputSchema: {
|
|
637
|
-
$ref: "#/definitions/token_trending_list_input",
|
|
638
|
-
definitions: {
|
|
639
|
-
token_trending_list_input: {
|
|
640
|
-
type: "object",
|
|
641
|
-
properties: {
|
|
642
|
-
chain: {
|
|
643
|
-
type: "string",
|
|
644
|
-
enum: [
|
|
645
|
-
"solana",
|
|
646
|
-
"ethereum",
|
|
647
|
-
"base",
|
|
648
|
-
"polygon",
|
|
649
|
-
"arbitrum",
|
|
650
|
-
"optimism"
|
|
651
|
-
],
|
|
652
|
-
description: "Blockchain to get trending tokens from (e.g. 'solana', 'ethereum', 'base')"
|
|
653
|
-
},
|
|
654
|
-
limit: {
|
|
655
|
-
type: "number",
|
|
656
|
-
description: "Number of results per page"
|
|
657
|
-
},
|
|
658
|
-
page: {
|
|
659
|
-
type: "number",
|
|
660
|
-
description: "The page number of results"
|
|
661
|
-
}
|
|
662
|
-
},
|
|
663
|
-
required: [
|
|
664
|
-
"chain",
|
|
665
|
-
"limit",
|
|
666
|
-
"page"
|
|
667
|
-
],
|
|
668
|
-
additionalProperties: false
|
|
669
|
-
}
|
|
670
|
-
},
|
|
671
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
name: "transaction_send",
|
|
676
|
-
description: "Broadcast a signed transaction to Solana. Simulates first, then sends and confirms.",
|
|
677
|
-
inputSchema: {
|
|
678
|
-
$ref: "#/definitions/transaction_send_input",
|
|
679
|
-
definitions: {
|
|
680
|
-
transaction_send_input: {
|
|
681
|
-
type: "object",
|
|
682
|
-
properties: {
|
|
683
|
-
transaction: {
|
|
684
|
-
type: "string",
|
|
685
|
-
description: "Base64-encoded signed transaction"
|
|
686
|
-
},
|
|
687
|
-
message: {
|
|
688
|
-
type: "string",
|
|
689
|
-
description: "Human-readable message describing the transaction"
|
|
690
|
-
}
|
|
691
|
-
},
|
|
692
|
-
required: [
|
|
693
|
-
"transaction",
|
|
694
|
-
"message"
|
|
695
|
-
],
|
|
696
|
-
additionalProperties: false
|
|
697
|
-
}
|
|
698
|
-
},
|
|
699
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
700
|
-
}
|
|
701
|
-
},
|
|
702
|
-
{
|
|
703
|
-
name: "user_retrieve",
|
|
704
|
-
description: "Get the currently authenticated user",
|
|
705
|
-
inputSchema: {
|
|
706
|
-
$ref: "#/definitions/user_retrieve_input",
|
|
707
|
-
definitions: {
|
|
708
|
-
user_retrieve_input: {
|
|
709
|
-
type: "object",
|
|
710
|
-
properties: {},
|
|
711
|
-
additionalProperties: false
|
|
712
|
-
}
|
|
713
|
-
},
|
|
714
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
715
|
-
}
|
|
716
|
-
},
|
|
717
|
-
{
|
|
718
|
-
name: "virtual-account_bank-account_delete",
|
|
719
|
-
description: "Delete a bank account",
|
|
720
|
-
inputSchema: {
|
|
721
|
-
$ref: "#/definitions/virtual-account_bank-account_delete_input",
|
|
722
|
-
definitions: {
|
|
723
|
-
"virtual-account_bank-account_delete_input": {
|
|
724
|
-
type: "object",
|
|
725
|
-
properties: {
|
|
726
|
-
bankAccountId: {
|
|
727
|
-
type: "string",
|
|
728
|
-
format: "uuid",
|
|
729
|
-
description: "The ID of the bank account to delete"
|
|
730
|
-
}
|
|
731
|
-
},
|
|
732
|
-
required: [
|
|
733
|
-
"bankAccountId"
|
|
734
|
-
],
|
|
735
|
-
additionalProperties: false
|
|
736
|
-
}
|
|
737
|
-
},
|
|
738
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
739
|
-
}
|
|
740
|
-
},
|
|
741
|
-
{
|
|
742
|
-
name: "virtual-account_bank-account_eur_register",
|
|
743
|
-
description: "Register a EUR bank account for offramp payouts",
|
|
744
|
-
inputSchema: {
|
|
745
|
-
$ref: "#/definitions/virtual-account_bank-account_eur_register_input",
|
|
746
|
-
definitions: {
|
|
747
|
-
"virtual-account_bank-account_eur_register_input": {
|
|
748
|
-
type: "object",
|
|
749
|
-
properties: {
|
|
750
|
-
iban: {
|
|
751
|
-
type: "string",
|
|
752
|
-
description: "IBAN for SEPA bank account"
|
|
753
|
-
},
|
|
754
|
-
address: {
|
|
755
|
-
type: "object",
|
|
756
|
-
properties: {
|
|
757
|
-
street: {
|
|
758
|
-
type: "string",
|
|
759
|
-
description: "Street address"
|
|
760
|
-
},
|
|
761
|
-
city: {
|
|
762
|
-
type: "string",
|
|
763
|
-
description: "City"
|
|
764
|
-
},
|
|
765
|
-
state: {
|
|
766
|
-
type: "string",
|
|
767
|
-
description: "State or province"
|
|
768
|
-
},
|
|
769
|
-
country: {
|
|
770
|
-
type: "string",
|
|
771
|
-
enum: [
|
|
772
|
-
"US",
|
|
773
|
-
"GB",
|
|
774
|
-
"CA",
|
|
775
|
-
"AU",
|
|
776
|
-
"DE",
|
|
777
|
-
"FR",
|
|
778
|
-
"IT",
|
|
779
|
-
"ES",
|
|
780
|
-
"NL",
|
|
781
|
-
"BE",
|
|
782
|
-
"AT",
|
|
783
|
-
"CH",
|
|
784
|
-
"SE",
|
|
785
|
-
"NO",
|
|
786
|
-
"DK",
|
|
787
|
-
"FI",
|
|
788
|
-
"IE",
|
|
789
|
-
"PT",
|
|
790
|
-
"PL",
|
|
791
|
-
"CZ",
|
|
792
|
-
"GR",
|
|
793
|
-
"JP",
|
|
794
|
-
"KR",
|
|
795
|
-
"CN",
|
|
796
|
-
"IN",
|
|
797
|
-
"BR",
|
|
798
|
-
"MX",
|
|
799
|
-
"AR",
|
|
800
|
-
"ZA",
|
|
801
|
-
"NZ",
|
|
802
|
-
"SG",
|
|
803
|
-
"HK",
|
|
804
|
-
"AE"
|
|
805
|
-
],
|
|
806
|
-
description: "ISO 3166-1 Alpha-2 country code"
|
|
807
|
-
},
|
|
808
|
-
postalCode: {
|
|
809
|
-
type: "string",
|
|
810
|
-
description: "Postal or ZIP code"
|
|
811
|
-
}
|
|
812
|
-
},
|
|
813
|
-
required: [
|
|
814
|
-
"street",
|
|
815
|
-
"city",
|
|
816
|
-
"state",
|
|
817
|
-
"country",
|
|
818
|
-
"postalCode"
|
|
819
|
-
],
|
|
820
|
-
additionalProperties: false,
|
|
821
|
-
description: "Address of the user that owns the bank account"
|
|
822
|
-
},
|
|
823
|
-
email: {
|
|
824
|
-
type: "string",
|
|
825
|
-
description: "Email address of the user that owns the bank account"
|
|
826
|
-
},
|
|
827
|
-
phoneNumber: {
|
|
828
|
-
type: "string",
|
|
829
|
-
description: "Phone number of the user"
|
|
830
|
-
},
|
|
831
|
-
providerCountry: {
|
|
832
|
-
type: "string",
|
|
833
|
-
enum: [
|
|
834
|
-
"US",
|
|
835
|
-
"GB",
|
|
836
|
-
"CA",
|
|
837
|
-
"AU",
|
|
838
|
-
"DE",
|
|
839
|
-
"FR",
|
|
840
|
-
"IT",
|
|
841
|
-
"ES",
|
|
842
|
-
"NL",
|
|
843
|
-
"BE",
|
|
844
|
-
"AT",
|
|
845
|
-
"CH",
|
|
846
|
-
"SE",
|
|
847
|
-
"NO",
|
|
848
|
-
"DK",
|
|
849
|
-
"FI",
|
|
850
|
-
"IE",
|
|
851
|
-
"PT",
|
|
852
|
-
"PL",
|
|
853
|
-
"CZ",
|
|
854
|
-
"GR",
|
|
855
|
-
"JP",
|
|
856
|
-
"KR",
|
|
857
|
-
"CN",
|
|
858
|
-
"IN",
|
|
859
|
-
"BR",
|
|
860
|
-
"MX",
|
|
861
|
-
"AR",
|
|
862
|
-
"ZA",
|
|
863
|
-
"NZ",
|
|
864
|
-
"SG",
|
|
865
|
-
"HK",
|
|
866
|
-
"AE"
|
|
867
|
-
],
|
|
868
|
-
description: "ISO 3166-1 Alpha-2 country code where the bank is located"
|
|
869
|
-
},
|
|
870
|
-
providerName: {
|
|
871
|
-
type: "string",
|
|
872
|
-
description: "Name of the bank"
|
|
873
|
-
},
|
|
874
|
-
givenName: {
|
|
875
|
-
type: "string",
|
|
876
|
-
description: "First/given name of the account holder"
|
|
877
|
-
},
|
|
878
|
-
familyName: {
|
|
879
|
-
type: "string",
|
|
880
|
-
description: "Last/family name of the account holder"
|
|
881
|
-
}
|
|
882
|
-
},
|
|
883
|
-
required: [
|
|
884
|
-
"iban",
|
|
885
|
-
"address",
|
|
886
|
-
"email",
|
|
887
|
-
"phoneNumber",
|
|
888
|
-
"providerCountry",
|
|
889
|
-
"providerName",
|
|
890
|
-
"givenName",
|
|
891
|
-
"familyName"
|
|
892
|
-
],
|
|
893
|
-
additionalProperties: false
|
|
894
|
-
}
|
|
895
|
-
},
|
|
896
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
897
|
-
}
|
|
898
|
-
},
|
|
899
|
-
{
|
|
900
|
-
name: "virtual-account_bank-account_list",
|
|
901
|
-
description: "List registered bank accounts",
|
|
902
|
-
inputSchema: {
|
|
903
|
-
$ref: "#/definitions/virtual-account_bank-account_list_input",
|
|
904
|
-
definitions: {
|
|
905
|
-
"virtual-account_bank-account_list_input": {
|
|
906
|
-
type: "object",
|
|
907
|
-
properties: {},
|
|
908
|
-
additionalProperties: false
|
|
909
|
-
}
|
|
910
|
-
},
|
|
911
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
912
|
-
}
|
|
913
|
-
},
|
|
914
|
-
{
|
|
915
|
-
name: "virtual-account_bank-account_retrieve",
|
|
916
|
-
description: "Get a bank account by currency",
|
|
917
|
-
inputSchema: {
|
|
918
|
-
$ref: "#/definitions/virtual-account_bank-account_retrieve_input",
|
|
919
|
-
definitions: {
|
|
920
|
-
"virtual-account_bank-account_retrieve_input": {
|
|
921
|
-
type: "object",
|
|
922
|
-
properties: {
|
|
923
|
-
currency: {
|
|
924
|
-
type: "string",
|
|
925
|
-
enum: [
|
|
926
|
-
"USD",
|
|
927
|
-
"EUR"
|
|
928
|
-
],
|
|
929
|
-
description: "The fiat currency code (USD or EUR)"
|
|
930
|
-
}
|
|
931
|
-
},
|
|
932
|
-
required: [
|
|
933
|
-
"currency"
|
|
934
|
-
],
|
|
935
|
-
additionalProperties: false
|
|
936
|
-
}
|
|
937
|
-
},
|
|
938
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
939
|
-
}
|
|
940
|
-
},
|
|
941
|
-
{
|
|
942
|
-
name: "virtual-account_bank-account_usd_register",
|
|
943
|
-
description: "Register a USD bank account for offramp payouts",
|
|
944
|
-
inputSchema: {
|
|
945
|
-
$ref: "#/definitions/virtual-account_bank-account_usd_register_input",
|
|
946
|
-
definitions: {
|
|
947
|
-
"virtual-account_bank-account_usd_register_input": {
|
|
948
|
-
type: "object",
|
|
949
|
-
properties: {
|
|
950
|
-
type: {
|
|
951
|
-
type: "string",
|
|
952
|
-
enum: [
|
|
953
|
-
"ACH",
|
|
954
|
-
"Wire"
|
|
955
|
-
],
|
|
956
|
-
description: "Type of bank account (ACH or Wire)"
|
|
957
|
-
},
|
|
958
|
-
accountNumber: {
|
|
959
|
-
type: "string",
|
|
960
|
-
description: "Account number"
|
|
961
|
-
},
|
|
962
|
-
routingNumber: {
|
|
963
|
-
type: "string",
|
|
964
|
-
description: "Routing number"
|
|
965
|
-
},
|
|
966
|
-
address: {
|
|
967
|
-
type: "object",
|
|
968
|
-
properties: {
|
|
969
|
-
street: {
|
|
970
|
-
type: "string",
|
|
971
|
-
description: "Street address"
|
|
972
|
-
},
|
|
973
|
-
city: {
|
|
974
|
-
type: "string",
|
|
975
|
-
description: "City"
|
|
976
|
-
},
|
|
977
|
-
state: {
|
|
978
|
-
type: "string",
|
|
979
|
-
description: "State or province"
|
|
980
|
-
},
|
|
981
|
-
country: {
|
|
982
|
-
type: "string",
|
|
983
|
-
enum: [
|
|
984
|
-
"US",
|
|
985
|
-
"GB",
|
|
986
|
-
"CA",
|
|
987
|
-
"AU",
|
|
988
|
-
"DE",
|
|
989
|
-
"FR",
|
|
990
|
-
"IT",
|
|
991
|
-
"ES",
|
|
992
|
-
"NL",
|
|
993
|
-
"BE",
|
|
994
|
-
"AT",
|
|
995
|
-
"CH",
|
|
996
|
-
"SE",
|
|
997
|
-
"NO",
|
|
998
|
-
"DK",
|
|
999
|
-
"FI",
|
|
1000
|
-
"IE",
|
|
1001
|
-
"PT",
|
|
1002
|
-
"PL",
|
|
1003
|
-
"CZ",
|
|
1004
|
-
"GR",
|
|
1005
|
-
"JP",
|
|
1006
|
-
"KR",
|
|
1007
|
-
"CN",
|
|
1008
|
-
"IN",
|
|
1009
|
-
"BR",
|
|
1010
|
-
"MX",
|
|
1011
|
-
"AR",
|
|
1012
|
-
"ZA",
|
|
1013
|
-
"NZ",
|
|
1014
|
-
"SG",
|
|
1015
|
-
"HK",
|
|
1016
|
-
"AE"
|
|
1017
|
-
],
|
|
1018
|
-
description: "ISO 3166-1 Alpha-2 country code"
|
|
1019
|
-
},
|
|
1020
|
-
postalCode: {
|
|
1021
|
-
type: "string",
|
|
1022
|
-
description: "Postal or ZIP code"
|
|
1023
|
-
}
|
|
1024
|
-
},
|
|
1025
|
-
required: [
|
|
1026
|
-
"street",
|
|
1027
|
-
"city",
|
|
1028
|
-
"state",
|
|
1029
|
-
"country",
|
|
1030
|
-
"postalCode"
|
|
1031
|
-
],
|
|
1032
|
-
additionalProperties: false,
|
|
1033
|
-
description: "Address of the user that owns the bank account"
|
|
1034
|
-
},
|
|
1035
|
-
email: {
|
|
1036
|
-
type: "string",
|
|
1037
|
-
description: "Email address of the user that owns the bank account"
|
|
1038
|
-
},
|
|
1039
|
-
phoneNumber: {
|
|
1040
|
-
type: "string",
|
|
1041
|
-
description: "Phone number of the user"
|
|
1042
|
-
},
|
|
1043
|
-
providerCountry: {
|
|
1044
|
-
type: "string",
|
|
1045
|
-
enum: [
|
|
1046
|
-
"US",
|
|
1047
|
-
"GB",
|
|
1048
|
-
"CA",
|
|
1049
|
-
"AU",
|
|
1050
|
-
"DE",
|
|
1051
|
-
"FR",
|
|
1052
|
-
"IT",
|
|
1053
|
-
"ES",
|
|
1054
|
-
"NL",
|
|
1055
|
-
"BE",
|
|
1056
|
-
"AT",
|
|
1057
|
-
"CH",
|
|
1058
|
-
"SE",
|
|
1059
|
-
"NO",
|
|
1060
|
-
"DK",
|
|
1061
|
-
"FI",
|
|
1062
|
-
"IE",
|
|
1063
|
-
"PT",
|
|
1064
|
-
"PL",
|
|
1065
|
-
"CZ",
|
|
1066
|
-
"GR",
|
|
1067
|
-
"JP",
|
|
1068
|
-
"KR",
|
|
1069
|
-
"CN",
|
|
1070
|
-
"IN",
|
|
1071
|
-
"BR",
|
|
1072
|
-
"MX",
|
|
1073
|
-
"AR",
|
|
1074
|
-
"ZA",
|
|
1075
|
-
"NZ",
|
|
1076
|
-
"SG",
|
|
1077
|
-
"HK",
|
|
1078
|
-
"AE"
|
|
1079
|
-
],
|
|
1080
|
-
description: "ISO 3166-1 Alpha-2 country code where the bank is located"
|
|
1081
|
-
},
|
|
1082
|
-
providerName: {
|
|
1083
|
-
type: "string",
|
|
1084
|
-
description: "Name of the bank"
|
|
1085
|
-
},
|
|
1086
|
-
givenName: {
|
|
1087
|
-
type: "string",
|
|
1088
|
-
description: "First/given name of the account holder"
|
|
1089
|
-
},
|
|
1090
|
-
familyName: {
|
|
1091
|
-
type: "string",
|
|
1092
|
-
description: "Last/family name of the account holder"
|
|
1093
|
-
}
|
|
1094
|
-
},
|
|
1095
|
-
required: [
|
|
1096
|
-
"type",
|
|
1097
|
-
"accountNumber",
|
|
1098
|
-
"routingNumber",
|
|
1099
|
-
"address",
|
|
1100
|
-
"email",
|
|
1101
|
-
"phoneNumber",
|
|
1102
|
-
"providerCountry",
|
|
1103
|
-
"providerName",
|
|
1104
|
-
"givenName",
|
|
1105
|
-
"familyName"
|
|
1106
|
-
],
|
|
1107
|
-
additionalProperties: false
|
|
1108
|
-
}
|
|
1109
|
-
},
|
|
1110
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1111
|
-
}
|
|
1112
|
-
},
|
|
1113
|
-
{
|
|
1114
|
-
name: "virtual-account_create",
|
|
1115
|
-
description: "Create a virtual account and start KYC verification",
|
|
1116
|
-
inputSchema: {
|
|
1117
|
-
$ref: "#/definitions/virtual-account_create_input",
|
|
1118
|
-
definitions: {
|
|
1119
|
-
"virtual-account_create_input": {
|
|
1120
|
-
type: "object",
|
|
1121
|
-
properties: {},
|
|
1122
|
-
additionalProperties: false
|
|
1123
|
-
}
|
|
1124
|
-
},
|
|
1125
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1126
|
-
}
|
|
1127
|
-
},
|
|
1128
|
-
{
|
|
1129
|
-
name: "virtual-account_delete",
|
|
1130
|
-
description: "Delete your virtual account",
|
|
1131
|
-
inputSchema: {
|
|
1132
|
-
$ref: "#/definitions/virtual-account_delete_input",
|
|
1133
|
-
definitions: {
|
|
1134
|
-
"virtual-account_delete_input": {
|
|
1135
|
-
type: "object",
|
|
1136
|
-
properties: {},
|
|
1137
|
-
additionalProperties: false
|
|
1138
|
-
}
|
|
1139
|
-
},
|
|
1140
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1141
|
-
}
|
|
1142
|
-
},
|
|
1143
|
-
{
|
|
1144
|
-
name: "virtual-account_identification_create",
|
|
1145
|
-
description: "Create a KYC verification link to complete identity verification",
|
|
1146
|
-
inputSchema: {
|
|
1147
|
-
$ref: "#/definitions/virtual-account_identification_create_input",
|
|
1148
|
-
definitions: {
|
|
1149
|
-
"virtual-account_identification_create_input": {
|
|
1150
|
-
type: "object",
|
|
1151
|
-
properties: {},
|
|
1152
|
-
additionalProperties: false
|
|
1153
|
-
}
|
|
1154
|
-
},
|
|
1155
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1156
|
-
}
|
|
1157
|
-
},
|
|
1158
|
-
{
|
|
1159
|
-
name: "virtual-account_identification_list",
|
|
1160
|
-
description: "List all KYC identifications",
|
|
1161
|
-
inputSchema: {
|
|
1162
|
-
$ref: "#/definitions/virtual-account_identification_list_input",
|
|
1163
|
-
definitions: {
|
|
1164
|
-
"virtual-account_identification_list_input": {
|
|
1165
|
-
type: "object",
|
|
1166
|
-
properties: {},
|
|
1167
|
-
additionalProperties: false
|
|
1168
|
-
}
|
|
1169
|
-
},
|
|
1170
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1171
|
-
}
|
|
1172
|
-
},
|
|
1173
|
-
{
|
|
1174
|
-
name: "virtual-account_identification_retrieve",
|
|
1175
|
-
description: "Get the status of a KYC identification",
|
|
1176
|
-
inputSchema: {
|
|
1177
|
-
$ref: "#/definitions/virtual-account_identification_retrieve_input",
|
|
1178
|
-
definitions: {
|
|
1179
|
-
"virtual-account_identification_retrieve_input": {
|
|
1180
|
-
type: "object",
|
|
1181
|
-
properties: {},
|
|
1182
|
-
additionalProperties: false
|
|
1183
|
-
}
|
|
1184
|
-
},
|
|
1185
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1186
|
-
}
|
|
1187
|
-
},
|
|
1188
|
-
{
|
|
1189
|
-
name: "virtual-account_offramp_create",
|
|
1190
|
-
description: "Create an offramp to convert stablecoin to fiat",
|
|
1191
|
-
inputSchema: {
|
|
1192
|
-
$ref: "#/definitions/virtual-account_offramp_create_input",
|
|
1193
|
-
definitions: {
|
|
1194
|
-
"virtual-account_offramp_create_input": {
|
|
1195
|
-
type: "object",
|
|
1196
|
-
properties: {
|
|
1197
|
-
name: {
|
|
1198
|
-
type: "string",
|
|
1199
|
-
description: "The name of the offramp"
|
|
1200
|
-
},
|
|
1201
|
-
fiat: {
|
|
1202
|
-
type: "string",
|
|
1203
|
-
enum: [
|
|
1204
|
-
"USD",
|
|
1205
|
-
"EUR"
|
|
1206
|
-
],
|
|
1207
|
-
description: "The fiat currency to convert to"
|
|
1208
|
-
},
|
|
1209
|
-
stablecoin: {
|
|
1210
|
-
type: "string",
|
|
1211
|
-
enum: [
|
|
1212
|
-
"USDC",
|
|
1213
|
-
"USDT",
|
|
1214
|
-
"EURC"
|
|
1215
|
-
],
|
|
1216
|
-
description: "The stablecoin token to convert from"
|
|
1217
|
-
}
|
|
1218
|
-
},
|
|
1219
|
-
required: [
|
|
1220
|
-
"name",
|
|
1221
|
-
"fiat",
|
|
1222
|
-
"stablecoin"
|
|
1223
|
-
],
|
|
1224
|
-
additionalProperties: false
|
|
1225
|
-
}
|
|
1226
|
-
},
|
|
1227
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1228
|
-
}
|
|
1229
|
-
},
|
|
1230
|
-
{
|
|
1231
|
-
name: "virtual-account_offramp_delete",
|
|
1232
|
-
description: "Cancel an offramp",
|
|
1233
|
-
inputSchema: {
|
|
1234
|
-
$ref: "#/definitions/virtual-account_offramp_delete_input",
|
|
1235
|
-
definitions: {
|
|
1236
|
-
"virtual-account_offramp_delete_input": {
|
|
1237
|
-
type: "object",
|
|
1238
|
-
properties: {
|
|
1239
|
-
offrampId: {
|
|
1240
|
-
type: "string",
|
|
1241
|
-
format: "uuid",
|
|
1242
|
-
description: "The ID of the offramp to cancel"
|
|
1243
|
-
}
|
|
1244
|
-
},
|
|
1245
|
-
required: [
|
|
1246
|
-
"offrampId"
|
|
1247
|
-
],
|
|
1248
|
-
additionalProperties: false
|
|
1249
|
-
}
|
|
1250
|
-
},
|
|
1251
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1252
|
-
}
|
|
1253
|
-
},
|
|
1254
|
-
{
|
|
1255
|
-
name: "virtual-account_offramp_initiate",
|
|
1256
|
-
description: "Build an unsigned transaction to send stablecoin to an offramp deposit address",
|
|
1257
|
-
inputSchema: {
|
|
1258
|
-
$ref: "#/definitions/virtual-account_offramp_initiate_input",
|
|
1259
|
-
definitions: {
|
|
1260
|
-
"virtual-account_offramp_initiate_input": {
|
|
1261
|
-
type: "object",
|
|
1262
|
-
properties: {
|
|
1263
|
-
wallet: {
|
|
1264
|
-
type: "string",
|
|
1265
|
-
description: "The wallet address to send from"
|
|
1266
|
-
},
|
|
1267
|
-
offrampId: {
|
|
1268
|
-
type: "string",
|
|
1269
|
-
description: "The ID of the offramp to initiate"
|
|
1270
|
-
},
|
|
1271
|
-
amount: {
|
|
1272
|
-
type: "number",
|
|
1273
|
-
minimum: 0,
|
|
1274
|
-
description: "The amount of stablecoin to send (in human-readable units, e.g., 100.5)"
|
|
1275
|
-
}
|
|
1276
|
-
},
|
|
1277
|
-
required: [
|
|
1278
|
-
"wallet",
|
|
1279
|
-
"offrampId",
|
|
1280
|
-
"amount"
|
|
1281
|
-
],
|
|
1282
|
-
additionalProperties: false
|
|
1283
|
-
}
|
|
1284
|
-
},
|
|
1285
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1286
|
-
}
|
|
1287
|
-
},
|
|
1288
|
-
{
|
|
1289
|
-
name: "virtual-account_offramp_list",
|
|
1290
|
-
description: "List all offramps",
|
|
1291
|
-
inputSchema: {
|
|
1292
|
-
$ref: "#/definitions/virtual-account_offramp_list_input",
|
|
1293
|
-
definitions: {
|
|
1294
|
-
"virtual-account_offramp_list_input": {
|
|
1295
|
-
type: "object",
|
|
1296
|
-
properties: {},
|
|
1297
|
-
additionalProperties: false
|
|
1298
|
-
}
|
|
1299
|
-
},
|
|
1300
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1301
|
-
}
|
|
1302
|
-
},
|
|
1303
|
-
{
|
|
1304
|
-
name: "virtual-account_offramp_retrieve",
|
|
1305
|
-
description: "Get offramp details",
|
|
1306
|
-
inputSchema: {
|
|
1307
|
-
$ref: "#/definitions/virtual-account_offramp_retrieve_input",
|
|
1308
|
-
definitions: {
|
|
1309
|
-
"virtual-account_offramp_retrieve_input": {
|
|
1310
|
-
type: "object",
|
|
1311
|
-
properties: {
|
|
1312
|
-
offrampId: {
|
|
1313
|
-
type: "string",
|
|
1314
|
-
format: "uuid",
|
|
1315
|
-
description: "The ID of the offramp to retrieve"
|
|
1316
|
-
}
|
|
1317
|
-
},
|
|
1318
|
-
required: [
|
|
1319
|
-
"offrampId"
|
|
1320
|
-
],
|
|
1321
|
-
additionalProperties: false
|
|
1322
|
-
}
|
|
1323
|
-
},
|
|
1324
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1325
|
-
}
|
|
1326
|
-
},
|
|
1327
|
-
{
|
|
1328
|
-
name: "virtual-account_onramp_create",
|
|
1329
|
-
description: "Create an onramp to convert fiat to stablecoin",
|
|
1330
|
-
inputSchema: {
|
|
1331
|
-
$ref: "#/definitions/virtual-account_onramp_create_input",
|
|
1332
|
-
definitions: {
|
|
1333
|
-
"virtual-account_onramp_create_input": {
|
|
1334
|
-
type: "object",
|
|
1335
|
-
properties: {
|
|
1336
|
-
name: {
|
|
1337
|
-
type: "string",
|
|
1338
|
-
description: "The name of the onramp"
|
|
1339
|
-
},
|
|
1340
|
-
fiat: {
|
|
1341
|
-
type: "string",
|
|
1342
|
-
enum: [
|
|
1343
|
-
"USD",
|
|
1344
|
-
"EUR"
|
|
1345
|
-
],
|
|
1346
|
-
description: "The fiat currency to convert from"
|
|
1347
|
-
},
|
|
1348
|
-
stablecoin: {
|
|
1349
|
-
type: "string",
|
|
1350
|
-
enum: [
|
|
1351
|
-
"USDC",
|
|
1352
|
-
"USDT",
|
|
1353
|
-
"EURC"
|
|
1354
|
-
],
|
|
1355
|
-
description: "The stablecoin token to convert to"
|
|
1356
|
-
}
|
|
1357
|
-
},
|
|
1358
|
-
required: [
|
|
1359
|
-
"name",
|
|
1360
|
-
"fiat",
|
|
1361
|
-
"stablecoin"
|
|
1362
|
-
],
|
|
1363
|
-
additionalProperties: false
|
|
1364
|
-
}
|
|
1365
|
-
},
|
|
1366
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1367
|
-
}
|
|
1368
|
-
},
|
|
1369
|
-
{
|
|
1370
|
-
name: "virtual-account_onramp_delete",
|
|
1371
|
-
description: "Cancel an onramp",
|
|
1372
|
-
inputSchema: {
|
|
1373
|
-
$ref: "#/definitions/virtual-account_onramp_delete_input",
|
|
1374
|
-
definitions: {
|
|
1375
|
-
"virtual-account_onramp_delete_input": {
|
|
1376
|
-
type: "object",
|
|
1377
|
-
properties: {
|
|
1378
|
-
onrampId: {
|
|
1379
|
-
type: "string",
|
|
1380
|
-
format: "uuid",
|
|
1381
|
-
description: "The ID of the onramp to cancel"
|
|
1382
|
-
}
|
|
1383
|
-
},
|
|
1384
|
-
required: [
|
|
1385
|
-
"onrampId"
|
|
1386
|
-
],
|
|
1387
|
-
additionalProperties: false
|
|
1388
|
-
}
|
|
1389
|
-
},
|
|
1390
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1391
|
-
}
|
|
1392
|
-
},
|
|
1393
|
-
{
|
|
1394
|
-
name: "virtual-account_onramp_list",
|
|
1395
|
-
description: "List all onramps",
|
|
1396
|
-
inputSchema: {
|
|
1397
|
-
$ref: "#/definitions/virtual-account_onramp_list_input",
|
|
1398
|
-
definitions: {
|
|
1399
|
-
"virtual-account_onramp_list_input": {
|
|
1400
|
-
type: "object",
|
|
1401
|
-
properties: {
|
|
1402
|
-
status: {
|
|
1403
|
-
type: "string",
|
|
1404
|
-
enum: [
|
|
1405
|
-
"Created",
|
|
1406
|
-
"Authorized",
|
|
1407
|
-
"DepositAccountAdded",
|
|
1408
|
-
"Approved",
|
|
1409
|
-
"Rejected",
|
|
1410
|
-
"Cancelled"
|
|
1411
|
-
],
|
|
1412
|
-
description: "Status of the onramps to get"
|
|
1413
|
-
}
|
|
1414
|
-
},
|
|
1415
|
-
required: [
|
|
1416
|
-
"status"
|
|
1417
|
-
],
|
|
1418
|
-
additionalProperties: false
|
|
1419
|
-
}
|
|
1420
|
-
},
|
|
1421
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1422
|
-
}
|
|
1423
|
-
},
|
|
1424
|
-
{
|
|
1425
|
-
name: "virtual-account_onramp_payment_create",
|
|
1426
|
-
description: "Create an open banking payment link for an onramp",
|
|
1427
|
-
inputSchema: {
|
|
1428
|
-
$ref: "#/definitions/virtual-account_onramp_payment_create_input",
|
|
1429
|
-
definitions: {
|
|
1430
|
-
"virtual-account_onramp_payment_create_input": {
|
|
1431
|
-
type: "object",
|
|
1432
|
-
properties: {
|
|
1433
|
-
onrampId: {
|
|
1434
|
-
type: "string",
|
|
1435
|
-
format: "uuid",
|
|
1436
|
-
description: "The ID of the onramp"
|
|
1437
|
-
},
|
|
1438
|
-
amount: {
|
|
1439
|
-
type: "string",
|
|
1440
|
-
description: "The amount to pay"
|
|
1441
|
-
},
|
|
1442
|
-
fiat: {
|
|
1443
|
-
type: "string",
|
|
1444
|
-
enum: [
|
|
1445
|
-
"USD",
|
|
1446
|
-
"EUR"
|
|
1447
|
-
],
|
|
1448
|
-
description: "The fiat currency (USD or EUR)"
|
|
1449
|
-
}
|
|
1450
|
-
},
|
|
1451
|
-
required: [
|
|
1452
|
-
"onrampId",
|
|
1453
|
-
"amount",
|
|
1454
|
-
"fiat"
|
|
1455
|
-
],
|
|
1456
|
-
additionalProperties: false
|
|
1457
|
-
}
|
|
1458
|
-
},
|
|
1459
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1460
|
-
}
|
|
1461
|
-
},
|
|
1462
|
-
{
|
|
1463
|
-
name: "virtual-account_onramp_payment_retrieve",
|
|
1464
|
-
description: "Get the status of an open banking payment",
|
|
1465
|
-
inputSchema: {
|
|
1466
|
-
$ref: "#/definitions/virtual-account_onramp_payment_retrieve_input",
|
|
1467
|
-
definitions: {
|
|
1468
|
-
"virtual-account_onramp_payment_retrieve_input": {
|
|
1469
|
-
type: "object",
|
|
1470
|
-
properties: {
|
|
1471
|
-
onrampId: {
|
|
1472
|
-
type: "string",
|
|
1473
|
-
format: "uuid",
|
|
1474
|
-
description: "The ID of the onramp this payment belongs to"
|
|
1475
|
-
},
|
|
1476
|
-
paymentId: {
|
|
1477
|
-
type: "string",
|
|
1478
|
-
format: "uuid",
|
|
1479
|
-
description: "The ID of the payment to retrieve"
|
|
1480
|
-
}
|
|
1481
|
-
},
|
|
1482
|
-
required: [
|
|
1483
|
-
"onrampId",
|
|
1484
|
-
"paymentId"
|
|
1485
|
-
],
|
|
1486
|
-
additionalProperties: false
|
|
1487
|
-
}
|
|
1488
|
-
},
|
|
1489
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1490
|
-
}
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
name: "virtual-account_onramp_retrieve",
|
|
1494
|
-
description: "Get onramp details and banking info",
|
|
1495
|
-
inputSchema: {
|
|
1496
|
-
$ref: "#/definitions/virtual-account_onramp_retrieve_input",
|
|
1497
|
-
definitions: {
|
|
1498
|
-
"virtual-account_onramp_retrieve_input": {
|
|
1499
|
-
type: "object",
|
|
1500
|
-
properties: {
|
|
1501
|
-
onrampId: {
|
|
1502
|
-
type: "string",
|
|
1503
|
-
format: "uuid",
|
|
1504
|
-
description: "The ID of the onramp to retrieve"
|
|
1505
|
-
}
|
|
1506
|
-
},
|
|
1507
|
-
required: [
|
|
1508
|
-
"onrampId"
|
|
1509
|
-
],
|
|
1510
|
-
additionalProperties: false
|
|
1511
|
-
}
|
|
1512
|
-
},
|
|
1513
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1514
|
-
}
|
|
1515
|
-
},
|
|
1516
|
-
{
|
|
1517
|
-
name: "virtual-account_retrieve",
|
|
1518
|
-
description: "Get your virtual account status",
|
|
1519
|
-
inputSchema: {
|
|
1520
|
-
$ref: "#/definitions/virtual-account_retrieve_input",
|
|
1521
|
-
definitions: {
|
|
1522
|
-
"virtual-account_retrieve_input": {
|
|
1523
|
-
type: "object",
|
|
1524
|
-
properties: {},
|
|
1525
|
-
additionalProperties: false
|
|
1526
|
-
}
|
|
1527
|
-
},
|
|
1528
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1529
|
-
}
|
|
1530
|
-
},
|
|
1531
|
-
{
|
|
1532
|
-
name: "virtual-account_signing_create",
|
|
1533
|
-
description: "Sign a required document for your virtual account",
|
|
1534
|
-
inputSchema: {
|
|
1535
|
-
$ref: "#/definitions/virtual-account_signing_create_input",
|
|
1536
|
-
definitions: {
|
|
1537
|
-
"virtual-account_signing_create_input": {
|
|
1538
|
-
type: "object",
|
|
1539
|
-
properties: {
|
|
1540
|
-
contentId: {
|
|
1541
|
-
type: "string",
|
|
1542
|
-
description: "The unique ID of the content to sign"
|
|
1543
|
-
}
|
|
1544
|
-
},
|
|
1545
|
-
required: [
|
|
1546
|
-
"contentId"
|
|
1547
|
-
],
|
|
1548
|
-
additionalProperties: false
|
|
1549
|
-
}
|
|
1550
|
-
},
|
|
1551
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1552
|
-
}
|
|
1553
|
-
},
|
|
1554
|
-
{
|
|
1555
|
-
name: "virtual-account_signing_list",
|
|
1556
|
-
description: "List all signed documents",
|
|
1557
|
-
inputSchema: {
|
|
1558
|
-
$ref: "#/definitions/virtual-account_signing_list_input",
|
|
1559
|
-
definitions: {
|
|
1560
|
-
"virtual-account_signing_list_input": {
|
|
1561
|
-
type: "object",
|
|
1562
|
-
properties: {},
|
|
1563
|
-
additionalProperties: false
|
|
1564
|
-
}
|
|
1565
|
-
},
|
|
1566
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1567
|
-
}
|
|
1568
|
-
},
|
|
1569
|
-
{
|
|
1570
|
-
name: "virtual-account_signing_required_list",
|
|
1571
|
-
description: "List documents that require your signature",
|
|
1572
|
-
inputSchema: {
|
|
1573
|
-
$ref: "#/definitions/virtual-account_signing_required_list_input",
|
|
1574
|
-
definitions: {
|
|
1575
|
-
"virtual-account_signing_required_list_input": {
|
|
1576
|
-
type: "object",
|
|
1577
|
-
properties: {},
|
|
1578
|
-
additionalProperties: false
|
|
1579
|
-
}
|
|
1580
|
-
},
|
|
1581
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1582
|
-
}
|
|
1583
|
-
},
|
|
1584
|
-
{
|
|
1585
|
-
name: "virtual-account_transaction_list",
|
|
1586
|
-
description: "List virtual account transactions",
|
|
1587
|
-
inputSchema: {
|
|
1588
|
-
$ref: "#/definitions/virtual-account_transaction_list_input",
|
|
1589
|
-
definitions: {
|
|
1590
|
-
"virtual-account_transaction_list_input": {
|
|
1591
|
-
type: "object",
|
|
1592
|
-
properties: {},
|
|
1593
|
-
additionalProperties: false
|
|
1594
|
-
}
|
|
1595
|
-
},
|
|
1596
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1597
|
-
}
|
|
1598
|
-
},
|
|
1599
|
-
{
|
|
1600
|
-
name: "virtual-account_wallet_list",
|
|
1601
|
-
description: "List registered wallets",
|
|
1602
|
-
inputSchema: {
|
|
1603
|
-
$ref: "#/definitions/virtual-account_wallet_list_input",
|
|
1604
|
-
definitions: {
|
|
1605
|
-
"virtual-account_wallet_list_input": {
|
|
1606
|
-
type: "object",
|
|
1607
|
-
properties: {},
|
|
1608
|
-
additionalProperties: false
|
|
1609
|
-
}
|
|
1610
|
-
},
|
|
1611
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1612
|
-
}
|
|
1613
|
-
},
|
|
1614
|
-
{
|
|
1615
|
-
name: "virtual-account_wallet_register",
|
|
1616
|
-
description: "Register a wallet using a signed verification message",
|
|
1617
|
-
inputSchema: {
|
|
1618
|
-
$ref: "#/definitions/virtual-account_wallet_register_input",
|
|
1619
|
-
definitions: {
|
|
1620
|
-
"virtual-account_wallet_register_input": {
|
|
1621
|
-
type: "object",
|
|
1622
|
-
properties: {
|
|
1623
|
-
wallet: {
|
|
1624
|
-
type: "string",
|
|
1625
|
-
description: "The wallet address to register"
|
|
1626
|
-
},
|
|
1627
|
-
message: {
|
|
1628
|
-
type: "string",
|
|
1629
|
-
description: "The verification message (from virtual-account_wallet_registration-message_create)"
|
|
1630
|
-
},
|
|
1631
|
-
signature: {
|
|
1632
|
-
type: "string",
|
|
1633
|
-
description: "Base58-encoded signature of the message"
|
|
1634
|
-
}
|
|
1635
|
-
},
|
|
1636
|
-
required: [
|
|
1637
|
-
"wallet",
|
|
1638
|
-
"message",
|
|
1639
|
-
"signature"
|
|
1640
|
-
],
|
|
1641
|
-
additionalProperties: false
|
|
1642
|
-
}
|
|
1643
|
-
},
|
|
1644
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1645
|
-
}
|
|
1646
|
-
},
|
|
1647
|
-
{
|
|
1648
|
-
name: "virtual-account_wallet_registration-message_create",
|
|
1649
|
-
description: "Create the verification message to register a wallet",
|
|
1650
|
-
inputSchema: {
|
|
1651
|
-
$ref: "#/definitions/virtual-account_wallet_registration-message_create_input",
|
|
1652
|
-
definitions: {
|
|
1653
|
-
"virtual-account_wallet_registration-message_create_input": {
|
|
1654
|
-
type: "object",
|
|
1655
|
-
properties: {
|
|
1656
|
-
wallet: {
|
|
1657
|
-
type: "string",
|
|
1658
|
-
description: "The wallet address to register"
|
|
1659
|
-
}
|
|
1660
|
-
},
|
|
1661
|
-
required: [
|
|
1662
|
-
"wallet"
|
|
1663
|
-
],
|
|
1664
|
-
additionalProperties: false
|
|
1665
|
-
}
|
|
1666
|
-
},
|
|
1667
|
-
$schema: "http://json-schema.org/draft-07/schema#"
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
];
|
|
1671
|
-
|
|
1672
|
-
// src/tools/wallet/create/tool.ts
|
|
1673
|
-
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
1674
|
-
import { join as join3 } from "path";
|
|
1675
|
-
import { homedir as homedir3 } from "os";
|
|
1676
|
-
import { generateMnemonic } from "@scure/bip39";
|
|
1677
|
-
import { wordlist as english } from "@scure/bip39/wordlists/english";
|
|
1678
|
-
|
|
1679
|
-
// src/tools/shared.ts
|
|
1680
|
-
var defineToolSchema = (config) => config;
|
|
1681
|
-
var createTool = (schema, handler) => ({
|
|
1682
|
-
schema,
|
|
1683
|
-
handler: async (params) => {
|
|
1684
|
-
const parsedInput = schema.input.parse(params);
|
|
1685
|
-
const result = await handler(parsedInput);
|
|
1686
|
-
return schema.output.parse(result);
|
|
1687
|
-
}
|
|
1688
|
-
});
|
|
1689
|
-
|
|
1690
|
-
// src/tools/wallet/vault.ts
|
|
1691
|
-
import {
|
|
1692
|
-
readFileSync as readFileSync2,
|
|
1693
|
-
writeFileSync as writeFileSync2,
|
|
1694
|
-
existsSync as existsSync2,
|
|
1695
|
-
renameSync as renameSync2,
|
|
1696
|
-
mkdirSync as mkdirSync2
|
|
1697
|
-
} from "fs";
|
|
1698
|
-
import { join as join2 } from "path";
|
|
1699
|
-
import { homedir as homedir2 } from "os";
|
|
1700
|
-
import {
|
|
1701
|
-
randomBytes as randomBytes2,
|
|
1702
|
-
randomUUID as randomUUID2,
|
|
1703
|
-
scryptSync,
|
|
1704
|
-
createCipheriv,
|
|
1705
|
-
createDecipheriv
|
|
1706
|
-
} from "crypto";
|
|
1707
|
-
var CONFIG_DIR2 = join2(homedir2(), ".config", "moonpay");
|
|
1708
|
-
var VAULT_PATH = join2(CONFIG_DIR2, "vault.json");
|
|
1709
|
-
function ensureConfigDir2() {
|
|
1710
|
-
mkdirSync2(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
1711
|
-
}
|
|
1712
|
-
function loadVault() {
|
|
1713
|
-
if (!existsSync2(VAULT_PATH)) {
|
|
1714
|
-
const empty = { version: 1, entries: {} };
|
|
1715
|
-
saveVault(empty);
|
|
1716
|
-
return empty;
|
|
1717
|
-
}
|
|
1718
|
-
const raw = JSON.parse(readFileSync2(VAULT_PATH, "utf-8"));
|
|
1719
|
-
const locked = lockedVaultDataSchema.safeParse(raw);
|
|
1720
|
-
if (locked.success) {
|
|
1721
|
-
throw new Error(
|
|
1722
|
-
"Vault is locked. Run `mp wallet unlock` to decrypt it first."
|
|
1723
|
-
);
|
|
1724
|
-
}
|
|
1725
|
-
const result = vaultDataSchema.safeParse(raw);
|
|
1726
|
-
if (!result.success) {
|
|
1727
|
-
throw new Error("Vault file is corrupted or has an unknown format.");
|
|
1728
|
-
}
|
|
1729
|
-
return result.data;
|
|
1730
|
-
}
|
|
1731
|
-
function saveVault(vault) {
|
|
1732
|
-
ensureConfigDir2();
|
|
1733
|
-
const tmpPath = join2(
|
|
1734
|
-
CONFIG_DIR2,
|
|
1735
|
-
`.vault.${randomBytes2(4).toString("hex")}.tmp`
|
|
1736
|
-
);
|
|
1737
|
-
writeFileSync2(tmpPath, JSON.stringify(vault, null, 2), { mode: 384 });
|
|
1738
|
-
renameSync2(tmpPath, VAULT_PATH);
|
|
1739
|
-
}
|
|
1740
|
-
function isVaultLocked() {
|
|
1741
|
-
if (!existsSync2(VAULT_PATH)) return false;
|
|
1742
|
-
const raw = JSON.parse(readFileSync2(VAULT_PATH, "utf-8"));
|
|
1743
|
-
return lockedVaultDataSchema.safeParse(raw).success;
|
|
1744
|
-
}
|
|
1745
|
-
function addHdEntry(mnemonic) {
|
|
1746
|
-
const vault = loadVault();
|
|
1747
|
-
const id = randomUUID2();
|
|
1748
|
-
const entry = { id, type: "hd", mnemonic };
|
|
1749
|
-
vault.entries[id] = entry;
|
|
1750
|
-
saveVault(vault);
|
|
1751
|
-
return id;
|
|
1752
|
-
}
|
|
1753
|
-
function addImportedEntry(chain, privateKey) {
|
|
1754
|
-
const vault = loadVault();
|
|
1755
|
-
const id = randomUUID2();
|
|
1756
|
-
const entry = { id, type: "imported", chain, privateKey };
|
|
1757
|
-
vault.entries[id] = entry;
|
|
1758
|
-
saveVault(vault);
|
|
1759
|
-
return id;
|
|
1760
|
-
}
|
|
1761
|
-
function removeVaultEntry(id) {
|
|
1762
|
-
const vault = loadVault();
|
|
1763
|
-
delete vault.entries[id];
|
|
1764
|
-
saveVault(vault);
|
|
1765
|
-
}
|
|
1766
|
-
function resolveSigningKey(wallet, chain) {
|
|
1767
|
-
const vault = loadVault();
|
|
1768
|
-
const entry = vault.entries[wallet.vaultRef];
|
|
1769
|
-
if (!entry) {
|
|
1770
|
-
throw new Error(
|
|
1771
|
-
`Vault entry not found for wallet "${wallet.name}". The vault may be out of sync.`
|
|
1772
|
-
);
|
|
1773
|
-
}
|
|
1774
|
-
const keyChain = KEY_CHAIN_MAP[chain];
|
|
1775
|
-
if (entry.type === "imported") {
|
|
1776
|
-
if (entry.chain !== keyChain) {
|
|
1777
|
-
throw new Error(
|
|
1778
|
-
`Wallet "${wallet.name}" was imported for ${entry.chain}, cannot sign for ${chain}.`
|
|
1779
|
-
);
|
|
1780
|
-
}
|
|
1781
|
-
return {
|
|
1782
|
-
privateKey: decodePrivateKey(entry.privateKey, keyChain),
|
|
1783
|
-
address: wallet.addresses[keyChain]
|
|
1784
|
-
};
|
|
1785
|
-
}
|
|
1786
|
-
const derived = deriveKeyForChain(entry.mnemonic, keyChain, wallet.account ?? 0);
|
|
1787
|
-
return {
|
|
1788
|
-
privateKey: derived.privateKey,
|
|
1789
|
-
address: derived.address
|
|
1790
|
-
};
|
|
1791
|
-
}
|
|
1792
|
-
function decodePrivateKey(key, chain) {
|
|
1793
|
-
if (chain === "solana") {
|
|
1794
|
-
const bs583 = __require("bs58");
|
|
1795
|
-
return bs583.default.decode(key);
|
|
1796
|
-
}
|
|
1797
|
-
return Uint8Array.from(Buffer.from(key, "hex"));
|
|
1798
|
-
}
|
|
1799
|
-
var SCRYPT_N = 2 ** 14;
|
|
1800
|
-
var SCRYPT_R = 8;
|
|
1801
|
-
var SCRYPT_P = 1;
|
|
1802
|
-
var KEY_LENGTH = 32;
|
|
1803
|
-
function deriveEncryptionKey(password, salt) {
|
|
1804
|
-
return scryptSync(password, salt, KEY_LENGTH, {
|
|
1805
|
-
N: SCRYPT_N,
|
|
1806
|
-
r: SCRYPT_R,
|
|
1807
|
-
p: SCRYPT_P
|
|
1808
|
-
});
|
|
1809
|
-
}
|
|
1810
|
-
function lockVault(password) {
|
|
1811
|
-
const vault = loadVault();
|
|
1812
|
-
const salt = randomBytes2(32);
|
|
1813
|
-
const key = deriveEncryptionKey(password, salt);
|
|
1814
|
-
const iv = randomBytes2(12);
|
|
1815
|
-
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
1816
|
-
const plaintext = JSON.stringify(vault);
|
|
1817
|
-
const encrypted = Buffer.concat([
|
|
1818
|
-
cipher.update(plaintext, "utf8"),
|
|
1819
|
-
cipher.final()
|
|
1820
|
-
]);
|
|
1821
|
-
const tag = cipher.getAuthTag();
|
|
1822
|
-
const locked = {
|
|
1823
|
-
version: 1,
|
|
1824
|
-
locked: true,
|
|
1825
|
-
ciphertext: encrypted.toString("base64"),
|
|
1826
|
-
iv: iv.toString("base64"),
|
|
1827
|
-
salt: salt.toString("base64"),
|
|
1828
|
-
tag: tag.toString("base64")
|
|
1829
|
-
};
|
|
1830
|
-
ensureConfigDir2();
|
|
1831
|
-
const tmpPath = join2(
|
|
1832
|
-
CONFIG_DIR2,
|
|
1833
|
-
`.vault.${randomBytes2(4).toString("hex")}.tmp`
|
|
1834
|
-
);
|
|
1835
|
-
writeFileSync2(tmpPath, JSON.stringify(locked, null, 2), { mode: 384 });
|
|
1836
|
-
renameSync2(tmpPath, VAULT_PATH);
|
|
1837
|
-
}
|
|
1838
|
-
function unlockVault(password) {
|
|
1839
|
-
if (!existsSync2(VAULT_PATH)) {
|
|
1840
|
-
throw new Error("No vault found. Create a wallet first.");
|
|
1841
|
-
}
|
|
1842
|
-
const raw = JSON.parse(readFileSync2(VAULT_PATH, "utf-8"));
|
|
1843
|
-
const locked = lockedVaultDataSchema.safeParse(raw);
|
|
1844
|
-
if (!locked.success) {
|
|
1845
|
-
throw new Error("Vault is not locked.");
|
|
1846
|
-
}
|
|
1847
|
-
const { ciphertext, iv, salt, tag } = locked.data;
|
|
1848
|
-
const saltBuf = Buffer.from(salt, "base64");
|
|
1849
|
-
const key = deriveEncryptionKey(password, saltBuf);
|
|
1850
|
-
const ivBuf = Buffer.from(iv, "base64");
|
|
1851
|
-
const tagBuf = Buffer.from(tag, "base64");
|
|
1852
|
-
const ciphertextBuf = Buffer.from(ciphertext, "base64");
|
|
1853
|
-
const decipher = createDecipheriv("aes-256-gcm", key, ivBuf, { authTagLength: 16 });
|
|
1854
|
-
decipher.setAuthTag(tagBuf);
|
|
1855
|
-
let decrypted;
|
|
1856
|
-
try {
|
|
1857
|
-
decrypted = Buffer.concat([
|
|
1858
|
-
decipher.update(ciphertextBuf),
|
|
1859
|
-
decipher.final()
|
|
1860
|
-
]);
|
|
1861
|
-
} catch {
|
|
1862
|
-
throw new Error("Wrong password.");
|
|
1863
|
-
}
|
|
1864
|
-
const vault = vaultDataSchema.parse(JSON.parse(decrypted.toString("utf8")));
|
|
1865
|
-
saveVault(vault);
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
// src/tools/wallet/create/schema.ts
|
|
1869
|
-
import { z } from "zod";
|
|
1870
|
-
var walletCreateSchema = defineToolSchema({
|
|
1871
|
-
name: "wallet_create",
|
|
1872
|
-
description: "Create a new multi-chain HD wallet. Generates a BIP39 mnemonic seed phrase and derives addresses for Solana, Ethereum (shared by Base, Arbitrum, Polygon, Optimism, BNB, Avalanche), Bitcoin, and Tron. The mnemonic is saved to a local backup file (path returned in output) \u2014 it is never printed or returned in the response. To derive additional accounts from the same mnemonic, pass --from with an existing wallet name and --account with the desired index.",
|
|
1873
|
-
input: z.object({
|
|
1874
|
-
name: z.string().describe("Wallet name"),
|
|
1875
|
-
from: z.string().nullable().describe("Name of an existing HD wallet to derive from. Uses the same mnemonic but a different account index. Omit to generate a new mnemonic."),
|
|
1876
|
-
account: z.number().int().min(0).nullable().describe("BIP44 account index (0, 1, 2, ...). Required when using --from. Omit for new wallets (defaults to 0).")
|
|
1877
|
-
}),
|
|
1878
|
-
output: z.object({
|
|
1879
|
-
name: z.string().describe("Wallet name"),
|
|
1880
|
-
account: z.number().describe("BIP44 account index used for derivation"),
|
|
1881
|
-
addresses: z.record(keyChainSchema, z.string()).describe("Derived addresses per chain (solana, ethereum, bitcoin, tron)"),
|
|
1882
|
-
backupPath: z.string().nullable().describe("Path to the mnemonic backup file (0o600 permissions). Null when derived from an existing wallet.")
|
|
1883
|
-
})
|
|
1884
|
-
});
|
|
1885
|
-
|
|
1886
|
-
// src/tools/wallet/create/tool.ts
|
|
1887
|
-
var walletCreate = createTool(walletCreateSchema, async (params) => {
|
|
1888
|
-
if (params.from) {
|
|
1889
|
-
if (params.account === null) {
|
|
1890
|
-
throw new Error("--account is required when using --from.");
|
|
1891
|
-
}
|
|
1892
|
-
return deriveFromExisting(params.name, params.from, params.account);
|
|
1893
|
-
}
|
|
1894
|
-
return createNew(params.name);
|
|
1895
|
-
});
|
|
1896
|
-
function createNew(name) {
|
|
1897
|
-
const mnemonic = generateMnemonic(english, 128);
|
|
1898
|
-
const addresses = deriveAllAddresses(mnemonic);
|
|
1899
|
-
const vaultRef = addHdEntry(mnemonic);
|
|
1900
|
-
const metadata = {
|
|
1901
|
-
name,
|
|
1902
|
-
type: "hd",
|
|
1903
|
-
vaultRef,
|
|
1904
|
-
account: 0,
|
|
1905
|
-
addresses,
|
|
1906
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1907
|
-
};
|
|
1908
|
-
saveWalletMetadata(metadata);
|
|
1909
|
-
const backupDir = join3(homedir3(), ".config", "moonpay", "backups");
|
|
1910
|
-
mkdirSync3(backupDir, { recursive: true, mode: 448 });
|
|
1911
|
-
const backupPath = join3(backupDir, `${name}.mnemonic`);
|
|
1912
|
-
writeFileSync3(backupPath, mnemonic + "\n", { mode: 384 });
|
|
1913
|
-
return { name, account: 0, addresses, backupPath };
|
|
1914
|
-
}
|
|
1915
|
-
function deriveFromExisting(name, from, account) {
|
|
1916
|
-
const source = loadWallet(from);
|
|
1917
|
-
if (source.type !== "hd") {
|
|
1918
|
-
throw new Error(
|
|
1919
|
-
`Wallet "${from}" is an imported single-key wallet. Only HD wallets support account derivation.`
|
|
1920
|
-
);
|
|
1921
|
-
}
|
|
1922
|
-
const vault = loadVault();
|
|
1923
|
-
const entry = vault.entries[source.vaultRef];
|
|
1924
|
-
if (!entry || entry.type !== "hd") {
|
|
1925
|
-
throw new Error(`Vault entry for wallet "${from}" not found or is not HD.`);
|
|
1926
|
-
}
|
|
1927
|
-
const addresses = deriveAllAddresses(entry.mnemonic, account);
|
|
1928
|
-
const metadata = {
|
|
1929
|
-
name,
|
|
1930
|
-
type: "hd",
|
|
1931
|
-
vaultRef: source.vaultRef,
|
|
1932
|
-
account,
|
|
1933
|
-
addresses,
|
|
1934
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1935
|
-
};
|
|
1936
|
-
saveWalletMetadata(metadata);
|
|
1937
|
-
return { name, account, addresses, backupPath: null };
|
|
1938
|
-
}
|
|
1939
|
-
|
|
1940
|
-
// src/tools/wallet/import/tool.ts
|
|
1941
|
-
import { validateMnemonic } from "@scure/bip39";
|
|
1942
|
-
import { wordlist as english2 } from "@scure/bip39/wordlists/english";
|
|
1943
|
-
import { Keypair } from "@solana/web3.js";
|
|
1944
|
-
import bs58 from "bs58";
|
|
1945
|
-
import { createInterface as createInterface2 } from "readline";
|
|
1946
|
-
|
|
1947
|
-
// src/tools/wallet/import/schema.ts
|
|
1948
|
-
import { z as z2 } from "zod";
|
|
1949
|
-
var walletImportSchema = defineToolSchema({
|
|
1950
|
-
name: "wallet_import",
|
|
1951
|
-
description: "Import a wallet from a BIP39 mnemonic (HD, all chains) or a single private key (one chain). Provide either --mnemonic or --key, not both.",
|
|
1952
|
-
input: z2.object({
|
|
1953
|
-
name: z2.string().describe("Wallet name"),
|
|
1954
|
-
mnemonic: z2.string().nullable().describe("BIP39 mnemonic seed phrase (for HD wallet import)"),
|
|
1955
|
-
key: z2.string().nullable().describe(
|
|
1956
|
-
"Private key: base58 for Solana, hex for EVM/Bitcoin (for single-chain import)"
|
|
1957
|
-
),
|
|
1958
|
-
chain: chainSchema.nullable().describe(
|
|
1959
|
-
"Chain for single-key import: solana, ethereum, base, arbitrum, or bitcoin (default solana)"
|
|
1960
|
-
)
|
|
1961
|
-
}),
|
|
1962
|
-
output: z2.object({
|
|
1963
|
-
name: z2.string().describe("Wallet name"),
|
|
1964
|
-
type: z2.enum(["hd", "imported"]).describe("Wallet type"),
|
|
1965
|
-
addresses: z2.record(keyChainSchema, z2.string()).describe("Wallet addresses per chain")
|
|
1966
|
-
})
|
|
1967
|
-
});
|
|
1968
|
-
|
|
1969
|
-
// src/tools/wallet/import/tool.ts
|
|
1970
|
-
async function promptSecret(prompt) {
|
|
1971
|
-
const rl = createInterface2({ input: process.stdin, output: process.stderr });
|
|
1972
|
-
return new Promise((resolve) => {
|
|
1973
|
-
rl.question(prompt, (answer) => {
|
|
1974
|
-
rl.close();
|
|
1975
|
-
resolve(answer.trim());
|
|
1976
|
-
});
|
|
1977
|
-
});
|
|
1978
|
-
}
|
|
1979
|
-
var walletImport = createTool(walletImportSchema, async (params) => {
|
|
1980
|
-
if (params.mnemonic && params.key) {
|
|
1981
|
-
throw new Error("Provide either --mnemonic or --key, not both.");
|
|
1982
|
-
}
|
|
1983
|
-
if (params.mnemonic) {
|
|
1984
|
-
return importMnemonic(params.name, params.mnemonic);
|
|
1985
|
-
}
|
|
1986
|
-
const chain = params.chain ? KEY_CHAIN_MAP[params.chain] : "solana";
|
|
1987
|
-
const key = params.key !== null ? params.key : await promptSecret("Enter private key: ");
|
|
1988
|
-
return importKey(params.name, chain, key);
|
|
1989
|
-
});
|
|
1990
|
-
async function importMnemonic(name, mnemonic) {
|
|
1991
|
-
const trimmed = mnemonic.trim().toLowerCase();
|
|
1992
|
-
if (!validateMnemonic(trimmed, english2)) {
|
|
1993
|
-
throw new Error("Invalid BIP39 mnemonic.");
|
|
1994
|
-
}
|
|
1995
|
-
const addresses = deriveAllAddresses(trimmed);
|
|
1996
|
-
const vaultRef = addHdEntry(trimmed);
|
|
1997
|
-
const metadata = {
|
|
1998
|
-
name,
|
|
1999
|
-
type: "hd",
|
|
2000
|
-
vaultRef,
|
|
2001
|
-
account: 0,
|
|
2002
|
-
addresses,
|
|
2003
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2004
|
-
};
|
|
2005
|
-
saveWalletMetadata(metadata);
|
|
2006
|
-
return { name, type: "hd", addresses };
|
|
2007
|
-
}
|
|
2008
|
-
async function importKey(name, chain, key) {
|
|
2009
|
-
let address;
|
|
2010
|
-
if (chain === "solana") {
|
|
2011
|
-
try {
|
|
2012
|
-
const secretKeyBytes = bs58.decode(key);
|
|
2013
|
-
const keypair = Keypair.fromSecretKey(secretKeyBytes);
|
|
2014
|
-
address = keypair.publicKey.toBase58();
|
|
2015
|
-
} catch {
|
|
2016
|
-
throw new Error(
|
|
2017
|
-
"Invalid private key. Expected a base58-encoded Solana secret key."
|
|
2018
|
-
);
|
|
2019
|
-
}
|
|
2020
|
-
} else if (chain === "ethereum") {
|
|
2021
|
-
const cleanKey = key.startsWith("0x") ? key.slice(2) : key;
|
|
2022
|
-
if (!/^[0-9a-fA-F]{64}$/.test(cleanKey)) {
|
|
2023
|
-
throw new Error(
|
|
2024
|
-
"Invalid private key. Expected a 64-character hex string for EVM."
|
|
2025
|
-
);
|
|
2026
|
-
}
|
|
2027
|
-
const { deriveKeyForChain: deriveKeyForChain2 } = await import("./chains-R754DQM5.js");
|
|
2028
|
-
const { HDKey } = await import("@scure/bip32");
|
|
2029
|
-
const ecc2 = await import("tiny-secp256k1");
|
|
2030
|
-
const { createHash: createHash3 } = await import("crypto");
|
|
2031
|
-
const privKeyBytes = Buffer.from(cleanKey, "hex");
|
|
2032
|
-
const pubKey = ecc2.pointFromScalar(privKeyBytes);
|
|
2033
|
-
if (!pubKey) throw new Error("Invalid private key.");
|
|
2034
|
-
const uncompressed = ecc2.pointCompress(pubKey, false);
|
|
2035
|
-
const hash = createHash3("sha3-256").update(uncompressed.slice(1)).digest();
|
|
2036
|
-
address = "0x" + hash.slice(-20).toString("hex");
|
|
2037
|
-
key = cleanKey;
|
|
2038
|
-
} else {
|
|
2039
|
-
const cleanKey = key.startsWith("0x") ? key.slice(2) : key;
|
|
2040
|
-
if (!/^[0-9a-fA-F]{64}$/.test(cleanKey)) {
|
|
2041
|
-
throw new Error(
|
|
2042
|
-
"Invalid private key. Expected a 64-character hex string for Bitcoin."
|
|
2043
|
-
);
|
|
2044
|
-
}
|
|
2045
|
-
const bitcoin = await import("bitcoinjs-lib");
|
|
2046
|
-
const ECPairFactory = (await import("ecpair")).default;
|
|
2047
|
-
const ecc2 = await import("tiny-secp256k1");
|
|
2048
|
-
const ECPair = ECPairFactory(ecc2);
|
|
2049
|
-
const keyPair = ECPair.fromPrivateKey(Buffer.from(cleanKey, "hex"));
|
|
2050
|
-
const { address: btcAddress } = bitcoin.payments.p2wpkh({
|
|
2051
|
-
pubkey: Buffer.from(keyPair.publicKey)
|
|
2052
|
-
});
|
|
2053
|
-
if (!btcAddress) throw new Error("Failed to derive Bitcoin address.");
|
|
2054
|
-
address = btcAddress;
|
|
2055
|
-
key = cleanKey;
|
|
2056
|
-
}
|
|
2057
|
-
const vaultRef = addImportedEntry(chain, key);
|
|
2058
|
-
const metadata = {
|
|
2059
|
-
name,
|
|
2060
|
-
type: "imported",
|
|
2061
|
-
vaultRef,
|
|
2062
|
-
account: 0,
|
|
2063
|
-
addresses: { [chain]: address },
|
|
2064
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2065
|
-
};
|
|
2066
|
-
saveWalletMetadata(metadata);
|
|
2067
|
-
return { name, type: "imported", addresses: { [chain]: address } };
|
|
2068
|
-
}
|
|
2069
|
-
|
|
2070
|
-
// src/tools/wallet/list/schema.ts
|
|
2071
|
-
import { z as z3 } from "zod";
|
|
2072
|
-
var walletListSchema = defineToolSchema({
|
|
2073
|
-
name: "wallet_list",
|
|
2074
|
-
description: "List all local wallets",
|
|
2075
|
-
input: z3.object({}),
|
|
2076
|
-
output: z3.array(walletInfoSchema)
|
|
2077
|
-
});
|
|
2078
|
-
|
|
2079
|
-
// src/tools/wallet/list/tool.ts
|
|
2080
|
-
var walletList = createTool(walletListSchema, async () => {
|
|
2081
|
-
return loadAllWallets();
|
|
2082
|
-
});
|
|
2083
|
-
|
|
2084
|
-
// src/tools/wallet/retrieve/schema.ts
|
|
2085
|
-
import { z as z4 } from "zod";
|
|
2086
|
-
var walletRetrieveSchema = defineToolSchema({
|
|
2087
|
-
name: "wallet_retrieve",
|
|
2088
|
-
description: "Get details of a specific wallet",
|
|
2089
|
-
input: z4.object({
|
|
2090
|
-
wallet: z4.string().describe("Wallet name or address")
|
|
2091
|
-
}),
|
|
2092
|
-
output: walletInfoSchema
|
|
2093
|
-
});
|
|
2094
|
-
|
|
2095
|
-
// src/tools/wallet/retrieve/tool.ts
|
|
2096
|
-
var walletRetrieve = createTool(
|
|
2097
|
-
walletRetrieveSchema,
|
|
2098
|
-
async (params) => {
|
|
2099
|
-
return loadWallet(params.wallet);
|
|
2100
|
-
}
|
|
2101
|
-
);
|
|
2102
|
-
|
|
2103
|
-
// src/tools/wallet/delete/schema.ts
|
|
2104
|
-
import { z as z5 } from "zod";
|
|
2105
|
-
var walletDeleteSchema = defineToolSchema({
|
|
2106
|
-
name: "wallet_delete",
|
|
2107
|
-
description: "Permanently delete a local wallet. This removes the private key file and cannot be undone.",
|
|
2108
|
-
input: z5.object({
|
|
2109
|
-
wallet: z5.string().describe("Name or address of the wallet to delete"),
|
|
2110
|
-
confirm: z5.boolean().describe("Must be true to confirm deletion")
|
|
2111
|
-
}),
|
|
2112
|
-
output: z5.object({
|
|
2113
|
-
name: z5.string().describe("Name of the deleted wallet"),
|
|
2114
|
-
deleted: z5.literal(true)
|
|
2115
|
-
})
|
|
2116
|
-
});
|
|
2117
|
-
|
|
2118
|
-
// src/tools/wallet/delete/tool.ts
|
|
2119
|
-
var walletDelete = createTool(walletDeleteSchema, async (params) => {
|
|
2120
|
-
if (!params.confirm) {
|
|
2121
|
-
throw new Error(
|
|
2122
|
-
"Deletion not confirmed. Pass --confirm to permanently delete this wallet."
|
|
2123
|
-
);
|
|
2124
|
-
}
|
|
2125
|
-
const wallet = loadWallet(params.wallet);
|
|
2126
|
-
removeVaultEntry(wallet.vaultRef);
|
|
2127
|
-
deleteWalletFile(wallet.name);
|
|
2128
|
-
return { name: wallet.name, deleted: true };
|
|
2129
|
-
});
|
|
2130
|
-
|
|
2131
|
-
// src/tools/transaction/sign/tool.ts
|
|
2132
|
-
import { Keypair as Keypair2, VersionedTransaction } from "@solana/web3.js";
|
|
2133
|
-
|
|
2134
|
-
// src/tools/transaction/sign/schema.ts
|
|
2135
|
-
import { z as z6 } from "zod";
|
|
2136
|
-
var transactionSignSchema = defineToolSchema({
|
|
2137
|
-
name: "transaction_sign",
|
|
2138
|
-
description: "Sign a transaction with a local wallet. Supports Solana (VersionedTransaction), EVM (RLP-encoded), and Bitcoin (PSBT) transactions.",
|
|
2139
|
-
input: z6.object({
|
|
2140
|
-
wallet: z6.string().describe("Wallet name or address"),
|
|
2141
|
-
chain: chainSchema.describe(
|
|
2142
|
-
"Chain: solana, ethereum, base, arbitrum, or bitcoin"
|
|
2143
|
-
),
|
|
2144
|
-
transaction: z6.string().describe("Base64-encoded unsigned transaction")
|
|
2145
|
-
}),
|
|
2146
|
-
output: z6.object({
|
|
2147
|
-
transaction: z6.string().describe("Base64-encoded signed transaction")
|
|
2148
|
-
})
|
|
2149
|
-
});
|
|
2150
|
-
|
|
2151
|
-
// src/tools/transaction/sign/tool.ts
|
|
2152
|
-
var transactionSign = createTool(
|
|
2153
|
-
transactionSignSchema,
|
|
2154
|
-
async (params) => {
|
|
2155
|
-
const wallet = loadWallet(params.wallet);
|
|
2156
|
-
const chain = params.chain;
|
|
2157
|
-
const keyChain = KEY_CHAIN_MAP[chain];
|
|
2158
|
-
const { privateKey } = resolveSigningKey(wallet, chain);
|
|
2159
|
-
const txBytes = Buffer.from(params.transaction.trim(), "base64");
|
|
2160
|
-
switch (keyChain) {
|
|
2161
|
-
case "solana":
|
|
2162
|
-
return signSolana(privateKey, txBytes);
|
|
2163
|
-
case "ethereum":
|
|
2164
|
-
return signEvm(privateKey, txBytes);
|
|
2165
|
-
case "bitcoin":
|
|
2166
|
-
return signBitcoin(privateKey, txBytes);
|
|
2167
|
-
case "tron":
|
|
2168
|
-
return signEvm(privateKey, txBytes);
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
);
|
|
2172
|
-
function signSolana(privateKey, txBytes) {
|
|
2173
|
-
const tx = VersionedTransaction.deserialize(txBytes);
|
|
2174
|
-
const keypair = Keypair2.fromSecretKey(privateKey);
|
|
2175
|
-
tx.sign([keypair]);
|
|
2176
|
-
return { transaction: Buffer.from(tx.serialize()).toString("base64") };
|
|
2177
|
-
}
|
|
2178
|
-
async function signEvm(privateKey, txBytes) {
|
|
2179
|
-
const { createHash: createHash3 } = await import("crypto");
|
|
2180
|
-
const ecc2 = await import("tiny-secp256k1");
|
|
2181
|
-
const hash = createHash3("sha3-256").update(txBytes).digest();
|
|
2182
|
-
const sig = ecc2.sign(hash, privateKey);
|
|
2183
|
-
if (!sig) throw new Error("EVM signing failed");
|
|
2184
|
-
const signed = Buffer.concat([txBytes, Buffer.from(sig)]);
|
|
2185
|
-
return { transaction: signed.toString("base64") };
|
|
2186
|
-
}
|
|
2187
|
-
async function signBitcoin(privateKey, txBytes) {
|
|
2188
|
-
const bitcoin = await import("bitcoinjs-lib");
|
|
2189
|
-
const ECPairFactory = (await import("ecpair")).default;
|
|
2190
|
-
const ecc2 = await import("tiny-secp256k1");
|
|
2191
|
-
const ECPair = ECPairFactory(ecc2);
|
|
2192
|
-
const keyPair = ECPair.fromPrivateKey(Buffer.from(privateKey));
|
|
2193
|
-
const psbt = bitcoin.Psbt.fromBase64(txBytes.toString("base64"));
|
|
2194
|
-
psbt.signAllInputs(keyPair);
|
|
2195
|
-
return { transaction: psbt.toBase64() };
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
// src/tools/message/sign/tool.ts
|
|
2199
|
-
import { createHash as createHash2 } from "crypto";
|
|
2200
|
-
import { Keypair as Keypair3 } from "@solana/web3.js";
|
|
2201
|
-
import bs582 from "bs58";
|
|
2202
|
-
import nacl from "tweetnacl";
|
|
2203
|
-
import * as ecc from "tiny-secp256k1";
|
|
2204
|
-
|
|
2205
|
-
// src/tools/message/sign/schema.ts
|
|
2206
|
-
import { z as z7 } from "zod";
|
|
2207
|
-
var messageSignSchema = defineToolSchema({
|
|
2208
|
-
name: "message_sign",
|
|
2209
|
-
description: "Sign a message with a local wallet. Supports Solana (ed25519), EVM (EIP-191 personal sign), and Bitcoin (secp256k1 ECDSA).",
|
|
2210
|
-
input: z7.object({
|
|
2211
|
-
wallet: z7.string().describe("Wallet address or name to sign with"),
|
|
2212
|
-
chain: chainSchema.describe(
|
|
2213
|
-
"Chain: solana, ethereum, base, arbitrum, or bitcoin"
|
|
2214
|
-
),
|
|
2215
|
-
message: z7.string().describe("Message text to sign")
|
|
2216
|
-
}),
|
|
2217
|
-
output: z7.object({
|
|
2218
|
-
signature: z7.string().describe(
|
|
2219
|
-
"Signature: base58 for Solana, hex (0x-prefixed) for EVM/Bitcoin"
|
|
2220
|
-
)
|
|
2221
|
-
})
|
|
2222
|
-
});
|
|
2223
|
-
|
|
2224
|
-
// src/tools/message/sign/tool.ts
|
|
2225
|
-
var messageSign = createTool(messageSignSchema, async (params) => {
|
|
2226
|
-
const wallet = loadWallet(params.wallet);
|
|
2227
|
-
const chain = params.chain;
|
|
2228
|
-
const keyChain = KEY_CHAIN_MAP[chain];
|
|
2229
|
-
const { privateKey } = resolveSigningKey(wallet, chain);
|
|
2230
|
-
const messageBytes = Buffer.from(params.message, "utf8");
|
|
2231
|
-
switch (keyChain) {
|
|
2232
|
-
case "solana":
|
|
2233
|
-
return signSolana2(privateKey, messageBytes);
|
|
2234
|
-
case "ethereum":
|
|
2235
|
-
return signEvm2(privateKey, messageBytes);
|
|
2236
|
-
case "bitcoin":
|
|
2237
|
-
return signBitcoin2(privateKey, messageBytes);
|
|
2238
|
-
case "tron":
|
|
2239
|
-
return signEvm2(privateKey, messageBytes);
|
|
2240
|
-
}
|
|
2241
|
-
});
|
|
2242
|
-
function signSolana2(privateKey, messageBytes) {
|
|
2243
|
-
const keypair = Keypair3.fromSecretKey(privateKey);
|
|
2244
|
-
const signatureBytes = nacl.sign.detached(messageBytes, keypair.secretKey);
|
|
2245
|
-
return { signature: bs582.encode(signatureBytes) };
|
|
2246
|
-
}
|
|
2247
|
-
function signEvm2(privateKey, messageBytes) {
|
|
2248
|
-
const prefix = Buffer.from(
|
|
2249
|
-
`Ethereum Signed Message:
|
|
2250
|
-
${messageBytes.length}`,
|
|
2251
|
-
"utf8"
|
|
2252
|
-
);
|
|
2253
|
-
const prefixed = Buffer.concat([prefix, messageBytes]);
|
|
2254
|
-
const hash = createHash2("sha3-256").update(prefixed).digest();
|
|
2255
|
-
const sig = ecc.sign(hash, privateKey);
|
|
2256
|
-
if (!sig) throw new Error("EVM message signing failed");
|
|
2257
|
-
return { signature: "0x" + Buffer.from(sig).toString("hex") };
|
|
2258
|
-
}
|
|
2259
|
-
function signBitcoin2(privateKey, messageBytes) {
|
|
2260
|
-
const hash1 = createHash2("sha256").update(messageBytes).digest();
|
|
2261
|
-
const hash2 = createHash2("sha256").update(hash1).digest();
|
|
2262
|
-
const sig = ecc.sign(hash2, privateKey);
|
|
2263
|
-
if (!sig) throw new Error("Bitcoin message signing failed");
|
|
2264
|
-
return { signature: "0x" + Buffer.from(sig).toString("hex") };
|
|
2265
|
-
}
|
|
2266
|
-
|
|
2267
|
-
// src/tools/wallet/lock/tool.ts
|
|
2268
|
-
import { createInterface as createInterface3 } from "readline";
|
|
2269
|
-
|
|
2270
|
-
// src/tools/wallet/lock/schema.ts
|
|
2271
|
-
import { z as z8 } from "zod";
|
|
2272
|
-
var walletLockSchema = defineToolSchema({
|
|
2273
|
-
name: "wallet_lock",
|
|
2274
|
-
description: "Encrypt the vault with a password. All signing operations will fail until `wallet unlock` is called. Password is prompted interactively.",
|
|
2275
|
-
input: z8.object({}),
|
|
2276
|
-
output: z8.object({
|
|
2277
|
-
locked: z8.literal(true)
|
|
2278
|
-
})
|
|
2279
|
-
});
|
|
2280
|
-
|
|
2281
|
-
// src/tools/wallet/lock/tool.ts
|
|
2282
|
-
async function promptPassword(prompt) {
|
|
2283
|
-
const rl = createInterface3({ input: process.stdin, output: process.stderr });
|
|
2284
|
-
return new Promise((resolve) => {
|
|
2285
|
-
rl.question(prompt, (answer) => {
|
|
2286
|
-
rl.close();
|
|
2287
|
-
resolve(answer);
|
|
2288
|
-
});
|
|
2289
|
-
});
|
|
2290
|
-
}
|
|
2291
|
-
var walletLock = createTool(walletLockSchema, async () => {
|
|
2292
|
-
if (isVaultLocked()) {
|
|
2293
|
-
throw new Error("Vault is already locked.");
|
|
2294
|
-
}
|
|
2295
|
-
const password = await promptPassword("Enter password to encrypt vault: ");
|
|
2296
|
-
if (!password) {
|
|
2297
|
-
throw new Error("Password cannot be empty.");
|
|
2298
|
-
}
|
|
2299
|
-
const confirm = await promptPassword("Confirm password: ");
|
|
2300
|
-
if (password !== confirm) {
|
|
2301
|
-
throw new Error("Passwords do not match.");
|
|
2302
|
-
}
|
|
2303
|
-
lockVault(password);
|
|
2304
|
-
return { locked: true };
|
|
2305
|
-
});
|
|
2306
|
-
|
|
2307
|
-
// src/tools/wallet/unlock/tool.ts
|
|
2308
|
-
import { createInterface as createInterface4 } from "readline";
|
|
2309
|
-
|
|
2310
|
-
// src/tools/wallet/unlock/schema.ts
|
|
2311
|
-
import { z as z9 } from "zod";
|
|
2312
|
-
var walletUnlockSchema = defineToolSchema({
|
|
2313
|
-
name: "wallet_unlock",
|
|
2314
|
-
description: "Decrypt the vault with a password. Restores access to all signing operations. Password is prompted interactively.",
|
|
2315
|
-
input: z9.object({}),
|
|
2316
|
-
output: z9.object({
|
|
2317
|
-
unlocked: z9.literal(true)
|
|
2318
|
-
})
|
|
2319
|
-
});
|
|
2320
|
-
|
|
2321
|
-
// src/tools/wallet/unlock/tool.ts
|
|
2322
|
-
async function promptPassword2(prompt) {
|
|
2323
|
-
const rl = createInterface4({ input: process.stdin, output: process.stderr });
|
|
2324
|
-
return new Promise((resolve) => {
|
|
2325
|
-
rl.question(prompt, (answer) => {
|
|
2326
|
-
rl.close();
|
|
2327
|
-
resolve(answer);
|
|
2328
|
-
});
|
|
2329
|
-
});
|
|
2330
|
-
}
|
|
2331
|
-
var walletUnlock = createTool(walletUnlockSchema, async () => {
|
|
2332
|
-
if (!isVaultLocked()) {
|
|
2333
|
-
throw new Error("Vault is not locked.");
|
|
2334
|
-
}
|
|
2335
|
-
const password = await promptPassword2("Enter password to decrypt vault: ");
|
|
2336
|
-
unlockVault(password);
|
|
2337
|
-
return { unlocked: true };
|
|
2338
|
-
});
|
|
2339
|
-
|
|
2340
|
-
// src/tools/bitcoin/balance/tool.ts
|
|
2341
|
-
import https from "https";
|
|
2342
|
-
|
|
2343
|
-
// src/tools/bitcoin/balance/schema.ts
|
|
2344
|
-
import { z as z10 } from "zod";
|
|
2345
|
-
var bitcoinBalanceRetrieveSchema = defineToolSchema({
|
|
2346
|
-
name: "bitcoin_balance_retrieve",
|
|
2347
|
-
description: "Get the BTC balance of a Bitcoin address. Returns confirmed and unconfirmed balances in BTC and satoshis.",
|
|
2348
|
-
input: z10.object({
|
|
2349
|
-
wallet: z10.string().describe("Bitcoin address (bc1...) or wallet name")
|
|
2350
|
-
}),
|
|
2351
|
-
output: z10.object({
|
|
2352
|
-
address: z10.string().describe("Bitcoin address"),
|
|
2353
|
-
confirmed: z10.object({
|
|
2354
|
-
btc: z10.string().describe("Confirmed balance in BTC"),
|
|
2355
|
-
sats: z10.number().describe("Confirmed balance in satoshis")
|
|
2356
|
-
}),
|
|
2357
|
-
unconfirmed: z10.object({
|
|
2358
|
-
btc: z10.string().describe("Unconfirmed (pending) balance in BTC"),
|
|
2359
|
-
sats: z10.number().describe("Unconfirmed (pending) balance in satoshis")
|
|
2360
|
-
}),
|
|
2361
|
-
total: z10.object({
|
|
2362
|
-
btc: z10.string().describe("Total balance in BTC"),
|
|
2363
|
-
sats: z10.number().describe("Total balance in satoshis")
|
|
2364
|
-
})
|
|
2365
|
-
})
|
|
2366
|
-
});
|
|
2367
|
-
|
|
2368
|
-
// src/tools/bitcoin/balance/tool.ts
|
|
2369
|
-
var SATS_PER_BTC = 1e8;
|
|
2370
|
-
function satsToBtc(sats) {
|
|
2371
|
-
return (sats / SATS_PER_BTC).toFixed(8);
|
|
2372
|
-
}
|
|
2373
|
-
function fetchJson(url) {
|
|
2374
|
-
return new Promise((resolve, reject) => {
|
|
2375
|
-
https.get(url, { headers: { "User-Agent": "moonpay-cli" } }, (res) => {
|
|
2376
|
-
if (res.statusCode !== 200) {
|
|
2377
|
-
reject(new Error(`HTTP ${res.statusCode} from ${url}`));
|
|
2378
|
-
res.resume();
|
|
2379
|
-
return;
|
|
2380
|
-
}
|
|
2381
|
-
let data = "";
|
|
2382
|
-
res.on("data", (chunk) => data += chunk);
|
|
2383
|
-
res.on("end", () => {
|
|
2384
|
-
try {
|
|
2385
|
-
resolve(JSON.parse(data));
|
|
2386
|
-
} catch {
|
|
2387
|
-
reject(new Error("Invalid JSON response"));
|
|
2388
|
-
}
|
|
2389
|
-
});
|
|
2390
|
-
}).on("error", reject);
|
|
2391
|
-
});
|
|
2392
|
-
}
|
|
2393
|
-
var bitcoinBalanceRetrieve = createTool(
|
|
2394
|
-
bitcoinBalanceRetrieveSchema,
|
|
2395
|
-
async (params) => {
|
|
2396
|
-
let address = params.wallet;
|
|
2397
|
-
if (!address.startsWith("bc1") && !address.startsWith("1") && !address.startsWith("3")) {
|
|
2398
|
-
const { loadWallet: loadWallet2 } = await import("./server-IUOCZFT7.js");
|
|
2399
|
-
const wallet = loadWallet2(address);
|
|
2400
|
-
const btcAddress = wallet.addresses.bitcoin;
|
|
2401
|
-
if (!btcAddress) {
|
|
2402
|
-
throw new Error(
|
|
2403
|
-
`Wallet "${address}" has no Bitcoin address. It may be an imported single-chain wallet.`
|
|
2404
|
-
);
|
|
2405
|
-
}
|
|
2406
|
-
address = btcAddress;
|
|
2407
|
-
}
|
|
2408
|
-
const data = await fetchJson(
|
|
2409
|
-
`https://mempool.space/api/address/${address}`
|
|
2410
|
-
);
|
|
2411
|
-
const confirmedSats = data.chain_stats.funded_txo_sum - data.chain_stats.spent_txo_sum;
|
|
2412
|
-
const unconfirmedSats = data.mempool_stats.funded_txo_sum - data.mempool_stats.spent_txo_sum;
|
|
2413
|
-
const totalSats = confirmedSats + unconfirmedSats;
|
|
2414
|
-
return {
|
|
2415
|
-
address,
|
|
2416
|
-
confirmed: { btc: satsToBtc(confirmedSats), sats: confirmedSats },
|
|
2417
|
-
unconfirmed: { btc: satsToBtc(unconfirmedSats), sats: unconfirmedSats },
|
|
2418
|
-
total: { btc: satsToBtc(totalSats), sats: totalSats }
|
|
2419
|
-
};
|
|
2420
|
-
}
|
|
2421
|
-
);
|
|
2422
|
-
|
|
2423
|
-
export {
|
|
2424
|
-
getConfigOrDefault,
|
|
2425
|
-
clearCredentials,
|
|
2426
|
-
resolveBaseUrl,
|
|
2427
|
-
login,
|
|
2428
|
-
callTool,
|
|
2429
|
-
schemas_default,
|
|
2430
|
-
defineToolSchema,
|
|
2431
|
-
createTool,
|
|
2432
|
-
resolveSigningKey,
|
|
2433
|
-
walletCreate,
|
|
2434
|
-
walletImport,
|
|
2435
|
-
walletList,
|
|
2436
|
-
walletRetrieve,
|
|
2437
|
-
walletDelete,
|
|
2438
|
-
transactionSign,
|
|
2439
|
-
messageSign,
|
|
2440
|
-
walletLock,
|
|
2441
|
-
walletUnlock,
|
|
2442
|
-
bitcoinBalanceRetrieve
|
|
2443
|
-
};
|
|
2444
|
-
//# sourceMappingURL=chunk-DAQDHLPY.js.map
|