@mixrpay/agent-sdk 0.6.0 → 0.6.1

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 CHANGED
@@ -41,9 +41,13 @@ await wallet.fetch(url, options);
41
41
  // Get wallet balance
42
42
  const balance = await wallet.getBalance();
43
43
 
44
- // Track payments
45
- const payments = wallet.getPaymentHistory();
46
- const total = wallet.getTotalSpent();
44
+ // Pre-flight balance check
45
+ const check = await wallet.canAfford(0.50);
46
+ if (check.canAfford) { /* proceed */ }
47
+
48
+ // Run diagnostics
49
+ const diag = await wallet.runDiagnostics();
50
+ console.log(diag.recommendations);
47
51
  ```
48
52
 
49
53
  ## Configuration
@@ -63,6 +67,7 @@ import {
63
67
  AgentWallet,
64
68
  InsufficientBalanceError,
65
69
  SessionLimitExceededError,
70
+ MixrPayError,
66
71
  } from '@mixrpay/agent-sdk';
67
72
 
68
73
  try {
@@ -71,12 +76,27 @@ try {
71
76
  if (error instanceof InsufficientBalanceError) {
72
77
  console.log(`Need $${error.required}, have $${error.available}`);
73
78
  }
79
+
80
+ // Check if error is retryable
81
+ if (error instanceof MixrPayError && error.isRetryable()) {
82
+ const delay = error.retryAfterMs || 1000;
83
+ await sleep(delay);
84
+ return retry();
85
+ }
74
86
  }
75
87
  ```
76
88
 
89
+ ## What's New in v0.6.0
90
+
91
+ - `canAfford(amountUsd)` - Pre-flight balance check
92
+ - `isRetryable()` on all errors - Determine if operation should be retried
93
+ - `retryAfterMs` on errors - Suggested retry delay
94
+ - Enhanced `runDiagnostics()` - Session limits, latency, recommendations
95
+ - `requestId` and `correlationId` in payment events
96
+
77
97
  ## Documentation
78
98
 
79
- [mixrpay.com/build](https://www.mixrpay.com/build)
99
+ [mixrpay.com/docs](https://www.mixrpay.com/docs)
80
100
 
81
101
  ## License
82
102
 
package/dist/index.cjs CHANGED
@@ -507,7 +507,7 @@ function getAmountUsd(requirements) {
507
507
  }
508
508
 
509
509
  // src/agent-wallet.ts
510
- var SDK_VERSION = "0.6.0";
510
+ var SDK_VERSION = "0.6.1";
511
511
  var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
512
512
  var DEFAULT_TIMEOUT = 3e4;
513
513
  var NETWORKS = {
@@ -699,7 +699,19 @@ var AgentWallet = class {
699
699
  });
700
700
  if (!registerResponse.ok) {
701
701
  const error = await registerResponse.json().catch(() => ({}));
702
- throw new MixrPayError(error.error || `Registration failed: ${registerResponse.status}`);
702
+ const errorMessage = error.error || `Registration failed with status ${registerResponse.status}`;
703
+ const requestId = error.request_id;
704
+ const errorCode = error.code;
705
+ let helpText = "";
706
+ if (registerResponse.status === 503) {
707
+ helpText = " The service may be temporarily unavailable. Please try again later.";
708
+ } else if (registerResponse.status === 500) {
709
+ helpText = " This is a server error. Please contact support with the request ID.";
710
+ } else if (errorCode === "MISSING_CHALLENGE" || errorCode === "MISSING_SIGNATURE") {
711
+ helpText = " This may indicate an SDK bug. Please update to the latest version.";
712
+ }
713
+ const fullMessage = requestId ? `${errorMessage} (request_id: ${requestId})${helpText}` : `${errorMessage}${helpText}`;
714
+ throw new MixrPayError(fullMessage);
703
715
  }
704
716
  const data = await registerResponse.json();
705
717
  return {
@@ -707,6 +719,52 @@ var AgentWallet = class {
707
719
  depositAddress: data.deposit_address
708
720
  };
709
721
  }
722
+ /**
723
+ * Check if the MixrPay server is properly configured for agent registration.
724
+ *
725
+ * Use this to diagnose registration issues before attempting to register.
726
+ *
727
+ * @param baseUrl - MixrPay API base URL (default: https://www.mixrpay.com)
728
+ * @returns Server health status including agent registration availability
729
+ *
730
+ * @example
731
+ * ```typescript
732
+ * const status = await AgentWallet.checkServerHealth();
733
+ * if (!status.agentRegistrationAvailable) {
734
+ * console.error('Agent registration is not available:', status);
735
+ * }
736
+ * ```
737
+ */
738
+ static async checkServerHealth(baseUrl) {
739
+ const url = (baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
740
+ try {
741
+ const response = await fetch(`${url}/api/health/ready?details=true`);
742
+ if (!response.ok) {
743
+ return {
744
+ healthy: false,
745
+ database: "unknown",
746
+ agentRegistrationAvailable: false,
747
+ privyConfigured: false,
748
+ error: `Health check failed with status ${response.status}`
749
+ };
750
+ }
751
+ const data = await response.json();
752
+ return {
753
+ healthy: data.status === "ready",
754
+ database: data.database || "unknown",
755
+ agentRegistrationAvailable: data.services?.agentRegistration?.available ?? false,
756
+ privyConfigured: data.services?.privy?.configured ?? false
757
+ };
758
+ } catch (error) {
759
+ return {
760
+ healthy: false,
761
+ database: "unreachable",
762
+ agentRegistrationAvailable: false,
763
+ privyConfigured: false,
764
+ error: error instanceof Error ? error.message : "Failed to reach server"
765
+ };
766
+ }
767
+ }
710
768
  /**
711
769
  * Get a session key for an already-registered agent.
712
770
  *
@@ -881,6 +939,67 @@ var AgentWallet = class {
881
939
  }
882
940
  return true;
883
941
  }
942
+ /**
943
+ * Withdraw USDC from agent's MixrPay wallet to their external wallet.
944
+ *
945
+ * SECURITY: Withdrawals can ONLY go to the agent's own registration wallet
946
+ * (the wallet used during `register()`). This prevents prompt injection
947
+ * attacks where a compromised agent might be tricked into withdrawing
948
+ * to an attacker's address.
949
+ *
950
+ * @param options - Withdrawal options
951
+ * @returns Withdrawal result with transaction hash
952
+ * @throws {MixrPayError} If withdrawal fails
953
+ *
954
+ * @example
955
+ * ```typescript
956
+ * const result = await AgentWallet.withdraw({
957
+ * privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
958
+ * amountUsd: 50.00,
959
+ * });
960
+ *
961
+ * console.log(`Withdrew $${result.amountUsd}`);
962
+ * console.log(`Transaction: ${result.txHash}`);
963
+ * console.log(`Remaining balance: $${result.remainingBalanceUsd}`);
964
+ * ```
965
+ */
966
+ static async withdraw(options) {
967
+ const { privateKey, amountUsd } = options;
968
+ const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
969
+ const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
970
+ const walletAddress = account.address;
971
+ const challengeResponse = await fetch(
972
+ `${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=withdraw`
973
+ );
974
+ if (!challengeResponse.ok) {
975
+ const error = await challengeResponse.json().catch(() => ({}));
976
+ throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
977
+ }
978
+ const { challenge, message } = await challengeResponse.json();
979
+ const signature = await (0, import_accounts2.signMessage)({ message, privateKey });
980
+ const withdrawResponse = await fetch(`${baseUrl}/api/v1/agent/withdraw`, {
981
+ method: "POST",
982
+ headers: { "Content-Type": "application/json" },
983
+ body: JSON.stringify({
984
+ challenge,
985
+ external_wallet: walletAddress,
986
+ signature,
987
+ to_address: walletAddress,
988
+ // Always withdraw to self
989
+ amount_usd: amountUsd
990
+ })
991
+ });
992
+ if (!withdrawResponse.ok) {
993
+ const error = await withdrawResponse.json().catch(() => ({}));
994
+ throw new MixrPayError(error.error || `Withdrawal failed: ${withdrawResponse.status}`);
995
+ }
996
+ const data = await withdrawResponse.json();
997
+ return {
998
+ txHash: data.tx_hash,
999
+ amountUsd: data.amount_usd,
1000
+ remainingBalanceUsd: data.remaining_balance_usd
1001
+ };
1002
+ }
884
1003
  // ===========================================================================
885
1004
  // Core Methods
886
1005
  // ===========================================================================
package/dist/index.d.cts CHANGED
@@ -378,7 +378,7 @@ interface SessionStats {
378
378
  */
379
379
 
380
380
  /** Current SDK version */
381
- declare const SDK_VERSION = "0.6.0";
381
+ declare const SDK_VERSION = "0.6.1";
382
382
  /** Supported networks */
383
383
  declare const NETWORKS: {
384
384
  readonly BASE_MAINNET: {
@@ -487,6 +487,28 @@ interface AgentRevokeSessionKeyOptions {
487
487
  /** MixrPay API base URL (default: https://www.mixrpay.com) */
488
488
  baseUrl?: string;
489
489
  }
490
+ /**
491
+ * Options for withdrawing funds
492
+ */
493
+ interface AgentWithdrawOptions {
494
+ /** The agent's external wallet private key (used for signing, NOT transmitted) */
495
+ privateKey: `0x${string}`;
496
+ /** Amount to withdraw in USD */
497
+ amountUsd: number;
498
+ /** MixrPay API base URL (default: https://www.mixrpay.com) */
499
+ baseUrl?: string;
500
+ }
501
+ /**
502
+ * Result from withdrawal
503
+ */
504
+ interface AgentWithdrawResult {
505
+ /** On-chain transaction hash */
506
+ txHash: string;
507
+ /** Amount withdrawn in USD */
508
+ amountUsd: number;
509
+ /** Remaining balance after withdrawal */
510
+ remainingBalanceUsd: number;
511
+ }
490
512
  type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
491
513
  /**
492
514
  * A wallet wrapper for AI agents that handles x402 payments automatically.
@@ -589,6 +611,29 @@ declare class AgentWallet {
589
611
  * ```
590
612
  */
591
613
  static register(options: AgentRegisterOptions): Promise<AgentRegisterResult>;
614
+ /**
615
+ * Check if the MixrPay server is properly configured for agent registration.
616
+ *
617
+ * Use this to diagnose registration issues before attempting to register.
618
+ *
619
+ * @param baseUrl - MixrPay API base URL (default: https://www.mixrpay.com)
620
+ * @returns Server health status including agent registration availability
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * const status = await AgentWallet.checkServerHealth();
625
+ * if (!status.agentRegistrationAvailable) {
626
+ * console.error('Agent registration is not available:', status);
627
+ * }
628
+ * ```
629
+ */
630
+ static checkServerHealth(baseUrl?: string): Promise<{
631
+ healthy: boolean;
632
+ database: string;
633
+ agentRegistrationAvailable: boolean;
634
+ privyConfigured: boolean;
635
+ error?: string;
636
+ }>;
592
637
  /**
593
638
  * Get a session key for an already-registered agent.
594
639
  *
@@ -657,6 +702,31 @@ declare class AgentWallet {
657
702
  * ```
658
703
  */
659
704
  static revokeSessionKey(options: AgentRevokeSessionKeyOptions): Promise<boolean>;
705
+ /**
706
+ * Withdraw USDC from agent's MixrPay wallet to their external wallet.
707
+ *
708
+ * SECURITY: Withdrawals can ONLY go to the agent's own registration wallet
709
+ * (the wallet used during `register()`). This prevents prompt injection
710
+ * attacks where a compromised agent might be tricked into withdrawing
711
+ * to an attacker's address.
712
+ *
713
+ * @param options - Withdrawal options
714
+ * @returns Withdrawal result with transaction hash
715
+ * @throws {MixrPayError} If withdrawal fails
716
+ *
717
+ * @example
718
+ * ```typescript
719
+ * const result = await AgentWallet.withdraw({
720
+ * privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
721
+ * amountUsd: 50.00,
722
+ * });
723
+ *
724
+ * console.log(`Withdrew $${result.amountUsd}`);
725
+ * console.log(`Transaction: ${result.txHash}`);
726
+ * console.log(`Remaining balance: $${result.remainingBalanceUsd}`);
727
+ * ```
728
+ */
729
+ static withdraw(options: AgentWithdrawOptions): Promise<AgentWithdrawResult>;
660
730
  /**
661
731
  * Make an HTTP request, automatically handling x402 payment if required.
662
732
  *
package/dist/index.d.ts CHANGED
@@ -378,7 +378,7 @@ interface SessionStats {
378
378
  */
379
379
 
380
380
  /** Current SDK version */
381
- declare const SDK_VERSION = "0.6.0";
381
+ declare const SDK_VERSION = "0.6.1";
382
382
  /** Supported networks */
383
383
  declare const NETWORKS: {
384
384
  readonly BASE_MAINNET: {
@@ -487,6 +487,28 @@ interface AgentRevokeSessionKeyOptions {
487
487
  /** MixrPay API base URL (default: https://www.mixrpay.com) */
488
488
  baseUrl?: string;
489
489
  }
490
+ /**
491
+ * Options for withdrawing funds
492
+ */
493
+ interface AgentWithdrawOptions {
494
+ /** The agent's external wallet private key (used for signing, NOT transmitted) */
495
+ privateKey: `0x${string}`;
496
+ /** Amount to withdraw in USD */
497
+ amountUsd: number;
498
+ /** MixrPay API base URL (default: https://www.mixrpay.com) */
499
+ baseUrl?: string;
500
+ }
501
+ /**
502
+ * Result from withdrawal
503
+ */
504
+ interface AgentWithdrawResult {
505
+ /** On-chain transaction hash */
506
+ txHash: string;
507
+ /** Amount withdrawn in USD */
508
+ amountUsd: number;
509
+ /** Remaining balance after withdrawal */
510
+ remainingBalanceUsd: number;
511
+ }
490
512
  type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
491
513
  /**
492
514
  * A wallet wrapper for AI agents that handles x402 payments automatically.
@@ -589,6 +611,29 @@ declare class AgentWallet {
589
611
  * ```
590
612
  */
591
613
  static register(options: AgentRegisterOptions): Promise<AgentRegisterResult>;
614
+ /**
615
+ * Check if the MixrPay server is properly configured for agent registration.
616
+ *
617
+ * Use this to diagnose registration issues before attempting to register.
618
+ *
619
+ * @param baseUrl - MixrPay API base URL (default: https://www.mixrpay.com)
620
+ * @returns Server health status including agent registration availability
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * const status = await AgentWallet.checkServerHealth();
625
+ * if (!status.agentRegistrationAvailable) {
626
+ * console.error('Agent registration is not available:', status);
627
+ * }
628
+ * ```
629
+ */
630
+ static checkServerHealth(baseUrl?: string): Promise<{
631
+ healthy: boolean;
632
+ database: string;
633
+ agentRegistrationAvailable: boolean;
634
+ privyConfigured: boolean;
635
+ error?: string;
636
+ }>;
592
637
  /**
593
638
  * Get a session key for an already-registered agent.
594
639
  *
@@ -657,6 +702,31 @@ declare class AgentWallet {
657
702
  * ```
658
703
  */
659
704
  static revokeSessionKey(options: AgentRevokeSessionKeyOptions): Promise<boolean>;
705
+ /**
706
+ * Withdraw USDC from agent's MixrPay wallet to their external wallet.
707
+ *
708
+ * SECURITY: Withdrawals can ONLY go to the agent's own registration wallet
709
+ * (the wallet used during `register()`). This prevents prompt injection
710
+ * attacks where a compromised agent might be tricked into withdrawing
711
+ * to an attacker's address.
712
+ *
713
+ * @param options - Withdrawal options
714
+ * @returns Withdrawal result with transaction hash
715
+ * @throws {MixrPayError} If withdrawal fails
716
+ *
717
+ * @example
718
+ * ```typescript
719
+ * const result = await AgentWallet.withdraw({
720
+ * privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
721
+ * amountUsd: 50.00,
722
+ * });
723
+ *
724
+ * console.log(`Withdrew $${result.amountUsd}`);
725
+ * console.log(`Transaction: ${result.txHash}`);
726
+ * console.log(`Remaining balance: $${result.remainingBalanceUsd}`);
727
+ * ```
728
+ */
729
+ static withdraw(options: AgentWithdrawOptions): Promise<AgentWithdrawResult>;
660
730
  /**
661
731
  * Make an HTTP request, automatically handling x402 payment if required.
662
732
  *
package/dist/index.js CHANGED
@@ -471,7 +471,7 @@ function getAmountUsd(requirements) {
471
471
  }
472
472
 
473
473
  // src/agent-wallet.ts
474
- var SDK_VERSION = "0.6.0";
474
+ var SDK_VERSION = "0.6.1";
475
475
  var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
476
476
  var DEFAULT_TIMEOUT = 3e4;
477
477
  var NETWORKS = {
@@ -663,7 +663,19 @@ var AgentWallet = class {
663
663
  });
664
664
  if (!registerResponse.ok) {
665
665
  const error = await registerResponse.json().catch(() => ({}));
666
- throw new MixrPayError(error.error || `Registration failed: ${registerResponse.status}`);
666
+ const errorMessage = error.error || `Registration failed with status ${registerResponse.status}`;
667
+ const requestId = error.request_id;
668
+ const errorCode = error.code;
669
+ let helpText = "";
670
+ if (registerResponse.status === 503) {
671
+ helpText = " The service may be temporarily unavailable. Please try again later.";
672
+ } else if (registerResponse.status === 500) {
673
+ helpText = " This is a server error. Please contact support with the request ID.";
674
+ } else if (errorCode === "MISSING_CHALLENGE" || errorCode === "MISSING_SIGNATURE") {
675
+ helpText = " This may indicate an SDK bug. Please update to the latest version.";
676
+ }
677
+ const fullMessage = requestId ? `${errorMessage} (request_id: ${requestId})${helpText}` : `${errorMessage}${helpText}`;
678
+ throw new MixrPayError(fullMessage);
667
679
  }
668
680
  const data = await registerResponse.json();
669
681
  return {
@@ -671,6 +683,52 @@ var AgentWallet = class {
671
683
  depositAddress: data.deposit_address
672
684
  };
673
685
  }
686
+ /**
687
+ * Check if the MixrPay server is properly configured for agent registration.
688
+ *
689
+ * Use this to diagnose registration issues before attempting to register.
690
+ *
691
+ * @param baseUrl - MixrPay API base URL (default: https://www.mixrpay.com)
692
+ * @returns Server health status including agent registration availability
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * const status = await AgentWallet.checkServerHealth();
697
+ * if (!status.agentRegistrationAvailable) {
698
+ * console.error('Agent registration is not available:', status);
699
+ * }
700
+ * ```
701
+ */
702
+ static async checkServerHealth(baseUrl) {
703
+ const url = (baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
704
+ try {
705
+ const response = await fetch(`${url}/api/health/ready?details=true`);
706
+ if (!response.ok) {
707
+ return {
708
+ healthy: false,
709
+ database: "unknown",
710
+ agentRegistrationAvailable: false,
711
+ privyConfigured: false,
712
+ error: `Health check failed with status ${response.status}`
713
+ };
714
+ }
715
+ const data = await response.json();
716
+ return {
717
+ healthy: data.status === "ready",
718
+ database: data.database || "unknown",
719
+ agentRegistrationAvailable: data.services?.agentRegistration?.available ?? false,
720
+ privyConfigured: data.services?.privy?.configured ?? false
721
+ };
722
+ } catch (error) {
723
+ return {
724
+ healthy: false,
725
+ database: "unreachable",
726
+ agentRegistrationAvailable: false,
727
+ privyConfigured: false,
728
+ error: error instanceof Error ? error.message : "Failed to reach server"
729
+ };
730
+ }
731
+ }
674
732
  /**
675
733
  * Get a session key for an already-registered agent.
676
734
  *
@@ -845,6 +903,67 @@ var AgentWallet = class {
845
903
  }
846
904
  return true;
847
905
  }
906
+ /**
907
+ * Withdraw USDC from agent's MixrPay wallet to their external wallet.
908
+ *
909
+ * SECURITY: Withdrawals can ONLY go to the agent's own registration wallet
910
+ * (the wallet used during `register()`). This prevents prompt injection
911
+ * attacks where a compromised agent might be tricked into withdrawing
912
+ * to an attacker's address.
913
+ *
914
+ * @param options - Withdrawal options
915
+ * @returns Withdrawal result with transaction hash
916
+ * @throws {MixrPayError} If withdrawal fails
917
+ *
918
+ * @example
919
+ * ```typescript
920
+ * const result = await AgentWallet.withdraw({
921
+ * privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
922
+ * amountUsd: 50.00,
923
+ * });
924
+ *
925
+ * console.log(`Withdrew $${result.amountUsd}`);
926
+ * console.log(`Transaction: ${result.txHash}`);
927
+ * console.log(`Remaining balance: $${result.remainingBalanceUsd}`);
928
+ * ```
929
+ */
930
+ static async withdraw(options) {
931
+ const { privateKey, amountUsd } = options;
932
+ const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
933
+ const account = privateKeyToAccount2(privateKey);
934
+ const walletAddress = account.address;
935
+ const challengeResponse = await fetch(
936
+ `${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=withdraw`
937
+ );
938
+ if (!challengeResponse.ok) {
939
+ const error = await challengeResponse.json().catch(() => ({}));
940
+ throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
941
+ }
942
+ const { challenge, message } = await challengeResponse.json();
943
+ const signature = await signMessage({ message, privateKey });
944
+ const withdrawResponse = await fetch(`${baseUrl}/api/v1/agent/withdraw`, {
945
+ method: "POST",
946
+ headers: { "Content-Type": "application/json" },
947
+ body: JSON.stringify({
948
+ challenge,
949
+ external_wallet: walletAddress,
950
+ signature,
951
+ to_address: walletAddress,
952
+ // Always withdraw to self
953
+ amount_usd: amountUsd
954
+ })
955
+ });
956
+ if (!withdrawResponse.ok) {
957
+ const error = await withdrawResponse.json().catch(() => ({}));
958
+ throw new MixrPayError(error.error || `Withdrawal failed: ${withdrawResponse.status}`);
959
+ }
960
+ const data = await withdrawResponse.json();
961
+ return {
962
+ txHash: data.tx_hash,
963
+ amountUsd: data.amount_usd,
964
+ remainingBalanceUsd: data.remaining_balance_usd
965
+ };
966
+ }
848
967
  // ===========================================================================
849
968
  // Core Methods
850
969
  // ===========================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mixrpay/agent-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "MixrPay Agent SDK - Enable AI agents to make x402 payments with session keys",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",