@mixrpay/agent-sdk 0.8.9 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -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
- "use strict";
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
- // src/index.ts
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 = (0, import_accounts.privateKeyToAccount)(privateKey);
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 (0, import_accounts.signTypedData)({
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 (0, import_accounts.signMessage)({
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 Privy-managed embedded wallet for the agent's payments.
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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
- privyConfigured: false,
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
- privyConfigured: data.services?.privy?.configured ?? false
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
- privyConfigured: false,
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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 = (0, import_accounts2.privateKeyToAccount)(privateKey);
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 (0, import_accounts2.signMessage)({ message, privateKey });
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 (max 20%). The child inherits merchant restrictions
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, // Max 20% of available budget
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 (0, import_accounts2.signMessage)({
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 how much can be spawned
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
  *
@@ -1971,8 +1929,8 @@ var AgentWallet = class {
1971
1929
  * ```typescript
1972
1930
  * const session = await wallet.getOrCreateSession({
1973
1931
  * merchantPublicKey: 'pk_live_abc123...',
1974
- * spendingLimitUsd: 25.00,
1975
- * durationDays: 7,
1932
+ * spendingLimitUsd: 100,
1933
+ * durationDays: 30,
1976
1934
  * });
1977
1935
  *
1978
1936
  * console.log(`Session active: $${session.remainingLimitUsd} remaining`);
@@ -1980,7 +1938,7 @@ var AgentWallet = class {
1980
1938
  */
1981
1939
  async getOrCreateSession(options) {
1982
1940
  this.logger.debug("getOrCreateSession called", options);
1983
- const { merchantPublicKey, spendingLimitUsd = 25, durationDays = 7 } = options;
1941
+ const { merchantPublicKey, spendingLimitUsd, durationDays } = options;
1984
1942
  try {
1985
1943
  const existingSession = await this.getSessionByMerchant(merchantPublicKey);
1986
1944
  if (existingSession && existingSession.status === "active") {
@@ -2294,10 +2252,7 @@ var AgentWallet = class {
2294
2252
  throw new SpendingLimitExceededError("client_max", this.maxPaymentUsd, priceUsd);
2295
2253
  }
2296
2254
  const session = await this.getOrCreateSession({
2297
- merchantPublicKey,
2298
- spendingLimitUsd: 25,
2299
- // Default limit
2300
- durationDays: 7
2255
+ merchantPublicKey
2301
2256
  });
2302
2257
  const headers = {
2303
2258
  "Content-Type": "application/json",
@@ -2342,9 +2297,7 @@ var AgentWallet = class {
2342
2297
  if (errorCode === "session_expired") {
2343
2298
  this.logger.info("Session expired, creating new one...");
2344
2299
  const newSession = await this.getOrCreateSession({
2345
- merchantPublicKey,
2346
- spendingLimitUsd: 25,
2347
- durationDays: 7
2300
+ merchantPublicKey
2348
2301
  });
2349
2302
  headers["X-Mixr-Session"] = newSession.id;
2350
2303
  return fetch(url, {
@@ -2723,6 +2676,75 @@ Timestamp: ${timestamp}`;
2723
2676
  return this.parseJitInstance(data.instance);
2724
2677
  }
2725
2678
  // ===========================================================================
2679
+ // Transaction Execution
2680
+ // ===========================================================================
2681
+ /**
2682
+ * Execute an on-chain transaction from the human's wallet.
2683
+ *
2684
+ * Submits arbitrary calldata to any contract, bounded by the session key's
2685
+ * budget limits (max_total, max_per_tx, max_daily). The platform validates
2686
+ * the budget, executes the transaction, and records a charge.
2687
+ *
2688
+ * @param params - Transaction parameters
2689
+ * @returns Transaction result with hash and remaining budget
2690
+ * @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
2691
+ *
2692
+ * @example
2693
+ * ```typescript
2694
+ * // Bridge USDC via deBridge
2695
+ * const quote = await deBridgeMcp.create_tx({ ... });
2696
+ * const result = await wallet.executeTransaction({
2697
+ * to: quote.contractAddress,
2698
+ * data: quote.calldata,
2699
+ * estimatedCostUsd: 25.0,
2700
+ * description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
2701
+ * });
2702
+ * console.log('TX:', result.txHash);
2703
+ * console.log('Budget remaining:', result.remainingBudgetUsd);
2704
+ * ```
2705
+ */
2706
+ async executeTransaction(params) {
2707
+ this.logger.debug("executeTransaction", { to: params.to, estimatedCostUsd: params.estimatedCostUsd });
2708
+ const authHeaders = await this.getSessionAuthHeaders();
2709
+ const response = await fetch(`${this.baseUrl}/api/v2/tx/execute`, {
2710
+ method: "POST",
2711
+ headers: {
2712
+ "Content-Type": "application/json",
2713
+ ...authHeaders
2714
+ },
2715
+ body: JSON.stringify({
2716
+ to: params.to,
2717
+ data: params.data,
2718
+ value: params.value?.toString() ?? "0",
2719
+ chain_id: params.chainId,
2720
+ estimated_cost_usd: params.estimatedCostUsd,
2721
+ description: params.description,
2722
+ idempotency_key: params.idempotencyKey
2723
+ })
2724
+ });
2725
+ const result = await response.json().catch(() => ({}));
2726
+ if (!response.ok) {
2727
+ const errorCode = result.error_code || "TX_FAILED";
2728
+ const errorMessage = result.error || `Transaction execution failed: ${response.status}`;
2729
+ if (errorCode === "BUDGET_EXCEEDED") {
2730
+ throw new MixrPayError(errorMessage, "SPENDING_LIMIT_EXCEEDED");
2731
+ }
2732
+ throw new MixrPayError(errorMessage, errorCode);
2733
+ }
2734
+ this.logger.info("Transaction executed", {
2735
+ txHash: result.tx_hash,
2736
+ estimatedCostUsd: params.estimatedCostUsd,
2737
+ remainingBudgetUsd: result.remaining_budget_usd
2738
+ });
2739
+ return {
2740
+ success: true,
2741
+ txHash: result.tx_hash,
2742
+ chargeId: result.charge_id,
2743
+ estimatedCostUsd: result.estimated_cost_usd,
2744
+ remainingBudgetUsd: result.remaining_budget_usd
2745
+ };
2746
+ }
2747
+ // ===========================================================================
2726
2748
  // Skills Methods
2727
2749
  // ===========================================================================
2728
2750
  /**
@@ -2861,7 +2883,7 @@ Timestamp: ${timestamp}`;
2861
2883
  );
2862
2884
  }
2863
2885
  const data = await response.json();
2864
- const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
2886
+ const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app.toLowerCase());
2865
2887
  return {
2866
2888
  connected: connectedAppNames,
2867
2889
  connections: data.connections || [],
@@ -4604,11 +4626,11 @@ Timestamp: ${timestamp}`;
4604
4626
  ...init.headers
4605
4627
  };
4606
4628
  if (this.sessionKey) {
4607
- const account = (0, import_accounts2.privateKeyToAccount)(this.sessionKey.rawPrivateKey);
4629
+ const account = accounts.privateKeyToAccount(this.sessionKey.rawPrivateKey);
4608
4630
  const address = account.address.toLowerCase();
4609
4631
  const timestamp = Date.now();
4610
4632
  const message = `MixrPay:${timestamp}:${address}`;
4611
- const signature = await (0, import_accounts2.signMessage)({
4633
+ const signature = await accounts.signMessage({
4612
4634
  message,
4613
4635
  privateKey: this.sessionKey.rawPrivateKey
4614
4636
  });
@@ -4624,22 +4646,20 @@ Timestamp: ${timestamp}`;
4624
4646
  });
4625
4647
  }
4626
4648
  };
4627
- // Annotate the CommonJS export names for ESM import in node:
4628
- 0 && (module.exports = {
4629
- AgentWallet,
4630
- InsufficientBalanceError,
4631
- InvalidSessionKeyError,
4632
- MerchantNotAllowedError,
4633
- MixrPayError,
4634
- PaymentFailedError,
4635
- SDK_VERSION,
4636
- SessionExpiredError,
4637
- SessionKeyExpiredError,
4638
- SessionLimitExceededError,
4639
- SessionNotFoundError,
4640
- SessionRevokedError,
4641
- SpendingLimitExceededError,
4642
- X402ProtocolError,
4643
- getErrorMessage,
4644
- isMixrPayError
4645
- });
4649
+
4650
+ exports.AgentWallet = AgentWallet;
4651
+ exports.InsufficientBalanceError = InsufficientBalanceError;
4652
+ exports.InvalidSessionKeyError = InvalidSessionKeyError;
4653
+ exports.MerchantNotAllowedError = MerchantNotAllowedError;
4654
+ exports.MixrPayError = MixrPayError;
4655
+ exports.PaymentFailedError = PaymentFailedError;
4656
+ exports.SDK_VERSION = SDK_VERSION;
4657
+ exports.SessionExpiredError = SessionExpiredError;
4658
+ exports.SessionKeyExpiredError = SessionKeyExpiredError;
4659
+ exports.SessionLimitExceededError = SessionLimitExceededError;
4660
+ exports.SessionNotFoundError = SessionNotFoundError;
4661
+ exports.SessionRevokedError = SessionRevokedError;
4662
+ exports.SpendingLimitExceededError = SpendingLimitExceededError;
4663
+ exports.X402ProtocolError = X402ProtocolError;
4664
+ exports.getErrorMessage = getErrorMessage;
4665
+ exports.isMixrPayError = isMixrPayError;
package/dist/index.d.cts CHANGED
@@ -233,12 +233,12 @@ interface CreateSessionOptions {
233
233
  merchantPublicKey: string;
234
234
  /**
235
235
  * Maximum spending limit for this session in USD.
236
- * @default 25.00
236
+ * If omitted, the server applies its own default.
237
237
  */
238
238
  spendingLimitUsd?: number;
239
239
  /**
240
240
  * Number of days this session should be valid.
241
- * @default 7
241
+ * If omitted, the server applies its own default.
242
242
  */
243
243
  durationDays?: number;
244
244
  }
@@ -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 (max 20% of available) */
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 20% cap) */
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 (20% of their budget) */
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 (20% of available) */
600
+ /** Maximum budget for next spawn */
601
601
  maxSpawnBudget: number;
602
- /** Whether spawning is allowed (depth < 10, can_spawn, available > 0) */
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 Privy-managed embedded wallet for the agent's payments.
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
- privyConfigured: boolean;
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 (max 20%). The child inherits merchant restrictions
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, // Max 20% of available budget
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 how much can be spawned
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
  *
@@ -1202,8 +1201,8 @@ declare class AgentWallet {
1202
1201
  * ```typescript
1203
1202
  * const session = await wallet.getOrCreateSession({
1204
1203
  * merchantPublicKey: 'pk_live_abc123...',
1205
- * spendingLimitUsd: 25.00,
1206
- * durationDays: 7,
1204
+ * spendingLimitUsd: 100,
1205
+ * durationDays: 30,
1207
1206
  * });
1208
1207
  *
1209
1208
  * console.log(`Session active: $${session.remainingLimitUsd} remaining`);
@@ -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
@@ -233,12 +233,12 @@ interface CreateSessionOptions {
233
233
  merchantPublicKey: string;
234
234
  /**
235
235
  * Maximum spending limit for this session in USD.
236
- * @default 25.00
236
+ * If omitted, the server applies its own default.
237
237
  */
238
238
  spendingLimitUsd?: number;
239
239
  /**
240
240
  * Number of days this session should be valid.
241
- * @default 7
241
+ * If omitted, the server applies its own default.
242
242
  */
243
243
  durationDays?: number;
244
244
  }
@@ -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 (max 20% of available) */
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 20% cap) */
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 (20% of their budget) */
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 (20% of available) */
600
+ /** Maximum budget for next spawn */
601
601
  maxSpawnBudget: number;
602
- /** Whether spawning is allowed (depth < 10, can_spawn, available > 0) */
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 Privy-managed embedded wallet for the agent's payments.
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
- privyConfigured: boolean;
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 (max 20%). The child inherits merchant restrictions
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, // Max 20% of available budget
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 how much can be spawned
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
  *
@@ -1202,8 +1201,8 @@ declare class AgentWallet {
1202
1201
  * ```typescript
1203
1202
  * const session = await wallet.getOrCreateSession({
1204
1203
  * merchantPublicKey: 'pk_live_abc123...',
1205
- * spendingLimitUsd: 25.00,
1206
- * durationDays: 7,
1204
+ * spendingLimitUsd: 100,
1205
+ * durationDays: 30,
1207
1206
  * });
1208
1207
  *
1209
1208
  * console.log(`Session active: $${session.remainingLimitUsd} remaining`);
@@ -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 viemSignMessage({
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 Privy-managed embedded wallet for the agent's payments.
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 = privateKeyToAccount2(privateKey);
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
- privyConfigured: false,
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
- privyConfigured: data.services?.privy?.configured ?? false
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
- privyConfigured: false,
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 = privateKeyToAccount2(privateKey);
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 = privateKeyToAccount2(privateKey);
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 = privateKeyToAccount2(privateKey);
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 = privateKeyToAccount2(privateKey);
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 = privateKeyToAccount2(privateKey);
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 (max 20%). The child inherits merchant restrictions
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, // Max 20% of available budget
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 how much can be spawned
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
  *
@@ -1934,8 +1927,8 @@ var AgentWallet = class {
1934
1927
  * ```typescript
1935
1928
  * const session = await wallet.getOrCreateSession({
1936
1929
  * merchantPublicKey: 'pk_live_abc123...',
1937
- * spendingLimitUsd: 25.00,
1938
- * durationDays: 7,
1930
+ * spendingLimitUsd: 100,
1931
+ * durationDays: 30,
1939
1932
  * });
1940
1933
  *
1941
1934
  * console.log(`Session active: $${session.remainingLimitUsd} remaining`);
@@ -1943,7 +1936,7 @@ var AgentWallet = class {
1943
1936
  */
1944
1937
  async getOrCreateSession(options) {
1945
1938
  this.logger.debug("getOrCreateSession called", options);
1946
- const { merchantPublicKey, spendingLimitUsd = 25, durationDays = 7 } = options;
1939
+ const { merchantPublicKey, spendingLimitUsd, durationDays } = options;
1947
1940
  try {
1948
1941
  const existingSession = await this.getSessionByMerchant(merchantPublicKey);
1949
1942
  if (existingSession && existingSession.status === "active") {
@@ -2257,10 +2250,7 @@ var AgentWallet = class {
2257
2250
  throw new SpendingLimitExceededError("client_max", this.maxPaymentUsd, priceUsd);
2258
2251
  }
2259
2252
  const session = await this.getOrCreateSession({
2260
- merchantPublicKey,
2261
- spendingLimitUsd: 25,
2262
- // Default limit
2263
- durationDays: 7
2253
+ merchantPublicKey
2264
2254
  });
2265
2255
  const headers = {
2266
2256
  "Content-Type": "application/json",
@@ -2305,9 +2295,7 @@ var AgentWallet = class {
2305
2295
  if (errorCode === "session_expired") {
2306
2296
  this.logger.info("Session expired, creating new one...");
2307
2297
  const newSession = await this.getOrCreateSession({
2308
- merchantPublicKey,
2309
- spendingLimitUsd: 25,
2310
- durationDays: 7
2298
+ merchantPublicKey
2311
2299
  });
2312
2300
  headers["X-Mixr-Session"] = newSession.id;
2313
2301
  return fetch(url, {
@@ -2686,6 +2674,75 @@ Timestamp: ${timestamp}`;
2686
2674
  return this.parseJitInstance(data.instance);
2687
2675
  }
2688
2676
  // ===========================================================================
2677
+ // Transaction Execution
2678
+ // ===========================================================================
2679
+ /**
2680
+ * Execute an on-chain transaction from the human's wallet.
2681
+ *
2682
+ * Submits arbitrary calldata to any contract, bounded by the session key's
2683
+ * budget limits (max_total, max_per_tx, max_daily). The platform validates
2684
+ * the budget, executes the transaction, and records a charge.
2685
+ *
2686
+ * @param params - Transaction parameters
2687
+ * @returns Transaction result with hash and remaining budget
2688
+ * @throws {MixrPayError} If budget exceeded, tx reverted, or auth fails
2689
+ *
2690
+ * @example
2691
+ * ```typescript
2692
+ * // Bridge USDC via deBridge
2693
+ * const quote = await deBridgeMcp.create_tx({ ... });
2694
+ * const result = await wallet.executeTransaction({
2695
+ * to: quote.contractAddress,
2696
+ * data: quote.calldata,
2697
+ * estimatedCostUsd: 25.0,
2698
+ * description: 'Bridge 25 USDC Base -> Avalanche via deBridge',
2699
+ * });
2700
+ * console.log('TX:', result.txHash);
2701
+ * console.log('Budget remaining:', result.remainingBudgetUsd);
2702
+ * ```
2703
+ */
2704
+ async executeTransaction(params) {
2705
+ this.logger.debug("executeTransaction", { to: params.to, estimatedCostUsd: params.estimatedCostUsd });
2706
+ const authHeaders = await this.getSessionAuthHeaders();
2707
+ const response = await fetch(`${this.baseUrl}/api/v2/tx/execute`, {
2708
+ method: "POST",
2709
+ headers: {
2710
+ "Content-Type": "application/json",
2711
+ ...authHeaders
2712
+ },
2713
+ body: JSON.stringify({
2714
+ to: params.to,
2715
+ data: params.data,
2716
+ value: params.value?.toString() ?? "0",
2717
+ chain_id: params.chainId,
2718
+ estimated_cost_usd: params.estimatedCostUsd,
2719
+ description: params.description,
2720
+ idempotency_key: params.idempotencyKey
2721
+ })
2722
+ });
2723
+ const result = await response.json().catch(() => ({}));
2724
+ if (!response.ok) {
2725
+ const errorCode = result.error_code || "TX_FAILED";
2726
+ const errorMessage = result.error || `Transaction execution failed: ${response.status}`;
2727
+ if (errorCode === "BUDGET_EXCEEDED") {
2728
+ throw new MixrPayError(errorMessage, "SPENDING_LIMIT_EXCEEDED");
2729
+ }
2730
+ throw new MixrPayError(errorMessage, errorCode);
2731
+ }
2732
+ this.logger.info("Transaction executed", {
2733
+ txHash: result.tx_hash,
2734
+ estimatedCostUsd: params.estimatedCostUsd,
2735
+ remainingBudgetUsd: result.remaining_budget_usd
2736
+ });
2737
+ return {
2738
+ success: true,
2739
+ txHash: result.tx_hash,
2740
+ chargeId: result.charge_id,
2741
+ estimatedCostUsd: result.estimated_cost_usd,
2742
+ remainingBudgetUsd: result.remaining_budget_usd
2743
+ };
2744
+ }
2745
+ // ===========================================================================
2689
2746
  // Skills Methods
2690
2747
  // ===========================================================================
2691
2748
  /**
@@ -2824,7 +2881,7 @@ Timestamp: ${timestamp}`;
2824
2881
  );
2825
2882
  }
2826
2883
  const data = await response.json();
2827
- const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
2884
+ const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app.toLowerCase());
2828
2885
  return {
2829
2886
  connected: connectedAppNames,
2830
2887
  connections: data.connections || [],
@@ -4567,7 +4624,7 @@ Timestamp: ${timestamp}`;
4567
4624
  ...init.headers
4568
4625
  };
4569
4626
  if (this.sessionKey) {
4570
- const account = privateKeyToAccount2(this.sessionKey.rawPrivateKey);
4627
+ const account = privateKeyToAccount(this.sessionKey.rawPrivateKey);
4571
4628
  const address = account.address.toLowerCase();
4572
4629
  const timestamp = Date.now();
4573
4630
  const message = `MixrPay:${timestamp}:${address}`;
@@ -4587,21 +4644,5 @@ Timestamp: ${timestamp}`;
4587
4644
  });
4588
4645
  }
4589
4646
  };
4590
- export {
4591
- AgentWallet,
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
- };
4647
+
4648
+ 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.8.9",
3
+ "version": "0.9.2",
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 src/index.ts --format esm,cjs --dts --clean",
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",