@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 +24 -4
- package/dist/index.cjs +121 -2
- package/dist/index.d.cts +71 -1
- package/dist/index.d.ts +71 -1
- package/dist/index.js +121 -2
- package/package.json +1 -1
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
|
-
//
|
|
45
|
-
const
|
|
46
|
-
|
|
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/
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
// ===========================================================================
|