@mixrpay/agent-sdk 0.8.9 → 0.9.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 +17 -0
- package/dist/index.cjs +114 -89
- package/dist/index.d.cts +50 -11
- package/dist/index.d.ts +50 -11
- package/dist/index.js +89 -43
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -107,6 +107,9 @@ await wallet.fetch(url, options);
|
|
|
107
107
|
// Get wallet balance
|
|
108
108
|
const balance = await wallet.getBalance();
|
|
109
109
|
|
|
110
|
+
// Execute on-chain transactions (bridges, swaps, DeFi) from human's wallet
|
|
111
|
+
await wallet.executeTransaction({ to, data, estimatedCostUsd });
|
|
112
|
+
|
|
110
113
|
// Pre-flight balance check
|
|
111
114
|
const check = await wallet.canAfford(0.50);
|
|
112
115
|
if (check.canAfford) { /* proceed */ }
|
|
@@ -116,6 +119,20 @@ const diag = await wallet.runDiagnostics();
|
|
|
116
119
|
console.log(diag.recommendations);
|
|
117
120
|
```
|
|
118
121
|
|
|
122
|
+
## Execute On-Chain Transactions
|
|
123
|
+
|
|
124
|
+
Agents can execute DeFi transactions (bridges, swaps) from the human's wallet, bounded by session key budget:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const result = await wallet.executeTransaction({
|
|
128
|
+
to: '0x...contractAddress',
|
|
129
|
+
data: '0x...calldata',
|
|
130
|
+
estimatedCostUsd: 25.0,
|
|
131
|
+
description: 'Bridge USDC via deBridge',
|
|
132
|
+
});
|
|
133
|
+
console.log(`TX: ${result.txHash}`);
|
|
134
|
+
```
|
|
135
|
+
|
|
119
136
|
## Configuration
|
|
120
137
|
|
|
121
138
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -1,46 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
'use strict';
|
|
19
2
|
|
|
20
|
-
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
AgentWallet: () => AgentWallet,
|
|
24
|
-
InsufficientBalanceError: () => InsufficientBalanceError,
|
|
25
|
-
InvalidSessionKeyError: () => InvalidSessionKeyError,
|
|
26
|
-
MerchantNotAllowedError: () => MerchantNotAllowedError,
|
|
27
|
-
MixrPayError: () => MixrPayError,
|
|
28
|
-
PaymentFailedError: () => PaymentFailedError,
|
|
29
|
-
SDK_VERSION: () => SDK_VERSION,
|
|
30
|
-
SessionExpiredError: () => SessionExpiredError,
|
|
31
|
-
SessionKeyExpiredError: () => SessionKeyExpiredError,
|
|
32
|
-
SessionLimitExceededError: () => SessionLimitExceededError,
|
|
33
|
-
SessionNotFoundError: () => SessionNotFoundError,
|
|
34
|
-
SessionRevokedError: () => SessionRevokedError,
|
|
35
|
-
SpendingLimitExceededError: () => SpendingLimitExceededError,
|
|
36
|
-
X402ProtocolError: () => X402ProtocolError,
|
|
37
|
-
getErrorMessage: () => getErrorMessage,
|
|
38
|
-
isMixrPayError: () => isMixrPayError
|
|
39
|
-
});
|
|
40
|
-
module.exports = __toCommonJS(index_exports);
|
|
3
|
+
var accounts = require('viem/accounts');
|
|
41
4
|
|
|
42
5
|
// src/session-key.ts
|
|
43
|
-
var import_accounts = require("viem/accounts");
|
|
44
6
|
|
|
45
7
|
// src/errors.ts
|
|
46
8
|
var MixrPayError = class extends Error {
|
|
@@ -324,7 +286,7 @@ var SessionKey = class _SessionKey {
|
|
|
324
286
|
isTest;
|
|
325
287
|
constructor(privateKey, isTest) {
|
|
326
288
|
this.privateKey = privateKey;
|
|
327
|
-
this.account =
|
|
289
|
+
this.account = accounts.privateKeyToAccount(privateKey);
|
|
328
290
|
this.address = this.account.address;
|
|
329
291
|
this.isTest = isTest;
|
|
330
292
|
}
|
|
@@ -374,7 +336,7 @@ var SessionKey = class _SessionKey {
|
|
|
374
336
|
* @returns Hex-encoded signature
|
|
375
337
|
*/
|
|
376
338
|
async signTransferAuthorization(domain, message) {
|
|
377
|
-
return
|
|
339
|
+
return accounts.signTypedData({
|
|
378
340
|
privateKey: this.privateKey,
|
|
379
341
|
domain,
|
|
380
342
|
types: TRANSFER_WITH_AUTHORIZATION_TYPES,
|
|
@@ -389,7 +351,7 @@ var SessionKey = class _SessionKey {
|
|
|
389
351
|
* @returns Hex-encoded signature
|
|
390
352
|
*/
|
|
391
353
|
async signMessage(message) {
|
|
392
|
-
return
|
|
354
|
+
return accounts.signMessage({
|
|
393
355
|
privateKey: this.privateKey,
|
|
394
356
|
message
|
|
395
357
|
});
|
|
@@ -440,9 +402,6 @@ async function createSessionAuthPayload(sessionKey) {
|
|
|
440
402
|
};
|
|
441
403
|
}
|
|
442
404
|
|
|
443
|
-
// src/agent-wallet.ts
|
|
444
|
-
var import_accounts2 = require("viem/accounts");
|
|
445
|
-
|
|
446
405
|
// src/x402.ts
|
|
447
406
|
async function parse402Response(response) {
|
|
448
407
|
let paymentData = null;
|
|
@@ -804,7 +763,7 @@ var AgentWallet = class {
|
|
|
804
763
|
/**
|
|
805
764
|
* Register a new agent with MixrPay.
|
|
806
765
|
*
|
|
807
|
-
* This creates a
|
|
766
|
+
* This creates a platform-managed embedded wallet for the agent's payments.
|
|
808
767
|
* The agent proves ownership of their external wallet by signing a challenge.
|
|
809
768
|
*
|
|
810
769
|
* @param options - Registration options including the private key
|
|
@@ -824,7 +783,7 @@ var AgentWallet = class {
|
|
|
824
783
|
static async register(options) {
|
|
825
784
|
const { privateKey, name } = options;
|
|
826
785
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
827
|
-
const account =
|
|
786
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
828
787
|
const walletAddress = account.address;
|
|
829
788
|
const challengeResponse = await fetch(
|
|
830
789
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=register`
|
|
@@ -834,7 +793,7 @@ var AgentWallet = class {
|
|
|
834
793
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
835
794
|
}
|
|
836
795
|
const { challenge, message } = await challengeResponse.json();
|
|
837
|
-
const signature = await
|
|
796
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
838
797
|
const registerResponse = await fetch(`${baseUrl}/api/v1/agent/register`, {
|
|
839
798
|
method: "POST",
|
|
840
799
|
headers: { "Content-Type": "application/json" },
|
|
@@ -892,7 +851,7 @@ var AgentWallet = class {
|
|
|
892
851
|
healthy: false,
|
|
893
852
|
database: "unknown",
|
|
894
853
|
agentRegistrationAvailable: false,
|
|
895
|
-
|
|
854
|
+
walletServiceConfigured: false,
|
|
896
855
|
error: `Health check failed with status ${response.status}`
|
|
897
856
|
};
|
|
898
857
|
}
|
|
@@ -901,14 +860,14 @@ var AgentWallet = class {
|
|
|
901
860
|
healthy: data.status === "ready",
|
|
902
861
|
database: data.database || "unknown",
|
|
903
862
|
agentRegistrationAvailable: data.services?.agentRegistration?.available ?? false,
|
|
904
|
-
|
|
863
|
+
walletServiceConfigured: data.services?.wallet?.configured ?? data.services?.privy?.configured ?? false
|
|
905
864
|
};
|
|
906
865
|
} catch (error) {
|
|
907
866
|
return {
|
|
908
867
|
healthy: false,
|
|
909
868
|
database: "unreachable",
|
|
910
869
|
agentRegistrationAvailable: false,
|
|
911
|
-
|
|
870
|
+
walletServiceConfigured: false,
|
|
912
871
|
error: error instanceof Error ? error.message : "Failed to reach server"
|
|
913
872
|
};
|
|
914
873
|
}
|
|
@@ -941,7 +900,7 @@ var AgentWallet = class {
|
|
|
941
900
|
static async getSessionKey(options) {
|
|
942
901
|
const { privateKey, spendingLimitUsd, maxPerTxUsd, maxDailyUsd, durationDays } = options;
|
|
943
902
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
944
|
-
const account =
|
|
903
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
945
904
|
const walletAddress = account.address;
|
|
946
905
|
const challengeResponse = await fetch(
|
|
947
906
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=session-key`
|
|
@@ -951,7 +910,7 @@ var AgentWallet = class {
|
|
|
951
910
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
952
911
|
}
|
|
953
912
|
const { challenge, message } = await challengeResponse.json();
|
|
954
|
-
const signature = await
|
|
913
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
955
914
|
const sessionKeyResponse = await fetch(`${baseUrl}/api/v1/agent/session-key`, {
|
|
956
915
|
method: "POST",
|
|
957
916
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1004,7 +963,7 @@ var AgentWallet = class {
|
|
|
1004
963
|
static async getStatus(options) {
|
|
1005
964
|
const { privateKey } = options;
|
|
1006
965
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1007
|
-
const account =
|
|
966
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
1008
967
|
const walletAddress = account.address;
|
|
1009
968
|
const challengeResponse = await fetch(
|
|
1010
969
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=status`
|
|
@@ -1014,7 +973,7 @@ var AgentWallet = class {
|
|
|
1014
973
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
1015
974
|
}
|
|
1016
975
|
const { challenge, message } = await challengeResponse.json();
|
|
1017
|
-
const signature = await
|
|
976
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
1018
977
|
const statusResponse = await fetch(
|
|
1019
978
|
`${baseUrl}/api/v1/agent/status?challenge=${challenge}&external_wallet=${walletAddress}&signature=${encodeURIComponent(signature)}`
|
|
1020
979
|
);
|
|
@@ -1060,7 +1019,7 @@ var AgentWallet = class {
|
|
|
1060
1019
|
static async revokeSessionKey(options) {
|
|
1061
1020
|
const { privateKey, sessionKeyId } = options;
|
|
1062
1021
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1063
|
-
const account =
|
|
1022
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
1064
1023
|
const walletAddress = account.address;
|
|
1065
1024
|
const challengeResponse = await fetch(
|
|
1066
1025
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=revoke`
|
|
@@ -1070,7 +1029,7 @@ var AgentWallet = class {
|
|
|
1070
1029
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
1071
1030
|
}
|
|
1072
1031
|
const { challenge, message } = await challengeResponse.json();
|
|
1073
|
-
const signature = await
|
|
1032
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
1074
1033
|
const revokeResponse = await fetch(`${baseUrl}/api/v1/agent/session-key/revoke`, {
|
|
1075
1034
|
method: "POST",
|
|
1076
1035
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1114,7 +1073,7 @@ var AgentWallet = class {
|
|
|
1114
1073
|
static async withdraw(options) {
|
|
1115
1074
|
const { privateKey, amountUsd } = options;
|
|
1116
1075
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1117
|
-
const account =
|
|
1076
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
1118
1077
|
const walletAddress = account.address;
|
|
1119
1078
|
const challengeResponse = await fetch(
|
|
1120
1079
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=withdraw`
|
|
@@ -1124,7 +1083,7 @@ var AgentWallet = class {
|
|
|
1124
1083
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
1125
1084
|
}
|
|
1126
1085
|
const { challenge, message } = await challengeResponse.json();
|
|
1127
|
-
const signature = await
|
|
1086
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
1128
1087
|
const withdrawResponse = await fetch(`${baseUrl}/api/v1/agent/withdraw`, {
|
|
1129
1088
|
method: "POST",
|
|
1130
1089
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1180,7 +1139,7 @@ var AgentWallet = class {
|
|
|
1180
1139
|
static async claimInvite(options) {
|
|
1181
1140
|
const { inviteCode, privateKey } = options;
|
|
1182
1141
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1183
|
-
const account =
|
|
1142
|
+
const account = accounts.privateKeyToAccount(privateKey);
|
|
1184
1143
|
const walletAddress = account.address;
|
|
1185
1144
|
const challengeResponse = await fetch(
|
|
1186
1145
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=claim-invite`
|
|
@@ -1190,7 +1149,7 @@ var AgentWallet = class {
|
|
|
1190
1149
|
throw new MixrPayError(error.error || `Failed to get challenge: ${challengeResponse.status}`);
|
|
1191
1150
|
}
|
|
1192
1151
|
const { challenge, message } = await challengeResponse.json();
|
|
1193
|
-
const signature = await
|
|
1152
|
+
const signature = await accounts.signMessage({ message, privateKey });
|
|
1194
1153
|
const claimResponse = await fetch(`${baseUrl}/api/v1/agent/claim-invite`, {
|
|
1195
1154
|
method: "POST",
|
|
1196
1155
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1240,7 +1199,7 @@ var AgentWallet = class {
|
|
|
1240
1199
|
* Spawn a child invite for sub-agents.
|
|
1241
1200
|
*
|
|
1242
1201
|
* Allows an agent to create an invite code for a sub-agent with a portion
|
|
1243
|
-
* of their remaining budget
|
|
1202
|
+
* of their remaining budget. The child inherits merchant restrictions
|
|
1244
1203
|
* and cannot outlive the parent session.
|
|
1245
1204
|
*
|
|
1246
1205
|
* @param options - Spawn options
|
|
@@ -1254,7 +1213,7 @@ var AgentWallet = class {
|
|
|
1254
1213
|
*
|
|
1255
1214
|
* // Spawn a child invite for a sub-agent
|
|
1256
1215
|
* const childInvite = await wallet.spawnChildInvite({
|
|
1257
|
-
* budgetUsd: 10.00,
|
|
1216
|
+
* budgetUsd: 10.00,
|
|
1258
1217
|
* name: 'Research Sub-Agent',
|
|
1259
1218
|
* allowedMerchants: ['firecrawl.dev'], // Must be subset of parent
|
|
1260
1219
|
* expiresInDays: 7, // Will be capped to parent's expiry
|
|
@@ -1269,7 +1228,7 @@ var AgentWallet = class {
|
|
|
1269
1228
|
const timestamp = Date.now();
|
|
1270
1229
|
const nonce = crypto.randomUUID();
|
|
1271
1230
|
const message = `spawn:${timestamp}:${nonce}`;
|
|
1272
|
-
const signature = await
|
|
1231
|
+
const signature = await accounts.signMessage({
|
|
1273
1232
|
message,
|
|
1274
1233
|
privateKey: this.sessionKey.rawPrivateKey
|
|
1275
1234
|
});
|
|
@@ -1310,8 +1269,7 @@ var AgentWallet = class {
|
|
|
1310
1269
|
/**
|
|
1311
1270
|
* Get available budget information for spawning.
|
|
1312
1271
|
*
|
|
1313
|
-
* Returns the current budget status including
|
|
1314
|
-
* to child agents (20% of available).
|
|
1272
|
+
* Returns the current budget status including spawn availability.
|
|
1315
1273
|
*
|
|
1316
1274
|
* @returns Budget information
|
|
1317
1275
|
*
|
|
@@ -2723,6 +2681,75 @@ Timestamp: ${timestamp}`;
|
|
|
2723
2681
|
return this.parseJitInstance(data.instance);
|
|
2724
2682
|
}
|
|
2725
2683
|
// ===========================================================================
|
|
2684
|
+
// Transaction Execution
|
|
2685
|
+
// ===========================================================================
|
|
2686
|
+
/**
|
|
2687
|
+
* Execute an on-chain transaction from the human's wallet.
|
|
2688
|
+
*
|
|
2689
|
+
* Submits arbitrary calldata to any contract, bounded by the session key's
|
|
2690
|
+
* budget limits (max_total, max_per_tx, max_daily). The platform validates
|
|
2691
|
+
* the budget, executes the transaction, and records a charge.
|
|
2692
|
+
*
|
|
2693
|
+
* @param params - Transaction parameters
|
|
2694
|
+
* @returns Transaction result with hash and remaining budget
|
|
2695
|
+
* @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
|
|
2696
|
+
*
|
|
2697
|
+
* @example
|
|
2698
|
+
* ```typescript
|
|
2699
|
+
* // Bridge USDC via deBridge
|
|
2700
|
+
* const quote = await deBridgeMcp.create_tx({ ... });
|
|
2701
|
+
* const result = await wallet.executeTransaction({
|
|
2702
|
+
* to: quote.contractAddress,
|
|
2703
|
+
* data: quote.calldata,
|
|
2704
|
+
* estimatedCostUsd: 25.0,
|
|
2705
|
+
* description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
|
|
2706
|
+
* });
|
|
2707
|
+
* console.log('TX:', result.txHash);
|
|
2708
|
+
* console.log('Budget remaining:', result.remainingBudgetUsd);
|
|
2709
|
+
* ```
|
|
2710
|
+
*/
|
|
2711
|
+
async executeTransaction(params) {
|
|
2712
|
+
this.logger.debug("executeTransaction", { to: params.to, estimatedCostUsd: params.estimatedCostUsd });
|
|
2713
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2714
|
+
const response = await fetch(`${this.baseUrl}/api/v2/tx/execute`, {
|
|
2715
|
+
method: "POST",
|
|
2716
|
+
headers: {
|
|
2717
|
+
"Content-Type": "application/json",
|
|
2718
|
+
...authHeaders
|
|
2719
|
+
},
|
|
2720
|
+
body: JSON.stringify({
|
|
2721
|
+
to: params.to,
|
|
2722
|
+
data: params.data,
|
|
2723
|
+
value: params.value?.toString() ?? "0",
|
|
2724
|
+
chain_id: params.chainId,
|
|
2725
|
+
estimated_cost_usd: params.estimatedCostUsd,
|
|
2726
|
+
description: params.description,
|
|
2727
|
+
idempotency_key: params.idempotencyKey
|
|
2728
|
+
})
|
|
2729
|
+
});
|
|
2730
|
+
const result = await response.json().catch(() => ({}));
|
|
2731
|
+
if (!response.ok) {
|
|
2732
|
+
const errorCode = result.error_code || "TX_FAILED";
|
|
2733
|
+
const errorMessage = result.error || `Transaction execution failed: ${response.status}`;
|
|
2734
|
+
if (errorCode === "BUDGET_EXCEEDED") {
|
|
2735
|
+
throw new MixrPayError(errorMessage, "SPENDING_LIMIT_EXCEEDED");
|
|
2736
|
+
}
|
|
2737
|
+
throw new MixrPayError(errorMessage, errorCode);
|
|
2738
|
+
}
|
|
2739
|
+
this.logger.info("Transaction executed", {
|
|
2740
|
+
txHash: result.tx_hash,
|
|
2741
|
+
estimatedCostUsd: params.estimatedCostUsd,
|
|
2742
|
+
remainingBudgetUsd: result.remaining_budget_usd
|
|
2743
|
+
});
|
|
2744
|
+
return {
|
|
2745
|
+
success: true,
|
|
2746
|
+
txHash: result.tx_hash,
|
|
2747
|
+
chargeId: result.charge_id,
|
|
2748
|
+
estimatedCostUsd: result.estimated_cost_usd,
|
|
2749
|
+
remainingBudgetUsd: result.remaining_budget_usd
|
|
2750
|
+
};
|
|
2751
|
+
}
|
|
2752
|
+
// ===========================================================================
|
|
2726
2753
|
// Skills Methods
|
|
2727
2754
|
// ===========================================================================
|
|
2728
2755
|
/**
|
|
@@ -2861,7 +2888,7 @@ Timestamp: ${timestamp}`;
|
|
|
2861
2888
|
);
|
|
2862
2889
|
}
|
|
2863
2890
|
const data = await response.json();
|
|
2864
|
-
const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
|
|
2891
|
+
const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app.toLowerCase());
|
|
2865
2892
|
return {
|
|
2866
2893
|
connected: connectedAppNames,
|
|
2867
2894
|
connections: data.connections || [],
|
|
@@ -4604,11 +4631,11 @@ Timestamp: ${timestamp}`;
|
|
|
4604
4631
|
...init.headers
|
|
4605
4632
|
};
|
|
4606
4633
|
if (this.sessionKey) {
|
|
4607
|
-
const account =
|
|
4634
|
+
const account = accounts.privateKeyToAccount(this.sessionKey.rawPrivateKey);
|
|
4608
4635
|
const address = account.address.toLowerCase();
|
|
4609
4636
|
const timestamp = Date.now();
|
|
4610
4637
|
const message = `MixrPay:${timestamp}:${address}`;
|
|
4611
|
-
const signature = await
|
|
4638
|
+
const signature = await accounts.signMessage({
|
|
4612
4639
|
message,
|
|
4613
4640
|
privateKey: this.sessionKey.rawPrivateKey
|
|
4614
4641
|
});
|
|
@@ -4624,22 +4651,20 @@ Timestamp: ${timestamp}`;
|
|
|
4624
4651
|
});
|
|
4625
4652
|
}
|
|
4626
4653
|
};
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
isMixrPayError
|
|
4645
|
-
});
|
|
4654
|
+
|
|
4655
|
+
exports.AgentWallet = AgentWallet;
|
|
4656
|
+
exports.InsufficientBalanceError = InsufficientBalanceError;
|
|
4657
|
+
exports.InvalidSessionKeyError = InvalidSessionKeyError;
|
|
4658
|
+
exports.MerchantNotAllowedError = MerchantNotAllowedError;
|
|
4659
|
+
exports.MixrPayError = MixrPayError;
|
|
4660
|
+
exports.PaymentFailedError = PaymentFailedError;
|
|
4661
|
+
exports.SDK_VERSION = SDK_VERSION;
|
|
4662
|
+
exports.SessionExpiredError = SessionExpiredError;
|
|
4663
|
+
exports.SessionKeyExpiredError = SessionKeyExpiredError;
|
|
4664
|
+
exports.SessionLimitExceededError = SessionLimitExceededError;
|
|
4665
|
+
exports.SessionNotFoundError = SessionNotFoundError;
|
|
4666
|
+
exports.SessionRevokedError = SessionRevokedError;
|
|
4667
|
+
exports.SpendingLimitExceededError = SpendingLimitExceededError;
|
|
4668
|
+
exports.X402ProtocolError = X402ProtocolError;
|
|
4669
|
+
exports.getErrorMessage = getErrorMessage;
|
|
4670
|
+
exports.isMixrPayError = isMixrPayError;
|
package/dist/index.d.cts
CHANGED
|
@@ -557,7 +557,7 @@ interface AgentClaimInviteResult {
|
|
|
557
557
|
* Options for spawning a child invite
|
|
558
558
|
*/
|
|
559
559
|
interface SpawnChildOptions {
|
|
560
|
-
/** Budget in USD for the child (
|
|
560
|
+
/** Budget in USD for the child (subject to platform limits) */
|
|
561
561
|
budgetUsd: number;
|
|
562
562
|
/** Name for the child invite */
|
|
563
563
|
name: string;
|
|
@@ -574,13 +574,13 @@ interface SpawnChildResult {
|
|
|
574
574
|
inviteCode: string;
|
|
575
575
|
/** Database ID of the invite */
|
|
576
576
|
inviteId: string;
|
|
577
|
-
/** Actual budget (may be less than requested due to
|
|
577
|
+
/** Actual budget (may be less than requested due to platform limits) */
|
|
578
578
|
budgetUsd: number;
|
|
579
579
|
/** When the invite expires */
|
|
580
580
|
expiresAt: Date;
|
|
581
581
|
/** Depth in hierarchy (1 = child, 2 = grandchild, etc.) */
|
|
582
582
|
depth: number;
|
|
583
|
-
/** How much this child can spawn
|
|
583
|
+
/** How much this child can spawn */
|
|
584
584
|
maxSpawnBudget: number;
|
|
585
585
|
/** Allowed merchants for this child */
|
|
586
586
|
allowedMerchants: string[];
|
|
@@ -597,9 +597,9 @@ interface AvailableBudget {
|
|
|
597
597
|
allocatedToChildren: number;
|
|
598
598
|
/** Available for spending or spawning */
|
|
599
599
|
available: number;
|
|
600
|
-
/** Maximum budget for next spawn
|
|
600
|
+
/** Maximum budget for next spawn */
|
|
601
601
|
maxSpawnBudget: number;
|
|
602
|
-
/** Whether spawning is allowed
|
|
602
|
+
/** Whether spawning is allowed */
|
|
603
603
|
canSpawn: boolean;
|
|
604
604
|
}
|
|
605
605
|
/**
|
|
@@ -748,7 +748,7 @@ declare class AgentWallet {
|
|
|
748
748
|
/**
|
|
749
749
|
* Register a new agent with MixrPay.
|
|
750
750
|
*
|
|
751
|
-
* This creates a
|
|
751
|
+
* This creates a platform-managed embedded wallet for the agent's payments.
|
|
752
752
|
* The agent proves ownership of their external wallet by signing a challenge.
|
|
753
753
|
*
|
|
754
754
|
* @param options - Registration options including the private key
|
|
@@ -786,7 +786,7 @@ declare class AgentWallet {
|
|
|
786
786
|
healthy: boolean;
|
|
787
787
|
database: string;
|
|
788
788
|
agentRegistrationAvailable: boolean;
|
|
789
|
-
|
|
789
|
+
walletServiceConfigured: boolean;
|
|
790
790
|
error?: string;
|
|
791
791
|
}>;
|
|
792
792
|
/**
|
|
@@ -916,7 +916,7 @@ declare class AgentWallet {
|
|
|
916
916
|
* Spawn a child invite for sub-agents.
|
|
917
917
|
*
|
|
918
918
|
* Allows an agent to create an invite code for a sub-agent with a portion
|
|
919
|
-
* of their remaining budget
|
|
919
|
+
* of their remaining budget. The child inherits merchant restrictions
|
|
920
920
|
* and cannot outlive the parent session.
|
|
921
921
|
*
|
|
922
922
|
* @param options - Spawn options
|
|
@@ -930,7 +930,7 @@ declare class AgentWallet {
|
|
|
930
930
|
*
|
|
931
931
|
* // Spawn a child invite for a sub-agent
|
|
932
932
|
* const childInvite = await wallet.spawnChildInvite({
|
|
933
|
-
* budgetUsd: 10.00,
|
|
933
|
+
* budgetUsd: 10.00,
|
|
934
934
|
* name: 'Research Sub-Agent',
|
|
935
935
|
* allowedMerchants: ['firecrawl.dev'], // Must be subset of parent
|
|
936
936
|
* expiresInDays: 7, // Will be capped to parent's expiry
|
|
@@ -944,8 +944,7 @@ declare class AgentWallet {
|
|
|
944
944
|
/**
|
|
945
945
|
* Get available budget information for spawning.
|
|
946
946
|
*
|
|
947
|
-
* Returns the current budget status including
|
|
948
|
-
* to child agents (20% of available).
|
|
947
|
+
* Returns the current budget status including spawn availability.
|
|
949
948
|
*
|
|
950
949
|
* @returns Budget information
|
|
951
950
|
*
|
|
@@ -1459,6 +1458,46 @@ declare class AgentWallet {
|
|
|
1459
1458
|
* ```
|
|
1460
1459
|
*/
|
|
1461
1460
|
getJitInstance(instanceId: string): Promise<JitInstance>;
|
|
1461
|
+
/**
|
|
1462
|
+
* Execute an on-chain transaction from the human's wallet.
|
|
1463
|
+
*
|
|
1464
|
+
* Submits arbitrary calldata to any contract, bounded by the session key's
|
|
1465
|
+
* budget limits (max_total, max_per_tx, max_daily). The platform validates
|
|
1466
|
+
* the budget, executes the transaction, and records a charge.
|
|
1467
|
+
*
|
|
1468
|
+
* @param params - Transaction parameters
|
|
1469
|
+
* @returns Transaction result with hash and remaining budget
|
|
1470
|
+
* @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
|
|
1471
|
+
*
|
|
1472
|
+
* @example
|
|
1473
|
+
* ```typescript
|
|
1474
|
+
* // Bridge USDC via deBridge
|
|
1475
|
+
* const quote = await deBridgeMcp.create_tx({ ... });
|
|
1476
|
+
* const result = await wallet.executeTransaction({
|
|
1477
|
+
* to: quote.contractAddress,
|
|
1478
|
+
* data: quote.calldata,
|
|
1479
|
+
* estimatedCostUsd: 25.0,
|
|
1480
|
+
* description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
|
|
1481
|
+
* });
|
|
1482
|
+
* console.log('TX:', result.txHash);
|
|
1483
|
+
* console.log('Budget remaining:', result.remainingBudgetUsd);
|
|
1484
|
+
* ```
|
|
1485
|
+
*/
|
|
1486
|
+
executeTransaction(params: {
|
|
1487
|
+
to: `0x${string}`;
|
|
1488
|
+
data: `0x${string}`;
|
|
1489
|
+
value?: bigint;
|
|
1490
|
+
chainId?: number;
|
|
1491
|
+
estimatedCostUsd: number;
|
|
1492
|
+
description?: string;
|
|
1493
|
+
idempotencyKey?: string;
|
|
1494
|
+
}): Promise<{
|
|
1495
|
+
success: boolean;
|
|
1496
|
+
txHash: string;
|
|
1497
|
+
chargeId: string;
|
|
1498
|
+
estimatedCostUsd: number;
|
|
1499
|
+
remainingBudgetUsd: number | null;
|
|
1500
|
+
}>;
|
|
1462
1501
|
/**
|
|
1463
1502
|
* Use a configured skill by deploying a JIT MCP server with your saved API keys.
|
|
1464
1503
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -557,7 +557,7 @@ interface AgentClaimInviteResult {
|
|
|
557
557
|
* Options for spawning a child invite
|
|
558
558
|
*/
|
|
559
559
|
interface SpawnChildOptions {
|
|
560
|
-
/** Budget in USD for the child (
|
|
560
|
+
/** Budget in USD for the child (subject to platform limits) */
|
|
561
561
|
budgetUsd: number;
|
|
562
562
|
/** Name for the child invite */
|
|
563
563
|
name: string;
|
|
@@ -574,13 +574,13 @@ interface SpawnChildResult {
|
|
|
574
574
|
inviteCode: string;
|
|
575
575
|
/** Database ID of the invite */
|
|
576
576
|
inviteId: string;
|
|
577
|
-
/** Actual budget (may be less than requested due to
|
|
577
|
+
/** Actual budget (may be less than requested due to platform limits) */
|
|
578
578
|
budgetUsd: number;
|
|
579
579
|
/** When the invite expires */
|
|
580
580
|
expiresAt: Date;
|
|
581
581
|
/** Depth in hierarchy (1 = child, 2 = grandchild, etc.) */
|
|
582
582
|
depth: number;
|
|
583
|
-
/** How much this child can spawn
|
|
583
|
+
/** How much this child can spawn */
|
|
584
584
|
maxSpawnBudget: number;
|
|
585
585
|
/** Allowed merchants for this child */
|
|
586
586
|
allowedMerchants: string[];
|
|
@@ -597,9 +597,9 @@ interface AvailableBudget {
|
|
|
597
597
|
allocatedToChildren: number;
|
|
598
598
|
/** Available for spending or spawning */
|
|
599
599
|
available: number;
|
|
600
|
-
/** Maximum budget for next spawn
|
|
600
|
+
/** Maximum budget for next spawn */
|
|
601
601
|
maxSpawnBudget: number;
|
|
602
|
-
/** Whether spawning is allowed
|
|
602
|
+
/** Whether spawning is allowed */
|
|
603
603
|
canSpawn: boolean;
|
|
604
604
|
}
|
|
605
605
|
/**
|
|
@@ -748,7 +748,7 @@ declare class AgentWallet {
|
|
|
748
748
|
/**
|
|
749
749
|
* Register a new agent with MixrPay.
|
|
750
750
|
*
|
|
751
|
-
* This creates a
|
|
751
|
+
* This creates a platform-managed embedded wallet for the agent's payments.
|
|
752
752
|
* The agent proves ownership of their external wallet by signing a challenge.
|
|
753
753
|
*
|
|
754
754
|
* @param options - Registration options including the private key
|
|
@@ -786,7 +786,7 @@ declare class AgentWallet {
|
|
|
786
786
|
healthy: boolean;
|
|
787
787
|
database: string;
|
|
788
788
|
agentRegistrationAvailable: boolean;
|
|
789
|
-
|
|
789
|
+
walletServiceConfigured: boolean;
|
|
790
790
|
error?: string;
|
|
791
791
|
}>;
|
|
792
792
|
/**
|
|
@@ -916,7 +916,7 @@ declare class AgentWallet {
|
|
|
916
916
|
* Spawn a child invite for sub-agents.
|
|
917
917
|
*
|
|
918
918
|
* Allows an agent to create an invite code for a sub-agent with a portion
|
|
919
|
-
* of their remaining budget
|
|
919
|
+
* of their remaining budget. The child inherits merchant restrictions
|
|
920
920
|
* and cannot outlive the parent session.
|
|
921
921
|
*
|
|
922
922
|
* @param options - Spawn options
|
|
@@ -930,7 +930,7 @@ declare class AgentWallet {
|
|
|
930
930
|
*
|
|
931
931
|
* // Spawn a child invite for a sub-agent
|
|
932
932
|
* const childInvite = await wallet.spawnChildInvite({
|
|
933
|
-
* budgetUsd: 10.00,
|
|
933
|
+
* budgetUsd: 10.00,
|
|
934
934
|
* name: 'Research Sub-Agent',
|
|
935
935
|
* allowedMerchants: ['firecrawl.dev'], // Must be subset of parent
|
|
936
936
|
* expiresInDays: 7, // Will be capped to parent's expiry
|
|
@@ -944,8 +944,7 @@ declare class AgentWallet {
|
|
|
944
944
|
/**
|
|
945
945
|
* Get available budget information for spawning.
|
|
946
946
|
*
|
|
947
|
-
* Returns the current budget status including
|
|
948
|
-
* to child agents (20% of available).
|
|
947
|
+
* Returns the current budget status including spawn availability.
|
|
949
948
|
*
|
|
950
949
|
* @returns Budget information
|
|
951
950
|
*
|
|
@@ -1459,6 +1458,46 @@ declare class AgentWallet {
|
|
|
1459
1458
|
* ```
|
|
1460
1459
|
*/
|
|
1461
1460
|
getJitInstance(instanceId: string): Promise<JitInstance>;
|
|
1461
|
+
/**
|
|
1462
|
+
* Execute an on-chain transaction from the human's wallet.
|
|
1463
|
+
*
|
|
1464
|
+
* Submits arbitrary calldata to any contract, bounded by the session key's
|
|
1465
|
+
* budget limits (max_total, max_per_tx, max_daily). The platform validates
|
|
1466
|
+
* the budget, executes the transaction, and records a charge.
|
|
1467
|
+
*
|
|
1468
|
+
* @param params - Transaction parameters
|
|
1469
|
+
* @returns Transaction result with hash and remaining budget
|
|
1470
|
+
* @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
|
|
1471
|
+
*
|
|
1472
|
+
* @example
|
|
1473
|
+
* ```typescript
|
|
1474
|
+
* // Bridge USDC via deBridge
|
|
1475
|
+
* const quote = await deBridgeMcp.create_tx({ ... });
|
|
1476
|
+
* const result = await wallet.executeTransaction({
|
|
1477
|
+
* to: quote.contractAddress,
|
|
1478
|
+
* data: quote.calldata,
|
|
1479
|
+
* estimatedCostUsd: 25.0,
|
|
1480
|
+
* description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
|
|
1481
|
+
* });
|
|
1482
|
+
* console.log('TX:', result.txHash);
|
|
1483
|
+
* console.log('Budget remaining:', result.remainingBudgetUsd);
|
|
1484
|
+
* ```
|
|
1485
|
+
*/
|
|
1486
|
+
executeTransaction(params: {
|
|
1487
|
+
to: `0x${string}`;
|
|
1488
|
+
data: `0x${string}`;
|
|
1489
|
+
value?: bigint;
|
|
1490
|
+
chainId?: number;
|
|
1491
|
+
estimatedCostUsd: number;
|
|
1492
|
+
description?: string;
|
|
1493
|
+
idempotencyKey?: string;
|
|
1494
|
+
}): Promise<{
|
|
1495
|
+
success: boolean;
|
|
1496
|
+
txHash: string;
|
|
1497
|
+
chargeId: string;
|
|
1498
|
+
estimatedCostUsd: number;
|
|
1499
|
+
remainingBudgetUsd: number | null;
|
|
1500
|
+
}>;
|
|
1462
1501
|
/**
|
|
1463
1502
|
* Use a configured skill by deploying a JIT MCP server with your saved API keys.
|
|
1464
1503
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
+
import { privateKeyToAccount, signMessage, signTypedData } from 'viem/accounts';
|
|
2
|
+
|
|
1
3
|
// src/session-key.ts
|
|
2
|
-
import {
|
|
3
|
-
privateKeyToAccount,
|
|
4
|
-
signTypedData,
|
|
5
|
-
signMessage as viemSignMessage
|
|
6
|
-
} from "viem/accounts";
|
|
7
4
|
|
|
8
5
|
// src/errors.ts
|
|
9
6
|
var MixrPayError = class extends Error {
|
|
@@ -352,7 +349,7 @@ var SessionKey = class _SessionKey {
|
|
|
352
349
|
* @returns Hex-encoded signature
|
|
353
350
|
*/
|
|
354
351
|
async signMessage(message) {
|
|
355
|
-
return
|
|
352
|
+
return signMessage({
|
|
356
353
|
privateKey: this.privateKey,
|
|
357
354
|
message
|
|
358
355
|
});
|
|
@@ -403,9 +400,6 @@ async function createSessionAuthPayload(sessionKey) {
|
|
|
403
400
|
};
|
|
404
401
|
}
|
|
405
402
|
|
|
406
|
-
// src/agent-wallet.ts
|
|
407
|
-
import { privateKeyToAccount as privateKeyToAccount2, signMessage } from "viem/accounts";
|
|
408
|
-
|
|
409
403
|
// src/x402.ts
|
|
410
404
|
async function parse402Response(response) {
|
|
411
405
|
let paymentData = null;
|
|
@@ -767,7 +761,7 @@ var AgentWallet = class {
|
|
|
767
761
|
/**
|
|
768
762
|
* Register a new agent with MixrPay.
|
|
769
763
|
*
|
|
770
|
-
* This creates a
|
|
764
|
+
* This creates a platform-managed embedded wallet for the agent's payments.
|
|
771
765
|
* The agent proves ownership of their external wallet by signing a challenge.
|
|
772
766
|
*
|
|
773
767
|
* @param options - Registration options including the private key
|
|
@@ -787,7 +781,7 @@ var AgentWallet = class {
|
|
|
787
781
|
static async register(options) {
|
|
788
782
|
const { privateKey, name } = options;
|
|
789
783
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
790
|
-
const account =
|
|
784
|
+
const account = privateKeyToAccount(privateKey);
|
|
791
785
|
const walletAddress = account.address;
|
|
792
786
|
const challengeResponse = await fetch(
|
|
793
787
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=register`
|
|
@@ -855,7 +849,7 @@ var AgentWallet = class {
|
|
|
855
849
|
healthy: false,
|
|
856
850
|
database: "unknown",
|
|
857
851
|
agentRegistrationAvailable: false,
|
|
858
|
-
|
|
852
|
+
walletServiceConfigured: false,
|
|
859
853
|
error: `Health check failed with status ${response.status}`
|
|
860
854
|
};
|
|
861
855
|
}
|
|
@@ -864,14 +858,14 @@ var AgentWallet = class {
|
|
|
864
858
|
healthy: data.status === "ready",
|
|
865
859
|
database: data.database || "unknown",
|
|
866
860
|
agentRegistrationAvailable: data.services?.agentRegistration?.available ?? false,
|
|
867
|
-
|
|
861
|
+
walletServiceConfigured: data.services?.wallet?.configured ?? data.services?.privy?.configured ?? false
|
|
868
862
|
};
|
|
869
863
|
} catch (error) {
|
|
870
864
|
return {
|
|
871
865
|
healthy: false,
|
|
872
866
|
database: "unreachable",
|
|
873
867
|
agentRegistrationAvailable: false,
|
|
874
|
-
|
|
868
|
+
walletServiceConfigured: false,
|
|
875
869
|
error: error instanceof Error ? error.message : "Failed to reach server"
|
|
876
870
|
};
|
|
877
871
|
}
|
|
@@ -904,7 +898,7 @@ var AgentWallet = class {
|
|
|
904
898
|
static async getSessionKey(options) {
|
|
905
899
|
const { privateKey, spendingLimitUsd, maxPerTxUsd, maxDailyUsd, durationDays } = options;
|
|
906
900
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
907
|
-
const account =
|
|
901
|
+
const account = privateKeyToAccount(privateKey);
|
|
908
902
|
const walletAddress = account.address;
|
|
909
903
|
const challengeResponse = await fetch(
|
|
910
904
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=session-key`
|
|
@@ -967,7 +961,7 @@ var AgentWallet = class {
|
|
|
967
961
|
static async getStatus(options) {
|
|
968
962
|
const { privateKey } = options;
|
|
969
963
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
970
|
-
const account =
|
|
964
|
+
const account = privateKeyToAccount(privateKey);
|
|
971
965
|
const walletAddress = account.address;
|
|
972
966
|
const challengeResponse = await fetch(
|
|
973
967
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=status`
|
|
@@ -1023,7 +1017,7 @@ var AgentWallet = class {
|
|
|
1023
1017
|
static async revokeSessionKey(options) {
|
|
1024
1018
|
const { privateKey, sessionKeyId } = options;
|
|
1025
1019
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1026
|
-
const account =
|
|
1020
|
+
const account = privateKeyToAccount(privateKey);
|
|
1027
1021
|
const walletAddress = account.address;
|
|
1028
1022
|
const challengeResponse = await fetch(
|
|
1029
1023
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=revoke`
|
|
@@ -1077,7 +1071,7 @@ var AgentWallet = class {
|
|
|
1077
1071
|
static async withdraw(options) {
|
|
1078
1072
|
const { privateKey, amountUsd } = options;
|
|
1079
1073
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1080
|
-
const account =
|
|
1074
|
+
const account = privateKeyToAccount(privateKey);
|
|
1081
1075
|
const walletAddress = account.address;
|
|
1082
1076
|
const challengeResponse = await fetch(
|
|
1083
1077
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=withdraw`
|
|
@@ -1143,7 +1137,7 @@ var AgentWallet = class {
|
|
|
1143
1137
|
static async claimInvite(options) {
|
|
1144
1138
|
const { inviteCode, privateKey } = options;
|
|
1145
1139
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
1146
|
-
const account =
|
|
1140
|
+
const account = privateKeyToAccount(privateKey);
|
|
1147
1141
|
const walletAddress = account.address;
|
|
1148
1142
|
const challengeResponse = await fetch(
|
|
1149
1143
|
`${baseUrl}/api/v1/agent/challenge?wallet=${walletAddress}&action=claim-invite`
|
|
@@ -1203,7 +1197,7 @@ var AgentWallet = class {
|
|
|
1203
1197
|
* Spawn a child invite for sub-agents.
|
|
1204
1198
|
*
|
|
1205
1199
|
* Allows an agent to create an invite code for a sub-agent with a portion
|
|
1206
|
-
* of their remaining budget
|
|
1200
|
+
* of their remaining budget. The child inherits merchant restrictions
|
|
1207
1201
|
* and cannot outlive the parent session.
|
|
1208
1202
|
*
|
|
1209
1203
|
* @param options - Spawn options
|
|
@@ -1217,7 +1211,7 @@ var AgentWallet = class {
|
|
|
1217
1211
|
*
|
|
1218
1212
|
* // Spawn a child invite for a sub-agent
|
|
1219
1213
|
* const childInvite = await wallet.spawnChildInvite({
|
|
1220
|
-
* budgetUsd: 10.00,
|
|
1214
|
+
* budgetUsd: 10.00,
|
|
1221
1215
|
* name: 'Research Sub-Agent',
|
|
1222
1216
|
* allowedMerchants: ['firecrawl.dev'], // Must be subset of parent
|
|
1223
1217
|
* expiresInDays: 7, // Will be capped to parent's expiry
|
|
@@ -1273,8 +1267,7 @@ var AgentWallet = class {
|
|
|
1273
1267
|
/**
|
|
1274
1268
|
* Get available budget information for spawning.
|
|
1275
1269
|
*
|
|
1276
|
-
* Returns the current budget status including
|
|
1277
|
-
* to child agents (20% of available).
|
|
1270
|
+
* Returns the current budget status including spawn availability.
|
|
1278
1271
|
*
|
|
1279
1272
|
* @returns Budget information
|
|
1280
1273
|
*
|
|
@@ -2686,6 +2679,75 @@ Timestamp: ${timestamp}`;
|
|
|
2686
2679
|
return this.parseJitInstance(data.instance);
|
|
2687
2680
|
}
|
|
2688
2681
|
// ===========================================================================
|
|
2682
|
+
// Transaction Execution
|
|
2683
|
+
// ===========================================================================
|
|
2684
|
+
/**
|
|
2685
|
+
* Execute an on-chain transaction from the human's wallet.
|
|
2686
|
+
*
|
|
2687
|
+
* Submits arbitrary calldata to any contract, bounded by the session key's
|
|
2688
|
+
* budget limits (max_total, max_per_tx, max_daily). The platform validates
|
|
2689
|
+
* the budget, executes the transaction, and records a charge.
|
|
2690
|
+
*
|
|
2691
|
+
* @param params - Transaction parameters
|
|
2692
|
+
* @returns Transaction result with hash and remaining budget
|
|
2693
|
+
* @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
|
|
2694
|
+
*
|
|
2695
|
+
* @example
|
|
2696
|
+
* ```typescript
|
|
2697
|
+
* // Bridge USDC via deBridge
|
|
2698
|
+
* const quote = await deBridgeMcp.create_tx({ ... });
|
|
2699
|
+
* const result = await wallet.executeTransaction({
|
|
2700
|
+
* to: quote.contractAddress,
|
|
2701
|
+
* data: quote.calldata,
|
|
2702
|
+
* estimatedCostUsd: 25.0,
|
|
2703
|
+
* description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
|
|
2704
|
+
* });
|
|
2705
|
+
* console.log('TX:', result.txHash);
|
|
2706
|
+
* console.log('Budget remaining:', result.remainingBudgetUsd);
|
|
2707
|
+
* ```
|
|
2708
|
+
*/
|
|
2709
|
+
async executeTransaction(params) {
|
|
2710
|
+
this.logger.debug("executeTransaction", { to: params.to, estimatedCostUsd: params.estimatedCostUsd });
|
|
2711
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2712
|
+
const response = await fetch(`${this.baseUrl}/api/v2/tx/execute`, {
|
|
2713
|
+
method: "POST",
|
|
2714
|
+
headers: {
|
|
2715
|
+
"Content-Type": "application/json",
|
|
2716
|
+
...authHeaders
|
|
2717
|
+
},
|
|
2718
|
+
body: JSON.stringify({
|
|
2719
|
+
to: params.to,
|
|
2720
|
+
data: params.data,
|
|
2721
|
+
value: params.value?.toString() ?? "0",
|
|
2722
|
+
chain_id: params.chainId,
|
|
2723
|
+
estimated_cost_usd: params.estimatedCostUsd,
|
|
2724
|
+
description: params.description,
|
|
2725
|
+
idempotency_key: params.idempotencyKey
|
|
2726
|
+
})
|
|
2727
|
+
});
|
|
2728
|
+
const result = await response.json().catch(() => ({}));
|
|
2729
|
+
if (!response.ok) {
|
|
2730
|
+
const errorCode = result.error_code || "TX_FAILED";
|
|
2731
|
+
const errorMessage = result.error || `Transaction execution failed: ${response.status}`;
|
|
2732
|
+
if (errorCode === "BUDGET_EXCEEDED") {
|
|
2733
|
+
throw new MixrPayError(errorMessage, "SPENDING_LIMIT_EXCEEDED");
|
|
2734
|
+
}
|
|
2735
|
+
throw new MixrPayError(errorMessage, errorCode);
|
|
2736
|
+
}
|
|
2737
|
+
this.logger.info("Transaction executed", {
|
|
2738
|
+
txHash: result.tx_hash,
|
|
2739
|
+
estimatedCostUsd: params.estimatedCostUsd,
|
|
2740
|
+
remainingBudgetUsd: result.remaining_budget_usd
|
|
2741
|
+
});
|
|
2742
|
+
return {
|
|
2743
|
+
success: true,
|
|
2744
|
+
txHash: result.tx_hash,
|
|
2745
|
+
chargeId: result.charge_id,
|
|
2746
|
+
estimatedCostUsd: result.estimated_cost_usd,
|
|
2747
|
+
remainingBudgetUsd: result.remaining_budget_usd
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
// ===========================================================================
|
|
2689
2751
|
// Skills Methods
|
|
2690
2752
|
// ===========================================================================
|
|
2691
2753
|
/**
|
|
@@ -2824,7 +2886,7 @@ Timestamp: ${timestamp}`;
|
|
|
2824
2886
|
);
|
|
2825
2887
|
}
|
|
2826
2888
|
const data = await response.json();
|
|
2827
|
-
const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
|
|
2889
|
+
const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app.toLowerCase());
|
|
2828
2890
|
return {
|
|
2829
2891
|
connected: connectedAppNames,
|
|
2830
2892
|
connections: data.connections || [],
|
|
@@ -4567,7 +4629,7 @@ Timestamp: ${timestamp}`;
|
|
|
4567
4629
|
...init.headers
|
|
4568
4630
|
};
|
|
4569
4631
|
if (this.sessionKey) {
|
|
4570
|
-
const account =
|
|
4632
|
+
const account = privateKeyToAccount(this.sessionKey.rawPrivateKey);
|
|
4571
4633
|
const address = account.address.toLowerCase();
|
|
4572
4634
|
const timestamp = Date.now();
|
|
4573
4635
|
const message = `MixrPay:${timestamp}:${address}`;
|
|
@@ -4587,21 +4649,5 @@ Timestamp: ${timestamp}`;
|
|
|
4587
4649
|
});
|
|
4588
4650
|
}
|
|
4589
4651
|
};
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
InsufficientBalanceError,
|
|
4593
|
-
InvalidSessionKeyError,
|
|
4594
|
-
MerchantNotAllowedError,
|
|
4595
|
-
MixrPayError,
|
|
4596
|
-
PaymentFailedError,
|
|
4597
|
-
SDK_VERSION,
|
|
4598
|
-
SessionExpiredError,
|
|
4599
|
-
SessionKeyExpiredError,
|
|
4600
|
-
SessionLimitExceededError,
|
|
4601
|
-
SessionNotFoundError,
|
|
4602
|
-
SessionRevokedError,
|
|
4603
|
-
SpendingLimitExceededError,
|
|
4604
|
-
X402ProtocolError,
|
|
4605
|
-
getErrorMessage,
|
|
4606
|
-
isMixrPayError
|
|
4607
|
-
};
|
|
4652
|
+
|
|
4653
|
+
export { AgentWallet, InsufficientBalanceError, InvalidSessionKeyError, MerchantNotAllowedError, MixrPayError, PaymentFailedError, SDK_VERSION, SessionExpiredError, SessionKeyExpiredError, SessionLimitExceededError, SessionNotFoundError, SessionRevokedError, SpendingLimitExceededError, X402ProtocolError, getErrorMessage, isMixrPayError };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mixrpay/agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "tsup
|
|
22
|
+
"build": "tsup --config tsup.config.ts",
|
|
23
23
|
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
|
|
24
24
|
"test": "vitest run",
|
|
25
25
|
"test:watch": "vitest",
|