@heyamiko/amiko-cli 0.3.3 → 0.3.5
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 +30 -1
- package/dist/index.js +244 -62
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,13 +122,40 @@ amiko creator publish <id> # publish a draft
|
|
|
122
122
|
amiko creator payout # request payout
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
## Swap (Solana)
|
|
126
|
+
|
|
127
|
+
Swap tokens on Solana via Jupiter aggregator (0.1% platform fee):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
amiko swap quote 5 usdt usdc # get swap quote
|
|
131
|
+
amiko swap quote 0.1 sol usdc # SOL → USDC quote
|
|
132
|
+
amiko swap quote 1 amiko usdc # AMIKO → USDC quote
|
|
133
|
+
amiko swap send 5 usdt usdc # build swap transaction
|
|
134
|
+
amiko swap send 5 usdt usdc --raw # output raw base64 tx
|
|
135
|
+
amiko swap tokens # list supported tokens
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Supports symbols (sol, usdc, usdt, amiko, bonk, jup, ...) or raw mint addresses.
|
|
139
|
+
|
|
140
|
+
## Bridge (Cross-Chain)
|
|
141
|
+
|
|
142
|
+
Bridge tokens across 26+ chains via Across Protocol:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
amiko bridge quote 10 # Solana → Tempo (default)
|
|
146
|
+
amiko bridge quote 5 --from base --to tempo
|
|
147
|
+
amiko bridge send 10 --from solana --to tempo --recipient 0x...
|
|
148
|
+
amiko bridge routes # list available routes
|
|
149
|
+
amiko bridge limits # check transfer limits
|
|
150
|
+
amiko bridge status <txHash> # track bridge status
|
|
151
|
+
```
|
|
152
|
+
|
|
125
153
|
## Other Commands
|
|
126
154
|
|
|
127
155
|
```bash
|
|
128
156
|
amiko reputation [address] # TARS score
|
|
129
157
|
amiko discover # MPP service info
|
|
130
158
|
amiko ping # health check
|
|
131
|
-
amiko bridge quote 5 # cross-chain bridge quote
|
|
132
159
|
amiko config show # view config
|
|
133
160
|
amiko config set <key> <value> # set config value
|
|
134
161
|
amiko update # update CLI to latest
|
|
@@ -166,6 +193,8 @@ src/
|
|
|
166
193
|
├── commands/
|
|
167
194
|
│ ├── connect.ts # connect (code, API key, browser)
|
|
168
195
|
│ ├── credits.ts # credits balance + topup
|
|
196
|
+
│ ├── swap.ts # Solana token swaps (Jupiter)
|
|
197
|
+
│ ├── bridge.ts # cross-chain bridging (Across)
|
|
169
198
|
│ ├── browse.ts # marketplace browsing
|
|
170
199
|
│ ├── call.ts # call agents
|
|
171
200
|
│ ├── wallet.ts # MPP wallet management
|
package/dist/index.js
CHANGED
|
@@ -1886,6 +1886,76 @@ var require_commander = __commonJS((exports) => {
|
|
|
1886
1886
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
1887
1887
|
});
|
|
1888
1888
|
|
|
1889
|
+
// src/lib/config.ts
|
|
1890
|
+
var exports_config = {};
|
|
1891
|
+
__export(exports_config, {
|
|
1892
|
+
saveConfig: () => saveConfig,
|
|
1893
|
+
resetConfig: () => resetConfig,
|
|
1894
|
+
loadConfig: () => loadConfig,
|
|
1895
|
+
getPrivyToken: () => getPrivyToken,
|
|
1896
|
+
getConfigPath: () => getConfigPath
|
|
1897
|
+
});
|
|
1898
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
1899
|
+
import { homedir } from "node:os";
|
|
1900
|
+
import { join } from "node:path";
|
|
1901
|
+
function loadConfig() {
|
|
1902
|
+
if (!existsSync(CONFIG_FILE))
|
|
1903
|
+
return { ...DEFAULTS };
|
|
1904
|
+
try {
|
|
1905
|
+
const raw = readFileSync(CONFIG_FILE, "utf-8");
|
|
1906
|
+
const parsed = JSON.parse(raw);
|
|
1907
|
+
return normalizeConfig({ ...DEFAULTS, ...parsed });
|
|
1908
|
+
} catch {
|
|
1909
|
+
return { ...DEFAULTS };
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
function saveConfig(config) {
|
|
1913
|
+
const current = loadConfig();
|
|
1914
|
+
const merged = normalizeConfig({ ...current, ...config });
|
|
1915
|
+
if (!existsSync(CONFIG_DIR))
|
|
1916
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
1917
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + `
|
|
1918
|
+
`);
|
|
1919
|
+
return merged;
|
|
1920
|
+
}
|
|
1921
|
+
function getConfigPath() {
|
|
1922
|
+
return CONFIG_FILE;
|
|
1923
|
+
}
|
|
1924
|
+
function resetConfig() {
|
|
1925
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
1926
|
+
return false;
|
|
1927
|
+
}
|
|
1928
|
+
unlinkSync(CONFIG_FILE);
|
|
1929
|
+
return true;
|
|
1930
|
+
}
|
|
1931
|
+
function getPrivyToken(config) {
|
|
1932
|
+
return config.privyToken || config.creatorToken;
|
|
1933
|
+
}
|
|
1934
|
+
function normalizeConfig(config) {
|
|
1935
|
+
const normalized = { ...config };
|
|
1936
|
+
if (!normalized.privyToken && normalized.creatorToken) {
|
|
1937
|
+
normalized.privyToken = normalized.creatorToken;
|
|
1938
|
+
}
|
|
1939
|
+
if (LEGACY_SITE_BASES.has(normalized.siteBase)) {
|
|
1940
|
+
normalized.siteBase = DEFAULTS.siteBase;
|
|
1941
|
+
}
|
|
1942
|
+
return normalized;
|
|
1943
|
+
}
|
|
1944
|
+
var CONFIG_DIR, CONFIG_FILE, DEFAULTS, LEGACY_SITE_BASES;
|
|
1945
|
+
var init_config = __esm(() => {
|
|
1946
|
+
CONFIG_DIR = join(homedir(), ".amiko");
|
|
1947
|
+
CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
1948
|
+
DEFAULTS = {
|
|
1949
|
+
apiBase: "https://mpp.amikomarkets.com",
|
|
1950
|
+
billingBase: "https://billing.heyamiko.com",
|
|
1951
|
+
siteBase: "https://platform.heyamiko.com"
|
|
1952
|
+
};
|
|
1953
|
+
LEGACY_SITE_BASES = new Set([
|
|
1954
|
+
"https://amiko-markets.vercel.app",
|
|
1955
|
+
"https://amiko-markets.vercel.app/"
|
|
1956
|
+
]);
|
|
1957
|
+
});
|
|
1958
|
+
|
|
1889
1959
|
// node_modules/cli-spinners/spinners.json
|
|
1890
1960
|
var require_spinners = __commonJS((exports, module) => {
|
|
1891
1961
|
module.exports = {
|
|
@@ -21037,7 +21107,7 @@ function nonoptional(innerType, params) {
|
|
|
21037
21107
|
...normalizeParams(params)
|
|
21038
21108
|
});
|
|
21039
21109
|
}
|
|
21040
|
-
function
|
|
21110
|
+
function success3(innerType) {
|
|
21041
21111
|
return new ZodMiniSuccess({
|
|
21042
21112
|
type: "success",
|
|
21043
21113
|
innerType
|
|
@@ -21560,7 +21630,7 @@ __export(exports_external, {
|
|
|
21560
21630
|
templateLiteral: () => templateLiteral,
|
|
21561
21631
|
symbol: () => symbol,
|
|
21562
21632
|
superRefine: () => superRefine,
|
|
21563
|
-
success: () =>
|
|
21633
|
+
success: () => success3,
|
|
21564
21634
|
stringbool: () => stringbool,
|
|
21565
21635
|
stringFormat: () => stringFormat,
|
|
21566
21636
|
string: () => string2,
|
|
@@ -21821,7 +21891,7 @@ __export(exports_zod, {
|
|
|
21821
21891
|
templateLiteral: () => templateLiteral,
|
|
21822
21892
|
symbol: () => symbol,
|
|
21823
21893
|
superRefine: () => superRefine,
|
|
21824
|
-
success: () =>
|
|
21894
|
+
success: () => success3,
|
|
21825
21895
|
stringbool: () => stringbool,
|
|
21826
21896
|
stringFormat: () => stringFormat,
|
|
21827
21897
|
string: () => string2,
|
|
@@ -23300,67 +23370,9 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
23300
23370
|
var source_default = chalk;
|
|
23301
23371
|
|
|
23302
23372
|
// src/onboarding.ts
|
|
23373
|
+
init_config();
|
|
23303
23374
|
import { createInterface } from "node:readline";
|
|
23304
23375
|
|
|
23305
|
-
// src/lib/config.ts
|
|
23306
|
-
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
23307
|
-
import { homedir } from "node:os";
|
|
23308
|
-
import { join } from "node:path";
|
|
23309
|
-
var CONFIG_DIR = join(homedir(), ".amiko");
|
|
23310
|
-
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
23311
|
-
var DEFAULTS = {
|
|
23312
|
-
apiBase: "https://mpp.amikomarkets.com",
|
|
23313
|
-
billingBase: "https://billing.heyamiko.com",
|
|
23314
|
-
siteBase: "https://platform.heyamiko.com"
|
|
23315
|
-
};
|
|
23316
|
-
var LEGACY_SITE_BASES = new Set([
|
|
23317
|
-
"https://amiko-markets.vercel.app",
|
|
23318
|
-
"https://amiko-markets.vercel.app/"
|
|
23319
|
-
]);
|
|
23320
|
-
function loadConfig() {
|
|
23321
|
-
if (!existsSync(CONFIG_FILE))
|
|
23322
|
-
return { ...DEFAULTS };
|
|
23323
|
-
try {
|
|
23324
|
-
const raw = readFileSync(CONFIG_FILE, "utf-8");
|
|
23325
|
-
const parsed = JSON.parse(raw);
|
|
23326
|
-
return normalizeConfig({ ...DEFAULTS, ...parsed });
|
|
23327
|
-
} catch {
|
|
23328
|
-
return { ...DEFAULTS };
|
|
23329
|
-
}
|
|
23330
|
-
}
|
|
23331
|
-
function saveConfig(config) {
|
|
23332
|
-
const current = loadConfig();
|
|
23333
|
-
const merged = normalizeConfig({ ...current, ...config });
|
|
23334
|
-
if (!existsSync(CONFIG_DIR))
|
|
23335
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
23336
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + `
|
|
23337
|
-
`);
|
|
23338
|
-
return merged;
|
|
23339
|
-
}
|
|
23340
|
-
function getConfigPath() {
|
|
23341
|
-
return CONFIG_FILE;
|
|
23342
|
-
}
|
|
23343
|
-
function resetConfig() {
|
|
23344
|
-
if (!existsSync(CONFIG_FILE)) {
|
|
23345
|
-
return false;
|
|
23346
|
-
}
|
|
23347
|
-
unlinkSync(CONFIG_FILE);
|
|
23348
|
-
return true;
|
|
23349
|
-
}
|
|
23350
|
-
function getPrivyToken(config) {
|
|
23351
|
-
return config.privyToken || config.creatorToken;
|
|
23352
|
-
}
|
|
23353
|
-
function normalizeConfig(config) {
|
|
23354
|
-
const normalized = { ...config };
|
|
23355
|
-
if (!normalized.privyToken && normalized.creatorToken) {
|
|
23356
|
-
normalized.privyToken = normalized.creatorToken;
|
|
23357
|
-
}
|
|
23358
|
-
if (LEGACY_SITE_BASES.has(normalized.siteBase)) {
|
|
23359
|
-
normalized.siteBase = DEFAULTS.siteBase;
|
|
23360
|
-
}
|
|
23361
|
-
return normalized;
|
|
23362
|
-
}
|
|
23363
|
-
|
|
23364
23376
|
// src/lib/format.ts
|
|
23365
23377
|
function table(rows) {
|
|
23366
23378
|
if (rows.length === 0)
|
|
@@ -24372,6 +24384,7 @@ function ora(options) {
|
|
|
24372
24384
|
}
|
|
24373
24385
|
|
|
24374
24386
|
// src/lib/api.ts
|
|
24387
|
+
init_config();
|
|
24375
24388
|
function mppBase() {
|
|
24376
24389
|
return trimBase(loadConfig().apiBase);
|
|
24377
24390
|
}
|
|
@@ -24480,6 +24493,7 @@ function trimBase(base) {
|
|
|
24480
24493
|
}
|
|
24481
24494
|
|
|
24482
24495
|
// src/commands/browse.ts
|
|
24496
|
+
init_config();
|
|
24483
24497
|
function siteUrl(agentSlug) {
|
|
24484
24498
|
const config = loadConfig();
|
|
24485
24499
|
return `${config.siteBase}/agents/${agentSlug}`;
|
|
@@ -24615,6 +24629,7 @@ function registerBrowseCommand(program2) {
|
|
|
24615
24629
|
}
|
|
24616
24630
|
|
|
24617
24631
|
// src/commands/call.ts
|
|
24632
|
+
init_config();
|
|
24618
24633
|
import { createInterface as createInterface2 } from "node:readline";
|
|
24619
24634
|
|
|
24620
24635
|
// src/lib/tempo.ts
|
|
@@ -24950,6 +24965,7 @@ function registerCallCommand(program2) {
|
|
|
24950
24965
|
}
|
|
24951
24966
|
|
|
24952
24967
|
// src/commands/wallet.ts
|
|
24968
|
+
init_config();
|
|
24953
24969
|
function sanitizeTempoWhoamiOutput(output) {
|
|
24954
24970
|
return output.replace(/^(\s*key:\s*)"[^"\n]*"$/m, '$1"[redacted]"');
|
|
24955
24971
|
}
|
|
@@ -25148,6 +25164,7 @@ Tip: add --open to auto-launch in browser.`));
|
|
|
25148
25164
|
}
|
|
25149
25165
|
|
|
25150
25166
|
// src/commands/creator.ts
|
|
25167
|
+
init_config();
|
|
25151
25168
|
function requireCreatorToken() {
|
|
25152
25169
|
const config = loadConfig();
|
|
25153
25170
|
const token = getPrivyToken(config);
|
|
@@ -25277,6 +25294,7 @@ function registerCreatorCommand(program2) {
|
|
|
25277
25294
|
}
|
|
25278
25295
|
|
|
25279
25296
|
// src/commands/reputation.ts
|
|
25297
|
+
init_config();
|
|
25280
25298
|
function registerReputationCommand(program2) {
|
|
25281
25299
|
program2.command("reputation").alias("rep").description("Look up TARS reputation for a wallet address").argument("[address]", "Wallet address (uses configured wallet if omitted)").action(async (address) => {
|
|
25282
25300
|
const addr = address || loadConfig().wallet;
|
|
@@ -25333,6 +25351,7 @@ function scoreTier(score) {
|
|
|
25333
25351
|
}
|
|
25334
25352
|
|
|
25335
25353
|
// src/commands/config.ts
|
|
25354
|
+
init_config();
|
|
25336
25355
|
var VALID_KEYS = [
|
|
25337
25356
|
"apiBase",
|
|
25338
25357
|
"billingBase",
|
|
@@ -25402,6 +25421,7 @@ function maskKey(key) {
|
|
|
25402
25421
|
}
|
|
25403
25422
|
|
|
25404
25423
|
// src/commands/discovery.ts
|
|
25424
|
+
init_config();
|
|
25405
25425
|
function registerDiscoveryCommand(program2) {
|
|
25406
25426
|
program2.command("discover").alias("status").description("Show MPP service info, endpoints, and pricing").action(async () => {
|
|
25407
25427
|
const config = loadConfig();
|
|
@@ -25489,6 +25509,7 @@ function registerDiscoveryCommand(program2) {
|
|
|
25489
25509
|
}
|
|
25490
25510
|
|
|
25491
25511
|
// src/commands/marketplace.ts
|
|
25512
|
+
init_config();
|
|
25492
25513
|
function timeAgo(timestamp) {
|
|
25493
25514
|
const seconds = Math.floor((Date.now() - new Date(timestamp).getTime()) / 1000);
|
|
25494
25515
|
if (seconds < 60)
|
|
@@ -25620,6 +25641,7 @@ function registerMarketplaceCommand(program2) {
|
|
|
25620
25641
|
}
|
|
25621
25642
|
|
|
25622
25643
|
// src/commands/login.ts
|
|
25644
|
+
init_config();
|
|
25623
25645
|
import { createServer } from "node:http";
|
|
25624
25646
|
import { randomBytes } from "node:crypto";
|
|
25625
25647
|
import { execSync } from "node:child_process";
|
|
@@ -25886,6 +25908,7 @@ function startCallbackServer(expectedState, timeoutMs = 120000, acknowledgementT
|
|
|
25886
25908
|
}
|
|
25887
25909
|
|
|
25888
25910
|
// src/lib/across.ts
|
|
25911
|
+
init_config();
|
|
25889
25912
|
function getBridgeBase() {
|
|
25890
25913
|
const config = loadConfig();
|
|
25891
25914
|
return `${config.apiBase}/v1/bridge`;
|
|
@@ -26035,6 +26058,7 @@ function getUsdcAddress(chainId) {
|
|
|
26035
26058
|
}
|
|
26036
26059
|
|
|
26037
26060
|
// src/commands/bridge.ts
|
|
26061
|
+
init_config();
|
|
26038
26062
|
var DEFAULT_ORIGIN = CHAINS.solana;
|
|
26039
26063
|
var DEFAULT_DESTINATION = CHAINS.tempo;
|
|
26040
26064
|
function registerBridgeCommand(program2) {
|
|
@@ -26367,9 +26391,162 @@ function registerBridgeCommand(program2) {
|
|
|
26367
26391
|
});
|
|
26368
26392
|
}
|
|
26369
26393
|
|
|
26394
|
+
// src/commands/swap.ts
|
|
26395
|
+
var KNOWN_TOKENS = {
|
|
26396
|
+
sol: { mint: "So11111111111111111111111111111111111111112", decimals: 9, name: "SOL" },
|
|
26397
|
+
wsol: { mint: "So11111111111111111111111111111111111111112", decimals: 9, name: "Wrapped SOL" },
|
|
26398
|
+
usdc: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6, name: "USDC" },
|
|
26399
|
+
usdt: { mint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", decimals: 6, name: "USDT" },
|
|
26400
|
+
pyusd: { mint: "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", decimals: 6, name: "PYUSD" },
|
|
26401
|
+
bonk: { mint: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", decimals: 5, name: "BONK" },
|
|
26402
|
+
jup: { mint: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", decimals: 6, name: "JUP" },
|
|
26403
|
+
jitosol: { mint: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", decimals: 9, name: "JitoSOL" },
|
|
26404
|
+
ray: { mint: "4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", decimals: 6, name: "RAY" },
|
|
26405
|
+
amiko: { mint: "AY1Ww6MxwC3cCiyrandHqLrp4FXvzgcwQTZpJ2FEpump", decimals: 6, name: "AMIKO" }
|
|
26406
|
+
};
|
|
26407
|
+
function resolveToken(input) {
|
|
26408
|
+
const lower = input.toLowerCase();
|
|
26409
|
+
const known = KNOWN_TOKENS[lower];
|
|
26410
|
+
if (known)
|
|
26411
|
+
return { mint: known.mint, decimals: known.decimals, symbol: known.name };
|
|
26412
|
+
return { mint: input, decimals: 6, symbol: truncAddr(input) };
|
|
26413
|
+
}
|
|
26414
|
+
function formatAmount(raw, decimals) {
|
|
26415
|
+
const n = typeof raw === "string" ? parseInt(raw, 10) : raw;
|
|
26416
|
+
return (n / 10 ** decimals).toFixed(decimals > 6 ? 4 : decimals);
|
|
26417
|
+
}
|
|
26418
|
+
function parseAmount(amount, decimals) {
|
|
26419
|
+
const num = parseFloat(amount);
|
|
26420
|
+
if (isNaN(num) || num <= 0)
|
|
26421
|
+
throw new Error(`Invalid amount: ${amount}`);
|
|
26422
|
+
return Math.round(num * 10 ** decimals).toString();
|
|
26423
|
+
}
|
|
26424
|
+
function registerSwapCommand(program2) {
|
|
26425
|
+
const cmd = program2.command("swap").description("Swap tokens on Solana via Jupiter");
|
|
26426
|
+
cmd.command("quote").description("Get a swap quote for Solana tokens").argument("<amount>", "Amount to swap (e.g., 5, 0.1)").argument("<from>", "Input token (sol, usdc, usdt, bonk, or mint address)").argument("<to>", "Output token (sol, usdc, usdt, bonk, or mint address)").option("--slippage <bps>", "Slippage tolerance in basis points", "50").action(async (amountStr, fromToken, toToken, opts) => {
|
|
26427
|
+
const spinner = ora("Fetching swap quote...").start();
|
|
26428
|
+
try {
|
|
26429
|
+
const input = resolveToken(fromToken);
|
|
26430
|
+
const output = resolveToken(toToken);
|
|
26431
|
+
const amount = parseAmount(amountStr, input.decimals);
|
|
26432
|
+
const params = new URLSearchParams({
|
|
26433
|
+
inputMint: input.mint,
|
|
26434
|
+
outputMint: output.mint,
|
|
26435
|
+
amount,
|
|
26436
|
+
slippageBps: opts.slippage
|
|
26437
|
+
});
|
|
26438
|
+
const quote = await get(`/v1/swap/quote?${params}`);
|
|
26439
|
+
spinner.stop();
|
|
26440
|
+
console.log(heading("Swap Quote"));
|
|
26441
|
+
console.log("");
|
|
26442
|
+
console.log(label("Input", `${formatAmount(quote.inAmount, input.decimals)} ${input.symbol}`));
|
|
26443
|
+
console.log(label("Output", `${formatAmount(quote.outAmount, output.decimals)} ${output.symbol}`));
|
|
26444
|
+
console.log(label("Min Output", `${formatAmount(quote.otherAmountThreshold, output.decimals)} ${output.symbol}`));
|
|
26445
|
+
if (quote.platformFee && parseInt(quote.platformFee.amount) > 0) {
|
|
26446
|
+
console.log(label("Platform Fee", `${formatAmount(quote.platformFee.amount, output.decimals)} ${output.symbol} (${quote.platformFee.feeBps} bps)`));
|
|
26447
|
+
}
|
|
26448
|
+
const impact = parseFloat(quote.priceImpactPct);
|
|
26449
|
+
if (impact > 0.1) {
|
|
26450
|
+
console.log(label("Price Impact", source_default.yellow(`${impact.toFixed(2)}%`)));
|
|
26451
|
+
} else {
|
|
26452
|
+
console.log(label("Price Impact", `${impact.toFixed(4)}%`));
|
|
26453
|
+
}
|
|
26454
|
+
console.log(label("Slippage", `${quote.slippageBps} bps`));
|
|
26455
|
+
if (quote.routePlan.length > 0) {
|
|
26456
|
+
const route = quote.routePlan.map((r) => r.swapInfo.label).join(" → ");
|
|
26457
|
+
console.log(label("Route", dim(route)));
|
|
26458
|
+
}
|
|
26459
|
+
console.log("");
|
|
26460
|
+
console.log(dim(`To execute: amiko swap send ${amountStr} ${fromToken} ${toToken}`));
|
|
26461
|
+
} catch (err) {
|
|
26462
|
+
spinner.stop();
|
|
26463
|
+
console.error(error(err instanceof Error ? err.message : "Failed to get quote"));
|
|
26464
|
+
process.exit(1);
|
|
26465
|
+
}
|
|
26466
|
+
});
|
|
26467
|
+
cmd.command("send").description("Execute a token swap on Solana").argument("<amount>", "Amount to swap (e.g., 5, 0.1)").argument("<from>", "Input token (sol, usdc, usdt, bonk, or mint address)").argument("<to>", "Output token (sol, usdc, usdt, bonk, or mint address)").option("--wallet <address>", "Wallet address (uses config wallet by default)").option("--slippage <bps>", "Slippage tolerance in basis points", "50").option("--raw", "Output raw transaction base64 for manual signing").action(async (amountStr, fromToken, toToken, opts) => {
|
|
26468
|
+
const spinner = ora("Building swap transaction...").start();
|
|
26469
|
+
try {
|
|
26470
|
+
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
26471
|
+
const config = loadConfig2();
|
|
26472
|
+
const wallet = opts.wallet || config.wallet;
|
|
26473
|
+
if (!wallet) {
|
|
26474
|
+
spinner.stop();
|
|
26475
|
+
console.error(error("No wallet address. Provide --wallet or set one: amiko config set wallet <address>"));
|
|
26476
|
+
process.exit(1);
|
|
26477
|
+
}
|
|
26478
|
+
const input = resolveToken(fromToken);
|
|
26479
|
+
const output = resolveToken(toToken);
|
|
26480
|
+
const amount = parseAmount(amountStr, input.decimals);
|
|
26481
|
+
const params = new URLSearchParams({
|
|
26482
|
+
inputMint: input.mint,
|
|
26483
|
+
outputMint: output.mint,
|
|
26484
|
+
amount,
|
|
26485
|
+
slippageBps: opts.slippage
|
|
26486
|
+
});
|
|
26487
|
+
const quote = await get(`/v1/swap/quote?${params}`);
|
|
26488
|
+
const txResponse = await post("/v1/swap/transaction", {
|
|
26489
|
+
quoteResponse: quote,
|
|
26490
|
+
userPublicKey: wallet
|
|
26491
|
+
});
|
|
26492
|
+
spinner.stop();
|
|
26493
|
+
console.log(heading("Swap Transaction"));
|
|
26494
|
+
console.log("");
|
|
26495
|
+
console.log(label("Swap", `${formatAmount(quote.inAmount, input.decimals)} ${input.symbol} → ${formatAmount(quote.outAmount, output.decimals)} ${output.symbol}`));
|
|
26496
|
+
console.log(label("Wallet", truncAddr(wallet)));
|
|
26497
|
+
if (txResponse.simulationError) {
|
|
26498
|
+
console.log(warn(`Simulation warning: ${txResponse.simulationError.error}`));
|
|
26499
|
+
}
|
|
26500
|
+
if (opts.raw) {
|
|
26501
|
+
console.log("");
|
|
26502
|
+
console.log(heading("Raw Transaction (base64)"));
|
|
26503
|
+
console.log(txResponse.swapTransaction);
|
|
26504
|
+
console.log("");
|
|
26505
|
+
console.log(label("Block Height", String(txResponse.lastValidBlockHeight)));
|
|
26506
|
+
console.log(label("CU Limit", String(txResponse.computeUnitLimit)));
|
|
26507
|
+
console.log("");
|
|
26508
|
+
console.log(dim("Sign and submit this transaction with your wallet."));
|
|
26509
|
+
return;
|
|
26510
|
+
}
|
|
26511
|
+
console.log("");
|
|
26512
|
+
console.log(heading("Transaction Ready"));
|
|
26513
|
+
console.log("");
|
|
26514
|
+
console.log(dim("Sign and submit with your Solana wallet:"));
|
|
26515
|
+
console.log("");
|
|
26516
|
+
console.log(` ${source_default.cyan("amiko swap send")} ${amountStr} ${fromToken} ${toToken} --raw | solana-keygen sign`);
|
|
26517
|
+
console.log("");
|
|
26518
|
+
console.log(dim("Or use --raw to get the base64 transaction for any wallet."));
|
|
26519
|
+
} catch (err) {
|
|
26520
|
+
spinner.stop();
|
|
26521
|
+
console.error(error(err instanceof Error ? err.message : "Swap failed"));
|
|
26522
|
+
process.exit(1);
|
|
26523
|
+
}
|
|
26524
|
+
});
|
|
26525
|
+
cmd.command("tokens").description("List supported Solana tokens for swapping").action(async () => {
|
|
26526
|
+
const spinner = ora("Fetching tokens...").start();
|
|
26527
|
+
try {
|
|
26528
|
+
const data = await get("/v1/swap/tokens");
|
|
26529
|
+
spinner.stop();
|
|
26530
|
+
console.log(heading("Solana Tokens"));
|
|
26531
|
+
console.log(dim(`${data.tokens.length} tokens (source: ${data.provider})
|
|
26532
|
+
`));
|
|
26533
|
+
for (const t of data.tokens) {
|
|
26534
|
+
console.log(` ${source_default.cyan(t.symbol.padEnd(10))} ${t.name.padEnd(25)} ${dim(truncAddr(t.address))}`);
|
|
26535
|
+
}
|
|
26536
|
+
console.log("");
|
|
26537
|
+
console.log(dim("Use symbol or mint address: amiko swap quote 5 usdt usdc"));
|
|
26538
|
+
} catch (err) {
|
|
26539
|
+
spinner.stop();
|
|
26540
|
+
console.error(error(err instanceof Error ? err.message : "Failed to fetch tokens"));
|
|
26541
|
+
process.exit(1);
|
|
26542
|
+
}
|
|
26543
|
+
});
|
|
26544
|
+
}
|
|
26545
|
+
|
|
26370
26546
|
// src/commands/connect.ts
|
|
26371
26547
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
26372
26548
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
26549
|
+
init_config();
|
|
26373
26550
|
function openBrowser2(url) {
|
|
26374
26551
|
try {
|
|
26375
26552
|
const platform = process.platform;
|
|
@@ -26554,6 +26731,9 @@ Tip: you can also generate a connect link from your Amiko settings`));
|
|
|
26554
26731
|
});
|
|
26555
26732
|
}
|
|
26556
26733
|
|
|
26734
|
+
// src/commands/credits.ts
|
|
26735
|
+
init_config();
|
|
26736
|
+
|
|
26557
26737
|
// src/lib/agent-config.ts
|
|
26558
26738
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
26559
26739
|
import { join as join3, resolve } from "node:path";
|
|
@@ -26623,6 +26803,7 @@ function resolveAuth(cliConfig) {
|
|
|
26623
26803
|
}
|
|
26624
26804
|
|
|
26625
26805
|
// src/lib/mpp-topup.ts
|
|
26806
|
+
init_config();
|
|
26626
26807
|
async function mppCreditsTopup(params) {
|
|
26627
26808
|
const config2 = loadConfig();
|
|
26628
26809
|
const mppBase2 = config2.apiBase.replace(/\/$/, "");
|
|
@@ -27011,6 +27192,7 @@ registerDiscoveryCommand(program2);
|
|
|
27011
27192
|
registerMarketplaceCommand(program2);
|
|
27012
27193
|
registerLoginCommand(program2);
|
|
27013
27194
|
registerBridgeCommand(program2);
|
|
27195
|
+
registerSwapCommand(program2);
|
|
27014
27196
|
registerConnectCommand(program2);
|
|
27015
27197
|
registerCreditsCommand(program2);
|
|
27016
27198
|
registerUpdateCommand(program2);
|