@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.
Files changed (2) hide show
  1. package/dist/index.js +159 -12
  2. 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/services.ts
75932
+ // src/commands/image.ts
75933
75933
  var TREASURY2 = "FPiZAf3jEnNfCwfvbv46jdPfHbmSepD4Q6iHiLJDQXvb";
75934
- async function payAndCall(mppBase2, method, path, billingBase2, billingToken, solanaWallet, amikoAmount, body) {
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: TREASURY2,
75943
- amount: amikoAmount,
75944
- token: "AMIKO",
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 — 1 AMIKO").option("--amiko <amount>", "AMIKO tokens to pay", "1").option("--raw", "Output raw response").action(async (method, path, bodyStr, opts) => {
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 || "1",
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 for AMIKO payment."));
76224
+ console.error(error("No Solana wallet."));
76083
76225
  process.exit(1);
76084
76226
  }
76085
- spinner.text = `Paying ${params.amiko} AMIKO...`;
76086
- const { res, txHash } = await payAndCall(mppBase2, params.method, params.path, billingBase2, billingToken, solanaWallet, params.amiko, params.body);
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 ${params.amiko} AMIKO`) + dim(` tx: ${txHash.slice(0, 16)}...`));
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyamiko/amiko-cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Amiko CLI — swap tokens, manage credits, bridge cross-chain, and call marketplace agents",
5
5
  "type": "module",
6
6
  "bin": {