@heyamiko/amiko-cli 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +159 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -75929,9 +75929,150 @@ function registerSearchCommand(program2) {
|
|
|
75929
75929
|
});
|
|
75930
75930
|
}
|
|
75931
75931
|
|
|
75932
|
-
// src/commands/
|
|
75932
|
+
// src/commands/image.ts
|
|
75933
75933
|
var TREASURY2 = "FPiZAf3jEnNfCwfvbv46jdPfHbmSepD4Q6iHiLJDQXvb";
|
|
75934
|
-
|
|
75934
|
+
function registerImageCommand(program2) {
|
|
75935
|
+
program2.command("image <prompt>").alias("img").description("Generate an image with DALL-E — costs 1 AMIKO").option("--size <size>", "Image size: 1024x1024, 1024x1792, 1792x1024", "1024x1024").option("--quality <q>", "Quality: standard or hd", "standard").option("--model <model>", "Model: dall-e-3 or dall-e-2", "dall-e-3").option("--raw", "Output raw JSON").action(async (prompt2, opts) => {
|
|
75936
|
+
const spinner = ora("Generating image...").start();
|
|
75937
|
+
try {
|
|
75938
|
+
const config2 = loadConfig();
|
|
75939
|
+
const auth = resolveAuth(config2);
|
|
75940
|
+
const mppBase2 = (config2.apiBase || "https://mpp.amikomarkets.com").replace(/\/$/, "");
|
|
75941
|
+
const billingBase2 = auth.billingBase || "https://billing.heyamiko.com";
|
|
75942
|
+
const billingToken = auth.platformKey || auth.twinToken || auth.privyToken;
|
|
75943
|
+
if (!billingToken) {
|
|
75944
|
+
spinner.stop();
|
|
75945
|
+
console.error(error("Not connected."));
|
|
75946
|
+
process.exit(1);
|
|
75947
|
+
}
|
|
75948
|
+
const allWallets = auth.agentWallets || config2.agentWallets || [];
|
|
75949
|
+
const solanaWallet = allWallets.find((w5) => w5.chain === "solana")?.address;
|
|
75950
|
+
if (!solanaWallet) {
|
|
75951
|
+
spinner.stop();
|
|
75952
|
+
console.error(error("No Solana wallet for AMIKO payment."));
|
|
75953
|
+
process.exit(1);
|
|
75954
|
+
}
|
|
75955
|
+
spinner.text = "Paying 1 AMIKO...";
|
|
75956
|
+
const transferRes = await fetch(`${billingBase2}/api/crossmint/wallets/${encodeURIComponent(solanaWallet)}/transfer`, {
|
|
75957
|
+
method: "POST",
|
|
75958
|
+
headers: {
|
|
75959
|
+
"Content-Type": "application/json",
|
|
75960
|
+
Authorization: `Bearer ${billingToken}`
|
|
75961
|
+
},
|
|
75962
|
+
body: JSON.stringify({
|
|
75963
|
+
to: TREASURY2,
|
|
75964
|
+
amount: "1",
|
|
75965
|
+
token: "AMIKO",
|
|
75966
|
+
chain: "solana"
|
|
75967
|
+
})
|
|
75968
|
+
});
|
|
75969
|
+
if (!transferRes.ok) {
|
|
75970
|
+
spinner.stop();
|
|
75971
|
+
const err = await transferRes.json().catch(() => ({ error: "Transfer failed" }));
|
|
75972
|
+
console.error(error(err.error || `Payment failed: ${transferRes.status}`));
|
|
75973
|
+
process.exit(1);
|
|
75974
|
+
}
|
|
75975
|
+
const transferData = await transferRes.json();
|
|
75976
|
+
const txHash = transferData.txHash;
|
|
75977
|
+
if (!txHash) {
|
|
75978
|
+
spinner.stop();
|
|
75979
|
+
console.error(error("Payment sent but no tx hash returned."));
|
|
75980
|
+
process.exit(1);
|
|
75981
|
+
}
|
|
75982
|
+
spinner.text = "Generating image...";
|
|
75983
|
+
const res = await fetch(`${mppBase2}/v1/ai/openai/images`, {
|
|
75984
|
+
method: "POST",
|
|
75985
|
+
headers: {
|
|
75986
|
+
"Content-Type": "application/json",
|
|
75987
|
+
"X-Payment-Tx": txHash
|
|
75988
|
+
},
|
|
75989
|
+
body: JSON.stringify({
|
|
75990
|
+
prompt: prompt2,
|
|
75991
|
+
size: opts.size,
|
|
75992
|
+
quality: opts.quality,
|
|
75993
|
+
model: opts.model
|
|
75994
|
+
})
|
|
75995
|
+
});
|
|
75996
|
+
spinner.stop();
|
|
75997
|
+
if (!res.ok) {
|
|
75998
|
+
const text = await res.text().catch(() => "");
|
|
75999
|
+
console.error(error(`Image generation failed: ${res.status} ${text.slice(0, 300)}`));
|
|
76000
|
+
console.log(dim(`Payment tx: https://solscan.io/tx/${txHash}`));
|
|
76001
|
+
process.exit(1);
|
|
76002
|
+
}
|
|
76003
|
+
const data = await res.json();
|
|
76004
|
+
if (opts.raw) {
|
|
76005
|
+
console.log(JSON.stringify(data, null, 2));
|
|
76006
|
+
return;
|
|
76007
|
+
}
|
|
76008
|
+
console.log(heading(`Image Generated
|
|
76009
|
+
`));
|
|
76010
|
+
console.log(label("Prompt", prompt2));
|
|
76011
|
+
console.log(label("Model", opts.model));
|
|
76012
|
+
console.log(label("Size", opts.size));
|
|
76013
|
+
console.log("");
|
|
76014
|
+
const images = data.images || data.data || [];
|
|
76015
|
+
for (const img of images) {
|
|
76016
|
+
const url2 = img.url || img.revised_prompt || "";
|
|
76017
|
+
if (url2)
|
|
76018
|
+
console.log(label("URL", url2));
|
|
76019
|
+
if (img.revised_prompt && img.revised_prompt !== prompt2) {
|
|
76020
|
+
console.log(label("Revised", dim(img.revised_prompt)));
|
|
76021
|
+
}
|
|
76022
|
+
}
|
|
76023
|
+
console.log("");
|
|
76024
|
+
console.log(success("Paid 1 AMIKO") + dim(` tx: ${txHash.slice(0, 16)}...`));
|
|
76025
|
+
} catch (err) {
|
|
76026
|
+
spinner.stop();
|
|
76027
|
+
console.error(error(err instanceof Error ? err.message : "Image generation failed"));
|
|
76028
|
+
process.exit(1);
|
|
76029
|
+
}
|
|
76030
|
+
});
|
|
76031
|
+
}
|
|
76032
|
+
|
|
76033
|
+
// src/commands/services.ts
|
|
76034
|
+
var TREASURY3 = "FPiZAf3jEnNfCwfvbv46jdPfHbmSepD4Q6iHiLJDQXvb";
|
|
76035
|
+
var AMIKO_MINT = "AY1Ww6MxwC3cCiyrandHqLrp4FXvzgcwQTZpJ2FEpump";
|
|
76036
|
+
var USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
76037
|
+
async function getAmikoPrice() {
|
|
76038
|
+
const res = await fetch(`https://lite-api.jup.ag/swap/v1/quote?inputMint=${AMIKO_MINT}&outputMint=${USDC_MINT}&amount=${1e6}&slippageBps=100`);
|
|
76039
|
+
if (!res.ok)
|
|
76040
|
+
return 0;
|
|
76041
|
+
const data = await res.json();
|
|
76042
|
+
return parseFloat(data.outAmount) / 1e6;
|
|
76043
|
+
}
|
|
76044
|
+
function usdToAmiko(usd2, pricePerAmiko) {
|
|
76045
|
+
if (pricePerAmiko <= 0)
|
|
76046
|
+
return "1";
|
|
76047
|
+
const amount2 = usd2 / pricePerAmiko;
|
|
76048
|
+
return Math.ceil(amount2 * 100) / 100 + "";
|
|
76049
|
+
}
|
|
76050
|
+
async function payAndCall(mppBase2, method, path, billingBase2, billingToken, solanaWallet, amountOrAuto, body, onProgress, token = "AMIKO") {
|
|
76051
|
+
let amount2 = amountOrAuto;
|
|
76052
|
+
if (amount2 === "auto") {
|
|
76053
|
+
onProgress?.("Fetching price...");
|
|
76054
|
+
try {
|
|
76055
|
+
const specRes = await fetch(`${mppBase2}/openapi.json`);
|
|
76056
|
+
if (specRes.ok) {
|
|
76057
|
+
const spec = await specRes.json();
|
|
76058
|
+
const pathSpec = spec.paths?.[path];
|
|
76059
|
+
const methodSpec = pathSpec?.[method.toLowerCase()];
|
|
76060
|
+
const usdPrice = parseFloat(methodSpec?.["x-payment-info"]?.price || "0");
|
|
76061
|
+
if (usdPrice > 0) {
|
|
76062
|
+
const amikoPrice = await getAmikoPrice();
|
|
76063
|
+
amount2 = usdToAmiko(usdPrice, amikoPrice);
|
|
76064
|
+
onProgress?.(`Price: $${usdPrice.toFixed(4)} = ${amount2} AMIKO`);
|
|
76065
|
+
} else {
|
|
76066
|
+
amount2 = "1";
|
|
76067
|
+
}
|
|
76068
|
+
} else {
|
|
76069
|
+
amount2 = "1";
|
|
76070
|
+
}
|
|
76071
|
+
} catch {
|
|
76072
|
+
amount2 = "1";
|
|
76073
|
+
}
|
|
76074
|
+
}
|
|
76075
|
+
onProgress?.(`Paying ${amount2} AMIKO...`);
|
|
75935
76076
|
const transferRes = await fetch(`${billingBase2}/api/crossmint/wallets/${encodeURIComponent(solanaWallet)}/transfer`, {
|
|
75936
76077
|
method: "POST",
|
|
75937
76078
|
headers: {
|
|
@@ -75939,9 +76080,9 @@ async function payAndCall(mppBase2, method, path, billingBase2, billingToken, so
|
|
|
75939
76080
|
Authorization: `Bearer ${billingToken}`
|
|
75940
76081
|
},
|
|
75941
76082
|
body: JSON.stringify({
|
|
75942
|
-
to:
|
|
75943
|
-
amount:
|
|
75944
|
-
token
|
|
76083
|
+
to: TREASURY3,
|
|
76084
|
+
amount: amount2,
|
|
76085
|
+
token,
|
|
75945
76086
|
chain: "solana"
|
|
75946
76087
|
})
|
|
75947
76088
|
});
|
|
@@ -75963,7 +76104,7 @@ async function payAndCall(mppBase2, method, path, billingBase2, billingToken, so
|
|
|
75963
76104
|
}
|
|
75964
76105
|
const url2 = path.startsWith("http") ? path : `${mppBase2}${path}`;
|
|
75965
76106
|
const res = await fetch(url2, fetchOpts);
|
|
75966
|
-
return { res, txHash };
|
|
76107
|
+
return { res, txHash, amikoSpent: amount2 };
|
|
75967
76108
|
}
|
|
75968
76109
|
function registerServicesCommand(program2) {
|
|
75969
76110
|
const svc = program2.command("service").alias("svc").description("Call any MPP service — pays with AMIKO tokens");
|
|
@@ -76018,7 +76159,7 @@ function registerServicesCommand(program2) {
|
|
|
76018
76159
|
opts
|
|
76019
76160
|
});
|
|
76020
76161
|
});
|
|
76021
|
-
svc.command("call <method> <path> [body]").description("Call any MPP endpoint —
|
|
76162
|
+
svc.command("call <method> <path> [body]").description("Call any MPP endpoint — pays in AMIKO or USDC on Solana").option("--amiko <amount>", "AMIKO tokens to pay (default: auto-price from USD)").option("--usdc <amount>", "Pay in USDC instead of AMIKO").option("--raw", "Output raw response").action(async (method, path, bodyStr, opts) => {
|
|
76022
76163
|
let body;
|
|
76023
76164
|
if (bodyStr) {
|
|
76024
76165
|
try {
|
|
@@ -76032,7 +76173,8 @@ function registerServicesCommand(program2) {
|
|
|
76032
76173
|
method: method.toUpperCase(),
|
|
76033
76174
|
path,
|
|
76034
76175
|
body,
|
|
76035
|
-
amiko: opts.amiko || "
|
|
76176
|
+
amiko: opts.amiko || (opts.usdc ? undefined : "auto"),
|
|
76177
|
+
usdc: opts.usdc,
|
|
76036
76178
|
opts
|
|
76037
76179
|
});
|
|
76038
76180
|
});
|
|
@@ -76079,11 +76221,15 @@ async function callService(params) {
|
|
|
76079
76221
|
const solanaWallet = allWallets.find((w5) => w5.chain === "solana")?.address;
|
|
76080
76222
|
if (!solanaWallet) {
|
|
76081
76223
|
spinner.stop();
|
|
76082
|
-
console.error(error("No Solana wallet
|
|
76224
|
+
console.error(error("No Solana wallet."));
|
|
76083
76225
|
process.exit(1);
|
|
76084
76226
|
}
|
|
76085
|
-
|
|
76086
|
-
const
|
|
76227
|
+
const token = params.usdc ? "USDC" : "AMIKO";
|
|
76228
|
+
const amount2 = params.usdc || params.amiko || "auto";
|
|
76229
|
+
const { res, txHash, amikoSpent } = await payAndCall(mppBase2, params.method, params.path, billingBase2, billingToken, solanaWallet, token === "USDC" ? amount2 : amount2, params.body, (msg) => {
|
|
76230
|
+
spinner.text = msg;
|
|
76231
|
+
});
|
|
76232
|
+
if (params.usdc) {}
|
|
76087
76233
|
spinner.stop();
|
|
76088
76234
|
if (!res.ok) {
|
|
76089
76235
|
const text = await res.text().catch(() => "");
|
|
@@ -76100,7 +76246,7 @@ async function callService(params) {
|
|
|
76100
76246
|
console.log(JSON.stringify(data, null, 2));
|
|
76101
76247
|
}
|
|
76102
76248
|
console.log("");
|
|
76103
|
-
console.log(success(`Paid ${
|
|
76249
|
+
console.log(success(`Paid ${amikoSpent} ${token}`) + dim(` tx: ${txHash.slice(0, 16)}...`));
|
|
76104
76250
|
} catch (err) {
|
|
76105
76251
|
spinner.stop();
|
|
76106
76252
|
console.error(error(err instanceof Error ? err.message : "Service call failed"));
|
|
@@ -76119,6 +76265,7 @@ program2.name("amiko").description("Amiko CLI — swap tokens, manage credits, b
|
|
|
76119
76265
|
registerConnectCommand(program2);
|
|
76120
76266
|
registerCreditsCommand(program2);
|
|
76121
76267
|
registerSearchCommand(program2);
|
|
76268
|
+
registerImageCommand(program2);
|
|
76122
76269
|
registerSwapCommand(program2);
|
|
76123
76270
|
registerBridgeCommand(program2);
|
|
76124
76271
|
registerBrowseCommand(program2);
|