@mixrpay/agent-sdk 0.4.1 → 0.5.0
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.cjs +235 -1
- package/dist/index.d.cts +185 -1
- package/dist/index.d.ts +185 -1
- package/dist/index.js +235 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -353,6 +353,9 @@ async function createSessionAuthPayload(sessionKey) {
|
|
|
353
353
|
};
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
+
// src/agent-wallet.ts
|
|
357
|
+
var import_accounts2 = require("viem/accounts");
|
|
358
|
+
|
|
356
359
|
// src/x402.ts
|
|
357
360
|
async function parse402Response(response) {
|
|
358
361
|
let paymentData = null;
|
|
@@ -442,7 +445,7 @@ function getAmountUsd(requirements) {
|
|
|
442
445
|
}
|
|
443
446
|
|
|
444
447
|
// src/agent-wallet.ts
|
|
445
|
-
var SDK_VERSION = "0.
|
|
448
|
+
var SDK_VERSION = "0.5.0";
|
|
446
449
|
var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
|
|
447
450
|
var DEFAULT_TIMEOUT = 3e4;
|
|
448
451
|
var NETWORKS = {
|
|
@@ -586,6 +589,237 @@ var AgentWallet = class {
|
|
|
586
589
|
}
|
|
587
590
|
}
|
|
588
591
|
// ===========================================================================
|
|
592
|
+
// Static Agent Registration Methods
|
|
593
|
+
// ===========================================================================
|
|
594
|
+
/**
|
|
595
|
+
* Register a new agent with MixrPay.
|
|
596
|
+
*
|
|
597
|
+
* This creates a Privy-managed embedded wallet for the agent's payments.
|
|
598
|
+
* The agent proves ownership of their external wallet by signing a challenge.
|
|
599
|
+
*
|
|
600
|
+
* @param options - Registration options including the private key
|
|
601
|
+
* @returns Registration result with deposit address
|
|
602
|
+
* @throws {MixrPayError} If registration fails
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```typescript
|
|
606
|
+
* const { depositAddress, userId } = await AgentWallet.register({
|
|
607
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
608
|
+
* name: 'My Trading Agent',
|
|
609
|
+
* });
|
|
610
|
+
*
|
|
611
|
+
* console.log(`Fund your agent at: ${depositAddress}`);
|
|
612
|
+
* ```
|
|
613
|
+
*/
|
|
614
|
+
static async register(options) {
|
|
615
|
+
const { privateKey, name } = options;
|
|
616
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
617
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
618
|
+
const walletAddress = account.address;
|
|
619
|
+
const challengeResponse = await fetch(
|
|
620
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=register`
|
|
621
|
+
);
|
|
622
|
+
if (!challengeResponse.ok) {
|
|
623
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
624
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
625
|
+
}
|
|
626
|
+
const { challenge, message } = await challengeResponse.json();
|
|
627
|
+
const signature = await (0, import_accounts2.signMessage)({ message, privateKey });
|
|
628
|
+
const registerResponse = await fetch(`${baseUrl}/api/v1/agent/register`, {
|
|
629
|
+
method: "POST",
|
|
630
|
+
headers: { "Content-Type": "application/json" },
|
|
631
|
+
body: JSON.stringify({
|
|
632
|
+
challenge,
|
|
633
|
+
external_wallet: walletAddress,
|
|
634
|
+
signature,
|
|
635
|
+
name
|
|
636
|
+
})
|
|
637
|
+
});
|
|
638
|
+
if (!registerResponse.ok) {
|
|
639
|
+
const error = await registerResponse.json().catch(() => ({}));
|
|
640
|
+
throw new MixrPayError(error.error || `Registration failed: ${registerResponse.status}`);
|
|
641
|
+
}
|
|
642
|
+
const data = await registerResponse.json();
|
|
643
|
+
return {
|
|
644
|
+
userId: data.user_id,
|
|
645
|
+
depositAddress: data.deposit_address
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Get a session key for an already-registered agent.
|
|
650
|
+
*
|
|
651
|
+
* Session keys allow the agent to make payments within the specified limits.
|
|
652
|
+
* The private key is returned ONCE - store it securely!
|
|
653
|
+
*
|
|
654
|
+
* @param options - Session key options
|
|
655
|
+
* @returns Session key result with the sk_live_ format key
|
|
656
|
+
* @throws {MixrPayError} If session key creation fails
|
|
657
|
+
*
|
|
658
|
+
* @example
|
|
659
|
+
* ```typescript
|
|
660
|
+
* const result = await AgentWallet.getSessionKey({
|
|
661
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
662
|
+
* spendingLimitUsd: 100,
|
|
663
|
+
* durationDays: 30,
|
|
664
|
+
* });
|
|
665
|
+
*
|
|
666
|
+
* // Store this securely - it's your payment key!
|
|
667
|
+
* console.log(`Session key: ${result.sessionKey}`);
|
|
668
|
+
*
|
|
669
|
+
* // Use it to create an AgentWallet
|
|
670
|
+
* const wallet = new AgentWallet({ sessionKey: result.sessionKey });
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
static async getSessionKey(options) {
|
|
674
|
+
const { privateKey, spendingLimitUsd, maxPerTxUsd, maxDailyUsd, durationDays } = options;
|
|
675
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
676
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
677
|
+
const walletAddress = account.address;
|
|
678
|
+
const challengeResponse = await fetch(
|
|
679
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=session-key`
|
|
680
|
+
);
|
|
681
|
+
if (!challengeResponse.ok) {
|
|
682
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
683
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
684
|
+
}
|
|
685
|
+
const { challenge, message } = await challengeResponse.json();
|
|
686
|
+
const signature = await (0, import_accounts2.signMessage)({ message, privateKey });
|
|
687
|
+
const sessionKeyResponse = await fetch(`${baseUrl}/api/v1/agent/session-key`, {
|
|
688
|
+
method: "POST",
|
|
689
|
+
headers: { "Content-Type": "application/json" },
|
|
690
|
+
body: JSON.stringify({
|
|
691
|
+
challenge,
|
|
692
|
+
external_wallet: walletAddress,
|
|
693
|
+
signature,
|
|
694
|
+
spending_limit_usd: spendingLimitUsd,
|
|
695
|
+
max_per_tx_usd: maxPerTxUsd,
|
|
696
|
+
max_daily_usd: maxDailyUsd,
|
|
697
|
+
duration_days: durationDays
|
|
698
|
+
})
|
|
699
|
+
});
|
|
700
|
+
if (!sessionKeyResponse.ok) {
|
|
701
|
+
const error = await sessionKeyResponse.json().catch(() => ({}));
|
|
702
|
+
throw new MixrPayError(error.error || `Session key creation failed: ${sessionKeyResponse.status}`);
|
|
703
|
+
}
|
|
704
|
+
const data = await sessionKeyResponse.json();
|
|
705
|
+
return {
|
|
706
|
+
sessionKey: data.session_key,
|
|
707
|
+
address: data.address,
|
|
708
|
+
sessionKeyId: data.session_key_id,
|
|
709
|
+
expiresAt: new Date(data.expires_at),
|
|
710
|
+
limits: {
|
|
711
|
+
maxTotalUsd: data.limits.max_total_usd,
|
|
712
|
+
maxPerTxUsd: data.limits.max_per_tx_usd,
|
|
713
|
+
maxDailyUsd: data.limits.max_daily_usd
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Get the status of a registered agent.
|
|
719
|
+
*
|
|
720
|
+
* Returns balance, active sessions, and spending information.
|
|
721
|
+
*
|
|
722
|
+
* @param options - Status options
|
|
723
|
+
* @returns Agent status
|
|
724
|
+
* @throws {MixrPayError} If status fetch fails
|
|
725
|
+
*
|
|
726
|
+
* @example
|
|
727
|
+
* ```typescript
|
|
728
|
+
* const status = await AgentWallet.getStatus({
|
|
729
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
730
|
+
* });
|
|
731
|
+
*
|
|
732
|
+
* console.log(`Balance: $${status.balanceUsd}`);
|
|
733
|
+
* console.log(`Active sessions: ${status.activeSessions.length}`);
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
static async getStatus(options) {
|
|
737
|
+
const { privateKey } = options;
|
|
738
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
739
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
740
|
+
const walletAddress = account.address;
|
|
741
|
+
const challengeResponse = await fetch(
|
|
742
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=status`
|
|
743
|
+
);
|
|
744
|
+
if (!challengeResponse.ok) {
|
|
745
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
746
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
747
|
+
}
|
|
748
|
+
const { challenge, message } = await challengeResponse.json();
|
|
749
|
+
const signature = await (0, import_accounts2.signMessage)({ message, privateKey });
|
|
750
|
+
const statusResponse = await fetch(
|
|
751
|
+
`${baseUrl}/api/v1/agent/status?challenge=${challenge}&external_wallet=${walletAddress}&signature=${encodeURIComponent(signature)}`
|
|
752
|
+
);
|
|
753
|
+
if (!statusResponse.ok) {
|
|
754
|
+
const error = await statusResponse.json().catch(() => ({}));
|
|
755
|
+
throw new MixrPayError(error.error || `Failed to get status: ${statusResponse.status}`);
|
|
756
|
+
}
|
|
757
|
+
const data = await statusResponse.json();
|
|
758
|
+
return {
|
|
759
|
+
depositAddress: data.deposit_address,
|
|
760
|
+
balanceUsd: data.balance_usd,
|
|
761
|
+
activeSessions: data.active_sessions.map((s) => ({
|
|
762
|
+
id: s.id,
|
|
763
|
+
expiresAt: new Date(s.expires_at),
|
|
764
|
+
totalSpentUsd: s.total_spent_usd,
|
|
765
|
+
remainingUsd: s.remaining_usd,
|
|
766
|
+
maxTotalUsd: s.max_total_usd
|
|
767
|
+
})),
|
|
768
|
+
totalSpentUsd: data.total_spent_usd
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Revoke a session key.
|
|
773
|
+
*
|
|
774
|
+
* After revocation, the session key can no longer be used for payments.
|
|
775
|
+
*
|
|
776
|
+
* @param options - Revoke options
|
|
777
|
+
* @returns true if revoked successfully
|
|
778
|
+
* @throws {MixrPayError} If revocation fails
|
|
779
|
+
*
|
|
780
|
+
* @example
|
|
781
|
+
* ```typescript
|
|
782
|
+
* const success = await AgentWallet.revokeSessionKey({
|
|
783
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
784
|
+
* sessionKeyId: 'session-key-uuid',
|
|
785
|
+
* });
|
|
786
|
+
*
|
|
787
|
+
* if (success) {
|
|
788
|
+
* console.log('Session key revoked');
|
|
789
|
+
* }
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
792
|
+
static async revokeSessionKey(options) {
|
|
793
|
+
const { privateKey, sessionKeyId } = options;
|
|
794
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
795
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
796
|
+
const walletAddress = account.address;
|
|
797
|
+
const challengeResponse = await fetch(
|
|
798
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=revoke`
|
|
799
|
+
);
|
|
800
|
+
if (!challengeResponse.ok) {
|
|
801
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
802
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
803
|
+
}
|
|
804
|
+
const { challenge, message } = await challengeResponse.json();
|
|
805
|
+
const signature = await (0, import_accounts2.signMessage)({ message, privateKey });
|
|
806
|
+
const revokeResponse = await fetch(`${baseUrl}/api/v1/agent/session-key/revoke`, {
|
|
807
|
+
method: "POST",
|
|
808
|
+
headers: { "Content-Type": "application/json" },
|
|
809
|
+
body: JSON.stringify({
|
|
810
|
+
challenge,
|
|
811
|
+
external_wallet: walletAddress,
|
|
812
|
+
signature,
|
|
813
|
+
session_key_id: sessionKeyId
|
|
814
|
+
})
|
|
815
|
+
});
|
|
816
|
+
if (!revokeResponse.ok) {
|
|
817
|
+
const error = await revokeResponse.json().catch(() => ({}));
|
|
818
|
+
throw new MixrPayError(error.error || `Revocation failed: ${revokeResponse.status}`);
|
|
819
|
+
}
|
|
820
|
+
return true;
|
|
821
|
+
}
|
|
822
|
+
// ===========================================================================
|
|
589
823
|
// Core Methods
|
|
590
824
|
// ===========================================================================
|
|
591
825
|
/**
|
package/dist/index.d.cts
CHANGED
|
@@ -359,7 +359,7 @@ interface SessionStats {
|
|
|
359
359
|
*/
|
|
360
360
|
|
|
361
361
|
/** Current SDK version */
|
|
362
|
-
declare const SDK_VERSION = "0.
|
|
362
|
+
declare const SDK_VERSION = "0.5.0";
|
|
363
363
|
/** Supported networks */
|
|
364
364
|
declare const NETWORKS: {
|
|
365
365
|
readonly BASE_MAINNET: {
|
|
@@ -373,6 +373,101 @@ declare const NETWORKS: {
|
|
|
373
373
|
readonly isTestnet: true;
|
|
374
374
|
};
|
|
375
375
|
};
|
|
376
|
+
/**
|
|
377
|
+
* Options for registering an agent
|
|
378
|
+
*/
|
|
379
|
+
interface AgentRegisterOptions {
|
|
380
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
381
|
+
privateKey: `0x${string}`;
|
|
382
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
383
|
+
baseUrl?: string;
|
|
384
|
+
/** Optional display name for the agent */
|
|
385
|
+
name?: string;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Result from agent registration
|
|
389
|
+
*/
|
|
390
|
+
interface AgentRegisterResult {
|
|
391
|
+
/** Internal user ID */
|
|
392
|
+
userId: string;
|
|
393
|
+
/** Address to fund the agent's payment wallet */
|
|
394
|
+
depositAddress: string;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Options for getting a session key
|
|
398
|
+
*/
|
|
399
|
+
interface AgentGetSessionKeyOptions {
|
|
400
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
401
|
+
privateKey: `0x${string}`;
|
|
402
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
403
|
+
baseUrl?: string;
|
|
404
|
+
/** Maximum total spending in USD (default: $25) */
|
|
405
|
+
spendingLimitUsd?: number;
|
|
406
|
+
/** Maximum per transaction in USD */
|
|
407
|
+
maxPerTxUsd?: number;
|
|
408
|
+
/** Maximum daily spending in USD */
|
|
409
|
+
maxDailyUsd?: number;
|
|
410
|
+
/** Session duration in days (default: 7, max: 365) */
|
|
411
|
+
durationDays?: number;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Result from getting a session key
|
|
415
|
+
*/
|
|
416
|
+
interface AgentGetSessionKeyResult {
|
|
417
|
+
/** The session key in sk_live_{hex} format - STORE SECURELY! */
|
|
418
|
+
sessionKey: string;
|
|
419
|
+
/** The derived public address */
|
|
420
|
+
address: string;
|
|
421
|
+
/** Session key database ID */
|
|
422
|
+
sessionKeyId: string;
|
|
423
|
+
/** When the session key expires */
|
|
424
|
+
expiresAt: Date;
|
|
425
|
+
/** Spending limits */
|
|
426
|
+
limits: {
|
|
427
|
+
maxTotalUsd: number | null;
|
|
428
|
+
maxPerTxUsd: number | null;
|
|
429
|
+
maxDailyUsd: number | null;
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Options for getting agent status
|
|
434
|
+
*/
|
|
435
|
+
interface AgentGetStatusOptions {
|
|
436
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
437
|
+
privateKey: `0x${string}`;
|
|
438
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
439
|
+
baseUrl?: string;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Result from getting agent status
|
|
443
|
+
*/
|
|
444
|
+
interface AgentGetStatusResult {
|
|
445
|
+
/** Address of the agent's payment wallet */
|
|
446
|
+
depositAddress: string;
|
|
447
|
+
/** Current USDC balance in USD */
|
|
448
|
+
balanceUsd: number;
|
|
449
|
+
/** Active session keys */
|
|
450
|
+
activeSessions: Array<{
|
|
451
|
+
id: string;
|
|
452
|
+
expiresAt: Date;
|
|
453
|
+
totalSpentUsd: number;
|
|
454
|
+
remainingUsd: number | null;
|
|
455
|
+
maxTotalUsd: number | null;
|
|
456
|
+
}>;
|
|
457
|
+
/** Total spent across all sessions */
|
|
458
|
+
totalSpentUsd: number;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Options for revoking a session key
|
|
462
|
+
*/
|
|
463
|
+
interface AgentRevokeSessionKeyOptions {
|
|
464
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
465
|
+
privateKey: `0x${string}`;
|
|
466
|
+
/** The session key ID to revoke */
|
|
467
|
+
sessionKeyId: string;
|
|
468
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
469
|
+
baseUrl?: string;
|
|
470
|
+
}
|
|
376
471
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
377
472
|
/**
|
|
378
473
|
* A wallet wrapper for AI agents that handles x402 payments automatically.
|
|
@@ -454,6 +549,95 @@ declare class AgentWallet {
|
|
|
454
549
|
* Validate the configuration before initialization.
|
|
455
550
|
*/
|
|
456
551
|
private validateConfig;
|
|
552
|
+
/**
|
|
553
|
+
* Register a new agent with MixrPay.
|
|
554
|
+
*
|
|
555
|
+
* This creates a Privy-managed embedded wallet for the agent's payments.
|
|
556
|
+
* The agent proves ownership of their external wallet by signing a challenge.
|
|
557
|
+
*
|
|
558
|
+
* @param options - Registration options including the private key
|
|
559
|
+
* @returns Registration result with deposit address
|
|
560
|
+
* @throws {MixrPayError} If registration fails
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* ```typescript
|
|
564
|
+
* const { depositAddress, userId } = await AgentWallet.register({
|
|
565
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
566
|
+
* name: 'My Trading Agent',
|
|
567
|
+
* });
|
|
568
|
+
*
|
|
569
|
+
* console.log(`Fund your agent at: ${depositAddress}`);
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
static register(options: AgentRegisterOptions): Promise<AgentRegisterResult>;
|
|
573
|
+
/**
|
|
574
|
+
* Get a session key for an already-registered agent.
|
|
575
|
+
*
|
|
576
|
+
* Session keys allow the agent to make payments within the specified limits.
|
|
577
|
+
* The private key is returned ONCE - store it securely!
|
|
578
|
+
*
|
|
579
|
+
* @param options - Session key options
|
|
580
|
+
* @returns Session key result with the sk_live_ format key
|
|
581
|
+
* @throws {MixrPayError} If session key creation fails
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```typescript
|
|
585
|
+
* const result = await AgentWallet.getSessionKey({
|
|
586
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
587
|
+
* spendingLimitUsd: 100,
|
|
588
|
+
* durationDays: 30,
|
|
589
|
+
* });
|
|
590
|
+
*
|
|
591
|
+
* // Store this securely - it's your payment key!
|
|
592
|
+
* console.log(`Session key: ${result.sessionKey}`);
|
|
593
|
+
*
|
|
594
|
+
* // Use it to create an AgentWallet
|
|
595
|
+
* const wallet = new AgentWallet({ sessionKey: result.sessionKey });
|
|
596
|
+
* ```
|
|
597
|
+
*/
|
|
598
|
+
static getSessionKey(options: AgentGetSessionKeyOptions): Promise<AgentGetSessionKeyResult>;
|
|
599
|
+
/**
|
|
600
|
+
* Get the status of a registered agent.
|
|
601
|
+
*
|
|
602
|
+
* Returns balance, active sessions, and spending information.
|
|
603
|
+
*
|
|
604
|
+
* @param options - Status options
|
|
605
|
+
* @returns Agent status
|
|
606
|
+
* @throws {MixrPayError} If status fetch fails
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```typescript
|
|
610
|
+
* const status = await AgentWallet.getStatus({
|
|
611
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
612
|
+
* });
|
|
613
|
+
*
|
|
614
|
+
* console.log(`Balance: $${status.balanceUsd}`);
|
|
615
|
+
* console.log(`Active sessions: ${status.activeSessions.length}`);
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
static getStatus(options: AgentGetStatusOptions): Promise<AgentGetStatusResult>;
|
|
619
|
+
/**
|
|
620
|
+
* Revoke a session key.
|
|
621
|
+
*
|
|
622
|
+
* After revocation, the session key can no longer be used for payments.
|
|
623
|
+
*
|
|
624
|
+
* @param options - Revoke options
|
|
625
|
+
* @returns true if revoked successfully
|
|
626
|
+
* @throws {MixrPayError} If revocation fails
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```typescript
|
|
630
|
+
* const success = await AgentWallet.revokeSessionKey({
|
|
631
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
632
|
+
* sessionKeyId: 'session-key-uuid',
|
|
633
|
+
* });
|
|
634
|
+
*
|
|
635
|
+
* if (success) {
|
|
636
|
+
* console.log('Session key revoked');
|
|
637
|
+
* }
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
static revokeSessionKey(options: AgentRevokeSessionKeyOptions): Promise<boolean>;
|
|
457
641
|
/**
|
|
458
642
|
* Make an HTTP request, automatically handling x402 payment if required.
|
|
459
643
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -359,7 +359,7 @@ interface SessionStats {
|
|
|
359
359
|
*/
|
|
360
360
|
|
|
361
361
|
/** Current SDK version */
|
|
362
|
-
declare const SDK_VERSION = "0.
|
|
362
|
+
declare const SDK_VERSION = "0.5.0";
|
|
363
363
|
/** Supported networks */
|
|
364
364
|
declare const NETWORKS: {
|
|
365
365
|
readonly BASE_MAINNET: {
|
|
@@ -373,6 +373,101 @@ declare const NETWORKS: {
|
|
|
373
373
|
readonly isTestnet: true;
|
|
374
374
|
};
|
|
375
375
|
};
|
|
376
|
+
/**
|
|
377
|
+
* Options for registering an agent
|
|
378
|
+
*/
|
|
379
|
+
interface AgentRegisterOptions {
|
|
380
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
381
|
+
privateKey: `0x${string}`;
|
|
382
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
383
|
+
baseUrl?: string;
|
|
384
|
+
/** Optional display name for the agent */
|
|
385
|
+
name?: string;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Result from agent registration
|
|
389
|
+
*/
|
|
390
|
+
interface AgentRegisterResult {
|
|
391
|
+
/** Internal user ID */
|
|
392
|
+
userId: string;
|
|
393
|
+
/** Address to fund the agent's payment wallet */
|
|
394
|
+
depositAddress: string;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Options for getting a session key
|
|
398
|
+
*/
|
|
399
|
+
interface AgentGetSessionKeyOptions {
|
|
400
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
401
|
+
privateKey: `0x${string}`;
|
|
402
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
403
|
+
baseUrl?: string;
|
|
404
|
+
/** Maximum total spending in USD (default: $25) */
|
|
405
|
+
spendingLimitUsd?: number;
|
|
406
|
+
/** Maximum per transaction in USD */
|
|
407
|
+
maxPerTxUsd?: number;
|
|
408
|
+
/** Maximum daily spending in USD */
|
|
409
|
+
maxDailyUsd?: number;
|
|
410
|
+
/** Session duration in days (default: 7, max: 365) */
|
|
411
|
+
durationDays?: number;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Result from getting a session key
|
|
415
|
+
*/
|
|
416
|
+
interface AgentGetSessionKeyResult {
|
|
417
|
+
/** The session key in sk_live_{hex} format - STORE SECURELY! */
|
|
418
|
+
sessionKey: string;
|
|
419
|
+
/** The derived public address */
|
|
420
|
+
address: string;
|
|
421
|
+
/** Session key database ID */
|
|
422
|
+
sessionKeyId: string;
|
|
423
|
+
/** When the session key expires */
|
|
424
|
+
expiresAt: Date;
|
|
425
|
+
/** Spending limits */
|
|
426
|
+
limits: {
|
|
427
|
+
maxTotalUsd: number | null;
|
|
428
|
+
maxPerTxUsd: number | null;
|
|
429
|
+
maxDailyUsd: number | null;
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Options for getting agent status
|
|
434
|
+
*/
|
|
435
|
+
interface AgentGetStatusOptions {
|
|
436
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
437
|
+
privateKey: `0x${string}`;
|
|
438
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
439
|
+
baseUrl?: string;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Result from getting agent status
|
|
443
|
+
*/
|
|
444
|
+
interface AgentGetStatusResult {
|
|
445
|
+
/** Address of the agent's payment wallet */
|
|
446
|
+
depositAddress: string;
|
|
447
|
+
/** Current USDC balance in USD */
|
|
448
|
+
balanceUsd: number;
|
|
449
|
+
/** Active session keys */
|
|
450
|
+
activeSessions: Array<{
|
|
451
|
+
id: string;
|
|
452
|
+
expiresAt: Date;
|
|
453
|
+
totalSpentUsd: number;
|
|
454
|
+
remainingUsd: number | null;
|
|
455
|
+
maxTotalUsd: number | null;
|
|
456
|
+
}>;
|
|
457
|
+
/** Total spent across all sessions */
|
|
458
|
+
totalSpentUsd: number;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Options for revoking a session key
|
|
462
|
+
*/
|
|
463
|
+
interface AgentRevokeSessionKeyOptions {
|
|
464
|
+
/** The agent's external wallet private key (used for signing, NOT transmitted) */
|
|
465
|
+
privateKey: `0x${string}`;
|
|
466
|
+
/** The session key ID to revoke */
|
|
467
|
+
sessionKeyId: string;
|
|
468
|
+
/** MixrPay API base URL (default: https://www.mixrpay.com) */
|
|
469
|
+
baseUrl?: string;
|
|
470
|
+
}
|
|
376
471
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
377
472
|
/**
|
|
378
473
|
* A wallet wrapper for AI agents that handles x402 payments automatically.
|
|
@@ -454,6 +549,95 @@ declare class AgentWallet {
|
|
|
454
549
|
* Validate the configuration before initialization.
|
|
455
550
|
*/
|
|
456
551
|
private validateConfig;
|
|
552
|
+
/**
|
|
553
|
+
* Register a new agent with MixrPay.
|
|
554
|
+
*
|
|
555
|
+
* This creates a Privy-managed embedded wallet for the agent's payments.
|
|
556
|
+
* The agent proves ownership of their external wallet by signing a challenge.
|
|
557
|
+
*
|
|
558
|
+
* @param options - Registration options including the private key
|
|
559
|
+
* @returns Registration result with deposit address
|
|
560
|
+
* @throws {MixrPayError} If registration fails
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* ```typescript
|
|
564
|
+
* const { depositAddress, userId } = await AgentWallet.register({
|
|
565
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
566
|
+
* name: 'My Trading Agent',
|
|
567
|
+
* });
|
|
568
|
+
*
|
|
569
|
+
* console.log(`Fund your agent at: ${depositAddress}`);
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
static register(options: AgentRegisterOptions): Promise<AgentRegisterResult>;
|
|
573
|
+
/**
|
|
574
|
+
* Get a session key for an already-registered agent.
|
|
575
|
+
*
|
|
576
|
+
* Session keys allow the agent to make payments within the specified limits.
|
|
577
|
+
* The private key is returned ONCE - store it securely!
|
|
578
|
+
*
|
|
579
|
+
* @param options - Session key options
|
|
580
|
+
* @returns Session key result with the sk_live_ format key
|
|
581
|
+
* @throws {MixrPayError} If session key creation fails
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```typescript
|
|
585
|
+
* const result = await AgentWallet.getSessionKey({
|
|
586
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
587
|
+
* spendingLimitUsd: 100,
|
|
588
|
+
* durationDays: 30,
|
|
589
|
+
* });
|
|
590
|
+
*
|
|
591
|
+
* // Store this securely - it's your payment key!
|
|
592
|
+
* console.log(`Session key: ${result.sessionKey}`);
|
|
593
|
+
*
|
|
594
|
+
* // Use it to create an AgentWallet
|
|
595
|
+
* const wallet = new AgentWallet({ sessionKey: result.sessionKey });
|
|
596
|
+
* ```
|
|
597
|
+
*/
|
|
598
|
+
static getSessionKey(options: AgentGetSessionKeyOptions): Promise<AgentGetSessionKeyResult>;
|
|
599
|
+
/**
|
|
600
|
+
* Get the status of a registered agent.
|
|
601
|
+
*
|
|
602
|
+
* Returns balance, active sessions, and spending information.
|
|
603
|
+
*
|
|
604
|
+
* @param options - Status options
|
|
605
|
+
* @returns Agent status
|
|
606
|
+
* @throws {MixrPayError} If status fetch fails
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```typescript
|
|
610
|
+
* const status = await AgentWallet.getStatus({
|
|
611
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
612
|
+
* });
|
|
613
|
+
*
|
|
614
|
+
* console.log(`Balance: $${status.balanceUsd}`);
|
|
615
|
+
* console.log(`Active sessions: ${status.activeSessions.length}`);
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
static getStatus(options: AgentGetStatusOptions): Promise<AgentGetStatusResult>;
|
|
619
|
+
/**
|
|
620
|
+
* Revoke a session key.
|
|
621
|
+
*
|
|
622
|
+
* After revocation, the session key can no longer be used for payments.
|
|
623
|
+
*
|
|
624
|
+
* @param options - Revoke options
|
|
625
|
+
* @returns true if revoked successfully
|
|
626
|
+
* @throws {MixrPayError} If revocation fails
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```typescript
|
|
630
|
+
* const success = await AgentWallet.revokeSessionKey({
|
|
631
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
632
|
+
* sessionKeyId: 'session-key-uuid',
|
|
633
|
+
* });
|
|
634
|
+
*
|
|
635
|
+
* if (success) {
|
|
636
|
+
* console.log('Session key revoked');
|
|
637
|
+
* }
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
static revokeSessionKey(options: AgentRevokeSessionKeyOptions): Promise<boolean>;
|
|
457
641
|
/**
|
|
458
642
|
* Make an HTTP request, automatically handling x402 payment if required.
|
|
459
643
|
*
|
package/dist/index.js
CHANGED
|
@@ -319,6 +319,9 @@ async function createSessionAuthPayload(sessionKey) {
|
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
// src/agent-wallet.ts
|
|
323
|
+
import { privateKeyToAccount as privateKeyToAccount2, signMessage } from "viem/accounts";
|
|
324
|
+
|
|
322
325
|
// src/x402.ts
|
|
323
326
|
async function parse402Response(response) {
|
|
324
327
|
let paymentData = null;
|
|
@@ -408,7 +411,7 @@ function getAmountUsd(requirements) {
|
|
|
408
411
|
}
|
|
409
412
|
|
|
410
413
|
// src/agent-wallet.ts
|
|
411
|
-
var SDK_VERSION = "0.
|
|
414
|
+
var SDK_VERSION = "0.5.0";
|
|
412
415
|
var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
|
|
413
416
|
var DEFAULT_TIMEOUT = 3e4;
|
|
414
417
|
var NETWORKS = {
|
|
@@ -552,6 +555,237 @@ var AgentWallet = class {
|
|
|
552
555
|
}
|
|
553
556
|
}
|
|
554
557
|
// ===========================================================================
|
|
558
|
+
// Static Agent Registration Methods
|
|
559
|
+
// ===========================================================================
|
|
560
|
+
/**
|
|
561
|
+
* Register a new agent with MixrPay.
|
|
562
|
+
*
|
|
563
|
+
* This creates a Privy-managed embedded wallet for the agent's payments.
|
|
564
|
+
* The agent proves ownership of their external wallet by signing a challenge.
|
|
565
|
+
*
|
|
566
|
+
* @param options - Registration options including the private key
|
|
567
|
+
* @returns Registration result with deposit address
|
|
568
|
+
* @throws {MixrPayError} If registration fails
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* ```typescript
|
|
572
|
+
* const { depositAddress, userId } = await AgentWallet.register({
|
|
573
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
574
|
+
* name: 'My Trading Agent',
|
|
575
|
+
* });
|
|
576
|
+
*
|
|
577
|
+
* console.log(`Fund your agent at: ${depositAddress}`);
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
static async register(options) {
|
|
581
|
+
const { privateKey, name } = options;
|
|
582
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
583
|
+
const account = privateKeyToAccount2(privateKey);
|
|
584
|
+
const walletAddress = account.address;
|
|
585
|
+
const challengeResponse = await fetch(
|
|
586
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=register`
|
|
587
|
+
);
|
|
588
|
+
if (!challengeResponse.ok) {
|
|
589
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
590
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
591
|
+
}
|
|
592
|
+
const { challenge, message } = await challengeResponse.json();
|
|
593
|
+
const signature = await signMessage({ message, privateKey });
|
|
594
|
+
const registerResponse = await fetch(`${baseUrl}/api/v1/agent/register`, {
|
|
595
|
+
method: "POST",
|
|
596
|
+
headers: { "Content-Type": "application/json" },
|
|
597
|
+
body: JSON.stringify({
|
|
598
|
+
challenge,
|
|
599
|
+
external_wallet: walletAddress,
|
|
600
|
+
signature,
|
|
601
|
+
name
|
|
602
|
+
})
|
|
603
|
+
});
|
|
604
|
+
if (!registerResponse.ok) {
|
|
605
|
+
const error = await registerResponse.json().catch(() => ({}));
|
|
606
|
+
throw new MixrPayError(error.error || `Registration failed: ${registerResponse.status}`);
|
|
607
|
+
}
|
|
608
|
+
const data = await registerResponse.json();
|
|
609
|
+
return {
|
|
610
|
+
userId: data.user_id,
|
|
611
|
+
depositAddress: data.deposit_address
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Get a session key for an already-registered agent.
|
|
616
|
+
*
|
|
617
|
+
* Session keys allow the agent to make payments within the specified limits.
|
|
618
|
+
* The private key is returned ONCE - store it securely!
|
|
619
|
+
*
|
|
620
|
+
* @param options - Session key options
|
|
621
|
+
* @returns Session key result with the sk_live_ format key
|
|
622
|
+
* @throws {MixrPayError} If session key creation fails
|
|
623
|
+
*
|
|
624
|
+
* @example
|
|
625
|
+
* ```typescript
|
|
626
|
+
* const result = await AgentWallet.getSessionKey({
|
|
627
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
628
|
+
* spendingLimitUsd: 100,
|
|
629
|
+
* durationDays: 30,
|
|
630
|
+
* });
|
|
631
|
+
*
|
|
632
|
+
* // Store this securely - it's your payment key!
|
|
633
|
+
* console.log(`Session key: ${result.sessionKey}`);
|
|
634
|
+
*
|
|
635
|
+
* // Use it to create an AgentWallet
|
|
636
|
+
* const wallet = new AgentWallet({ sessionKey: result.sessionKey });
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
static async getSessionKey(options) {
|
|
640
|
+
const { privateKey, spendingLimitUsd, maxPerTxUsd, maxDailyUsd, durationDays } = options;
|
|
641
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
642
|
+
const account = privateKeyToAccount2(privateKey);
|
|
643
|
+
const walletAddress = account.address;
|
|
644
|
+
const challengeResponse = await fetch(
|
|
645
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=session-key`
|
|
646
|
+
);
|
|
647
|
+
if (!challengeResponse.ok) {
|
|
648
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
649
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
650
|
+
}
|
|
651
|
+
const { challenge, message } = await challengeResponse.json();
|
|
652
|
+
const signature = await signMessage({ message, privateKey });
|
|
653
|
+
const sessionKeyResponse = await fetch(`${baseUrl}/api/v1/agent/session-key`, {
|
|
654
|
+
method: "POST",
|
|
655
|
+
headers: { "Content-Type": "application/json" },
|
|
656
|
+
body: JSON.stringify({
|
|
657
|
+
challenge,
|
|
658
|
+
external_wallet: walletAddress,
|
|
659
|
+
signature,
|
|
660
|
+
spending_limit_usd: spendingLimitUsd,
|
|
661
|
+
max_per_tx_usd: maxPerTxUsd,
|
|
662
|
+
max_daily_usd: maxDailyUsd,
|
|
663
|
+
duration_days: durationDays
|
|
664
|
+
})
|
|
665
|
+
});
|
|
666
|
+
if (!sessionKeyResponse.ok) {
|
|
667
|
+
const error = await sessionKeyResponse.json().catch(() => ({}));
|
|
668
|
+
throw new MixrPayError(error.error || `Session key creation failed: ${sessionKeyResponse.status}`);
|
|
669
|
+
}
|
|
670
|
+
const data = await sessionKeyResponse.json();
|
|
671
|
+
return {
|
|
672
|
+
sessionKey: data.session_key,
|
|
673
|
+
address: data.address,
|
|
674
|
+
sessionKeyId: data.session_key_id,
|
|
675
|
+
expiresAt: new Date(data.expires_at),
|
|
676
|
+
limits: {
|
|
677
|
+
maxTotalUsd: data.limits.max_total_usd,
|
|
678
|
+
maxPerTxUsd: data.limits.max_per_tx_usd,
|
|
679
|
+
maxDailyUsd: data.limits.max_daily_usd
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Get the status of a registered agent.
|
|
685
|
+
*
|
|
686
|
+
* Returns balance, active sessions, and spending information.
|
|
687
|
+
*
|
|
688
|
+
* @param options - Status options
|
|
689
|
+
* @returns Agent status
|
|
690
|
+
* @throws {MixrPayError} If status fetch fails
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```typescript
|
|
694
|
+
* const status = await AgentWallet.getStatus({
|
|
695
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
696
|
+
* });
|
|
697
|
+
*
|
|
698
|
+
* console.log(`Balance: $${status.balanceUsd}`);
|
|
699
|
+
* console.log(`Active sessions: ${status.activeSessions.length}`);
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
static async getStatus(options) {
|
|
703
|
+
const { privateKey } = options;
|
|
704
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
705
|
+
const account = privateKeyToAccount2(privateKey);
|
|
706
|
+
const walletAddress = account.address;
|
|
707
|
+
const challengeResponse = await fetch(
|
|
708
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=status`
|
|
709
|
+
);
|
|
710
|
+
if (!challengeResponse.ok) {
|
|
711
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
712
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
713
|
+
}
|
|
714
|
+
const { challenge, message } = await challengeResponse.json();
|
|
715
|
+
const signature = await signMessage({ message, privateKey });
|
|
716
|
+
const statusResponse = await fetch(
|
|
717
|
+
`${baseUrl}/api/v1/agent/status?challenge=${challenge}&external_wallet=${walletAddress}&signature=${encodeURIComponent(signature)}`
|
|
718
|
+
);
|
|
719
|
+
if (!statusResponse.ok) {
|
|
720
|
+
const error = await statusResponse.json().catch(() => ({}));
|
|
721
|
+
throw new MixrPayError(error.error || `Failed to get status: ${statusResponse.status}`);
|
|
722
|
+
}
|
|
723
|
+
const data = await statusResponse.json();
|
|
724
|
+
return {
|
|
725
|
+
depositAddress: data.deposit_address,
|
|
726
|
+
balanceUsd: data.balance_usd,
|
|
727
|
+
activeSessions: data.active_sessions.map((s) => ({
|
|
728
|
+
id: s.id,
|
|
729
|
+
expiresAt: new Date(s.expires_at),
|
|
730
|
+
totalSpentUsd: s.total_spent_usd,
|
|
731
|
+
remainingUsd: s.remaining_usd,
|
|
732
|
+
maxTotalUsd: s.max_total_usd
|
|
733
|
+
})),
|
|
734
|
+
totalSpentUsd: data.total_spent_usd
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Revoke a session key.
|
|
739
|
+
*
|
|
740
|
+
* After revocation, the session key can no longer be used for payments.
|
|
741
|
+
*
|
|
742
|
+
* @param options - Revoke options
|
|
743
|
+
* @returns true if revoked successfully
|
|
744
|
+
* @throws {MixrPayError} If revocation fails
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```typescript
|
|
748
|
+
* const success = await AgentWallet.revokeSessionKey({
|
|
749
|
+
* privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
750
|
+
* sessionKeyId: 'session-key-uuid',
|
|
751
|
+
* });
|
|
752
|
+
*
|
|
753
|
+
* if (success) {
|
|
754
|
+
* console.log('Session key revoked');
|
|
755
|
+
* }
|
|
756
|
+
* ```
|
|
757
|
+
*/
|
|
758
|
+
static async revokeSessionKey(options) {
|
|
759
|
+
const { privateKey, sessionKeyId } = options;
|
|
760
|
+
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
761
|
+
const account = privateKeyToAccount2(privateKey);
|
|
762
|
+
const walletAddress = account.address;
|
|
763
|
+
const challengeResponse = await fetch(
|
|
764
|
+
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=revoke`
|
|
765
|
+
);
|
|
766
|
+
if (!challengeResponse.ok) {
|
|
767
|
+
const error = await challengeResponse.json().catch(() => ({}));
|
|
768
|
+
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
769
|
+
}
|
|
770
|
+
const { challenge, message } = await challengeResponse.json();
|
|
771
|
+
const signature = await signMessage({ message, privateKey });
|
|
772
|
+
const revokeResponse = await fetch(`${baseUrl}/api/v1/agent/session-key/revoke`, {
|
|
773
|
+
method: "POST",
|
|
774
|
+
headers: { "Content-Type": "application/json" },
|
|
775
|
+
body: JSON.stringify({
|
|
776
|
+
challenge,
|
|
777
|
+
external_wallet: walletAddress,
|
|
778
|
+
signature,
|
|
779
|
+
session_key_id: sessionKeyId
|
|
780
|
+
})
|
|
781
|
+
});
|
|
782
|
+
if (!revokeResponse.ok) {
|
|
783
|
+
const error = await revokeResponse.json().catch(() => ({}));
|
|
784
|
+
throw new MixrPayError(error.error || `Revocation failed: ${revokeResponse.status}`);
|
|
785
|
+
}
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
// ===========================================================================
|
|
555
789
|
// Core Methods
|
|
556
790
|
// ===========================================================================
|
|
557
791
|
/**
|