@compass-labs/widgets 0.1.36 → 0.1.38

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.
@@ -91,17 +91,46 @@ function createCompassHandler(config) {
91
91
  return await handleCreditExecute(client, body, config);
92
92
  case "credit/transfer":
93
93
  return await handleCreditTransfer(client, body);
94
+ case "approval/execute":
95
+ return await handleApprovalExecute(body, config);
94
96
  default:
95
97
  return jsonResponse({ error: `Unknown POST route: ${route}` }, 404);
96
98
  }
97
99
  }
98
100
  return jsonResponse({ error: `Method ${method} not allowed` }, 405);
99
101
  } catch (error) {
100
- const message = error instanceof Error ? error.message : "Internal server error";
101
- return jsonResponse({ error: message }, 500);
102
+ const { message, status } = extractErrorMessage(error);
103
+ return jsonResponse({ error: message }, status);
102
104
  }
103
105
  };
104
106
  }
107
+ function extractErrorMessage(error) {
108
+ if (!(error instanceof Error)) {
109
+ return { message: "Something went wrong. Please try again.", status: 500 };
110
+ }
111
+ const raw = error.message || "";
112
+ const jsonMatch = raw.match(/Body:\s*(\{[\s\S]*\})/);
113
+ if (jsonMatch) {
114
+ try {
115
+ const body = JSON.parse(jsonMatch[1]);
116
+ if (Array.isArray(body.detail)) {
117
+ const msgs = body.detail.map((d) => d.msg || d.message).filter(Boolean);
118
+ if (msgs.length > 0) return { message: msgs.join(". "), status: 422 };
119
+ }
120
+ if (typeof body.detail === "string") return { message: body.detail, status: 422 };
121
+ if (typeof body.error === "string") return { message: body.error, status: 500 };
122
+ if (typeof body.description === "string") return { message: body.description, status: 500 };
123
+ } catch {
124
+ }
125
+ }
126
+ if (error.name === "SDKValidationError" || raw.startsWith("Input validation failed")) {
127
+ return { message: "Invalid request data. Please check your inputs and try again.", status: 400 };
128
+ }
129
+ if (raw.includes("Insufficient") || raw.includes("not deployed") || raw.includes("reverted") || raw.includes("not configured") || raw.includes("Unsupported chain")) {
130
+ return { message: raw, status: 500 };
131
+ }
132
+ return { message: "Something went wrong. Please try again.", status: 500 };
133
+ }
105
134
  function jsonResponse(data, status = 200) {
106
135
  return new Response(JSON.stringify(data), {
107
136
  status,
@@ -260,10 +289,6 @@ async function handleExecute(client, body, config) {
260
289
  chain: viemChain,
261
290
  transport: http(rpcUrl)
262
291
  });
263
- const publicClient = createPublicClient({
264
- chain: viemChain,
265
- transport: http(rpcUrl)
266
- });
267
292
  const response = await client.gasSponsorship.gasSponsorshipPrepare({
268
293
  chain,
269
294
  owner,
@@ -284,12 +309,6 @@ async function handleExecute(client, body, config) {
284
309
  value: transaction.value ? BigInt(transaction.value) : 0n,
285
310
  gas: transaction.gas ? BigInt(transaction.gas) : void 0
286
311
  });
287
- const receipt = await publicClient.waitForTransactionReceipt({
288
- hash: txHash
289
- });
290
- if (receipt.status === "reverted") {
291
- return jsonResponse({ error: "Transaction reverted" }, 500);
292
- }
293
312
  return jsonResponse({ txHash, success: true });
294
313
  }
295
314
  async function handleTransferApprove(client, body) {
@@ -342,8 +361,53 @@ async function handleTransferApprove(client, body) {
342
361
  throw error;
343
362
  }
344
363
  }
364
+ async function handleApprovalExecute(body, config) {
365
+ const { owner, chain = "base", transaction } = body;
366
+ const { gasSponsorPrivateKey, rpcUrls } = config;
367
+ if (!owner || !transaction) {
368
+ return jsonResponse({ error: "Missing required parameters (owner, transaction)" }, 400);
369
+ }
370
+ if (!gasSponsorPrivateKey) {
371
+ return jsonResponse(
372
+ { error: "Gas sponsor not configured. Set gasSponsorPrivateKey in handler config." },
373
+ 500
374
+ );
375
+ }
376
+ const viemChain = CHAIN_MAP[chain.toLowerCase()];
377
+ if (!viemChain) {
378
+ return jsonResponse({ error: `Unsupported chain: ${chain}` }, 500);
379
+ }
380
+ const rpcUrl = rpcUrls?.[chain.toLowerCase()];
381
+ if (!rpcUrl) {
382
+ return jsonResponse({ error: `No RPC URL configured for chain: ${chain}` }, 500);
383
+ }
384
+ const sponsorAccount = privateKeyToAccount(gasSponsorPrivateKey);
385
+ const walletClient = createWalletClient({
386
+ account: sponsorAccount,
387
+ chain: viemChain,
388
+ transport: http(rpcUrl)
389
+ });
390
+ const publicClient = createPublicClient({
391
+ chain: viemChain,
392
+ transport: http(rpcUrl)
393
+ });
394
+ const txHash = await walletClient.sendTransaction({
395
+ to: transaction.to,
396
+ data: transaction.data,
397
+ value: transaction.value ? BigInt(transaction.value) : 0n,
398
+ gas: transaction.gas ? BigInt(transaction.gas) : void 0
399
+ });
400
+ const receipt = await publicClient.waitForTransactionReceipt({
401
+ hash: txHash,
402
+ timeout: 6e4
403
+ });
404
+ if (receipt.status === "reverted") {
405
+ return jsonResponse({ error: "Approval transaction reverted" }, 500);
406
+ }
407
+ return jsonResponse({ txHash, status: "success" });
408
+ }
345
409
  async function handleTransferPrepare(client, body, config) {
346
- const { owner, chain = "base", token, amount, action } = body;
410
+ const { owner, chain = "base", token, amount, action, product } = body;
347
411
  const { gasSponsorPrivateKey } = config;
348
412
  if (!owner || !token || !amount || !action) {
349
413
  return jsonResponse({ error: "Missing required parameters" }, 400);
@@ -353,15 +417,28 @@ async function handleTransferPrepare(client, body, config) {
353
417
  const sponsorAccount = privateKeyToAccount(gasSponsorPrivateKey);
354
418
  spender = sponsorAccount.address;
355
419
  }
356
- const response = await client.earn.earnTransfer({
357
- owner,
358
- chain,
359
- token,
360
- amount,
361
- action,
362
- gasSponsorship: true,
363
- ...spender && { spender }
364
- });
420
+ let response;
421
+ if (product === "credit") {
422
+ response = await client.credit.creditTransfer({
423
+ owner,
424
+ chain,
425
+ token,
426
+ amount,
427
+ action,
428
+ gasSponsorship: true,
429
+ ...spender && { spender }
430
+ });
431
+ } else {
432
+ response = await client.earn.earnTransfer({
433
+ owner,
434
+ chain,
435
+ token,
436
+ amount,
437
+ action,
438
+ gasSponsorship: true,
439
+ ...spender && { spender }
440
+ });
441
+ }
365
442
  const eip712 = response.eip712;
366
443
  if (!eip712) {
367
444
  return jsonResponse({ error: "No EIP-712 data returned from API" }, 500);
@@ -389,7 +466,7 @@ async function handleTransferPrepare(client, body, config) {
389
466
  });
390
467
  }
391
468
  async function handleTransferExecute(client, body, config) {
392
- const { owner, chain = "base", eip712, signature } = body;
469
+ const { owner, chain = "base", eip712, signature, product } = body;
393
470
  const { gasSponsorPrivateKey, rpcUrls } = config;
394
471
  if (!owner || !eip712 || !signature) {
395
472
  return jsonResponse({ error: "Missing required parameters" }, 400);
@@ -414,22 +491,14 @@ async function handleTransferExecute(client, body, config) {
414
491
  chain: viemChain,
415
492
  transport: http(rpcUrl)
416
493
  });
417
- const publicClient = createPublicClient({
418
- chain: viemChain,
419
- transport: http(rpcUrl)
494
+ const response = await client.gasSponsorship.gasSponsorshipPrepare({
495
+ chain,
496
+ owner,
497
+ sender: sponsorAccount.address,
498
+ eip712,
499
+ signature,
500
+ ...product === "credit" && { product: "credit" }
420
501
  });
421
- let response;
422
- try {
423
- response = await client.gasSponsorship.gasSponsorshipPrepare({
424
- chain,
425
- owner,
426
- sender: sponsorAccount.address,
427
- eip712,
428
- signature
429
- });
430
- } catch (prepareError) {
431
- throw prepareError;
432
- }
433
502
  const transaction = response.transaction;
434
503
  if (!transaction) {
435
504
  return jsonResponse(
@@ -443,12 +512,6 @@ async function handleTransferExecute(client, body, config) {
443
512
  value: transaction.value ? BigInt(transaction.value) : 0n,
444
513
  gas: transaction.gas ? BigInt(transaction.gas) : void 0
445
514
  });
446
- const receipt = await publicClient.waitForTransactionReceipt({
447
- hash: txHash
448
- });
449
- if (receipt.status === "reverted") {
450
- return jsonResponse({ error: "Transaction reverted" }, 500);
451
- }
452
515
  return jsonResponse({ txHash, success: true });
453
516
  }
454
517
  async function handleEarnAccountBalances(client, params) {
@@ -1360,6 +1423,7 @@ async function handleCreditTransfer(client, body) {
1360
1423
  chain,
1361
1424
  token,
1362
1425
  amount,
1426
+ action: "DEPOSIT",
1363
1427
  gasSponsorship: true
1364
1428
  });
1365
1429
  const eip712 = response.eip712;