agentmall 0.1.5 → 0.1.7

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/cli.js +80 -15
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -596,11 +596,22 @@ async function getBuyerToken(purchaseId) {
596
596
 
597
597
  // src/cli/index.ts
598
598
  var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
599
- async function runCommandCapture(command2, args2) {
599
+ function parseTempoBalance(balance) {
600
+ const parsed = Number.parseFloat(balance ?? "0");
601
+ return Number.isFinite(parsed) ? parsed : 0;
602
+ }
603
+ function formatUsdcNumber(amount) {
604
+ return amount.toFixed(6).replace(/\.?0+$/, "");
605
+ }
606
+ async function runCommandCapture(command2, args2, envOverrides) {
600
607
  return await new Promise((resolve, reject) => {
601
608
  const child = spawn(command2, args2, {
602
609
  stdio: ["ignore", "pipe", "pipe"],
603
- shell: process.platform === "win32"
610
+ shell: process.platform === "win32",
611
+ env: {
612
+ ...process.env,
613
+ ...envOverrides
614
+ }
604
615
  });
605
616
  let stdout = "";
606
617
  let stderr = "";
@@ -668,21 +679,66 @@ async function ensureTempoReady() {
668
679
  function formatUsdAmount(cents) {
669
680
  return (cents / 100).toFixed(2);
670
681
  }
682
+ async function ensureSufficientBalance(requiredCents, wallet) {
683
+ const required = Number.parseFloat(formatUsdAmount(requiredCents));
684
+ let available = parseTempoBalance(wallet.balance?.available);
685
+ if (available >= required) {
686
+ return wallet;
687
+ }
688
+ console.log();
689
+ console.log(
690
+ ` Tempo wallet balance is too low for this order: have ${formatUsdcNumber(available)} USDC, need ${formatUsdAmount(requiredCents)} USDC.`
691
+ );
692
+ console.log(` Shortfall: ${formatUsdcNumber(required - available)} USDC`);
693
+ const fundNow = await promptConfirm("Open Tempo funding flow now?");
694
+ if (!fundNow) {
695
+ throw new Error(
696
+ `Insufficient USDC balance: have ${formatUsdcNumber(available)}, need ${formatUsdAmount(requiredCents)}.`
697
+ );
698
+ }
699
+ const fundCode = await runInteractiveCommand("tempo", ["wallet", "fund"]);
700
+ if (fundCode !== 0) {
701
+ throw new Error("Tempo wallet funding was cancelled.");
702
+ }
703
+ const refreshed = await ensureTempoReady();
704
+ available = parseTempoBalance(refreshed.balance?.available);
705
+ if (available < required) {
706
+ throw new Error(
707
+ `Still not enough USDC after funding: have ${formatUsdcNumber(available)}, need ${formatUsdAmount(requiredCents)}.`
708
+ );
709
+ }
710
+ console.log(
711
+ ` Funding complete. New balance: ${formatUsdcNumber(available)} ${refreshed.balance?.symbol ?? "USDC"}`
712
+ );
713
+ return refreshed;
714
+ }
671
715
  async function createPurchaseWithTempo(body) {
672
716
  const totalChargeCents = body.max_budget + SERVICE_FEE_CENTS;
673
- const result = await runCommandCapture("tempo", [
674
- "request",
675
- "-s",
676
- "--max-spend",
677
- formatUsdAmount(totalChargeCents),
678
- "-X",
679
- "POST",
680
- "--json",
681
- JSON.stringify(body),
682
- `${BASE_URL}/api/purchases`
683
- ]);
717
+ const result = await runCommandCapture(
718
+ "tempo",
719
+ [
720
+ "request",
721
+ "-s",
722
+ "-X",
723
+ "POST",
724
+ "--json",
725
+ JSON.stringify(body),
726
+ `${BASE_URL}/api/purchases`
727
+ ],
728
+ {
729
+ TEMPO_MAX_SPEND: formatUsdAmount(totalChargeCents)
730
+ }
731
+ );
684
732
  if (result.code !== 0) {
685
- const message = result.stderr.trim() || result.stdout.trim() || "Tempo request failed";
733
+ const raw = result.stderr.trim() || result.stdout.trim();
734
+ const payload = raw ? (() => {
735
+ try {
736
+ return JSON.parse(raw);
737
+ } catch {
738
+ return null;
739
+ }
740
+ })() : null;
741
+ const message = (payload?.message ?? raw) || "Tempo request failed";
686
742
  throw new Error(message);
687
743
  }
688
744
  try {
@@ -732,7 +788,11 @@ async function buy(urlArg) {
732
788
  console.log(" Cancelled.");
733
789
  return;
734
790
  }
735
- const wallet = await ensureTempoReady();
791
+ const totalChargeCents = maxBudget + SERVICE_FEE_CENTS;
792
+ const wallet = await ensureSufficientBalance(
793
+ totalChargeCents,
794
+ await ensureTempoReady()
795
+ );
736
796
  if (wallet.wallet) {
737
797
  const balance = wallet.balance?.available ? `, balance ${wallet.balance.available} ${wallet.balance?.symbol ?? "USDC"}` : "";
738
798
  console.log(` Paying with Tempo wallet ${wallet.wallet}${balance}`);
@@ -765,6 +825,11 @@ async function buy(urlArg) {
765
825
  process.exitCode = 1;
766
826
  return;
767
827
  }
828
+ if (error instanceof Error) {
829
+ console.error(` \x1B[31mError:\x1B[0m ${error.message}`);
830
+ process.exitCode = 1;
831
+ return;
832
+ }
768
833
  throw error;
769
834
  }
770
835
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentmall",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "SDK and CLI for the AgentMall API — let AI agents buy physical products from US retailers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",