@solana/connector 0.2.4 → 0.2.6

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.
Files changed (64) hide show
  1. package/dist/{chunk-SIVITWXE.mjs → chunk-26SWXQP6.mjs} +11 -8
  2. package/dist/chunk-26SWXQP6.mjs.map +1 -0
  3. package/dist/{chunk-NLPEO5GT.js → chunk-5MA4YO43.js} +3 -3
  4. package/dist/chunk-5MA4YO43.js.map +1 -0
  5. package/dist/{chunk-R3IOWWA7.js → chunk-6UTXGTYX.js} +26 -23
  6. package/dist/chunk-6UTXGTYX.js.map +1 -0
  7. package/dist/{chunk-TMCJU76S.js → chunk-7DATF5NN.js} +4 -4
  8. package/dist/{chunk-TMCJU76S.js.map → chunk-7DATF5NN.js.map} +1 -1
  9. package/dist/{chunk-E3DAIOYS.mjs → chunk-GM3PZ3WK.mjs} +11 -6
  10. package/dist/chunk-GM3PZ3WK.mjs.map +1 -0
  11. package/dist/{chunk-QST7XLMB.js → chunk-PNZYYZZS.js} +11 -6
  12. package/dist/chunk-PNZYYZZS.js.map +1 -0
  13. package/dist/{chunk-CTHICIEC.mjs → chunk-PP7GI6BR.mjs} +3 -3
  14. package/dist/{chunk-CTHICIEC.mjs.map → chunk-PP7GI6BR.mjs.map} +1 -1
  15. package/dist/{chunk-KE3IEBN2.mjs → chunk-STJOIQUF.mjs} +21 -5
  16. package/dist/chunk-STJOIQUF.mjs.map +1 -0
  17. package/dist/{chunk-POESNTBI.js → chunk-USIWRRHO.js} +20 -4
  18. package/dist/chunk-USIWRRHO.js.map +1 -0
  19. package/dist/{chunk-A7WQ3K75.mjs → chunk-ZBPAQUIP.mjs} +3 -3
  20. package/dist/chunk-ZBPAQUIP.mjs.map +1 -0
  21. package/dist/compat.d.mts +1 -1
  22. package/dist/compat.d.ts +1 -1
  23. package/dist/headless.d.mts +5 -6
  24. package/dist/headless.d.ts +5 -6
  25. package/dist/headless.js +113 -113
  26. package/dist/headless.mjs +3 -3
  27. package/dist/index.d.mts +2 -3
  28. package/dist/index.d.ts +2 -3
  29. package/dist/index.js +154 -154
  30. package/dist/index.mjs +4 -4
  31. package/dist/{protocol-G-z1lRqo.d.mts → protocol-nWSt9TTV.d.mts} +1 -1
  32. package/dist/{protocol-G-z1lRqo.d.ts → protocol-nWSt9TTV.d.ts} +1 -1
  33. package/dist/react.d.mts +23 -18
  34. package/dist/react.d.ts +23 -18
  35. package/dist/react.js +49 -49
  36. package/dist/react.mjs +2 -2
  37. package/dist/remote.d.mts +2 -2
  38. package/dist/remote.d.ts +2 -2
  39. package/dist/remote.js +13 -13
  40. package/dist/remote.mjs +2 -2
  41. package/dist/server.d.mts +1 -1
  42. package/dist/server.d.ts +1 -1
  43. package/dist/server.js +13 -10
  44. package/dist/server.js.map +1 -1
  45. package/dist/server.mjs +5 -2
  46. package/dist/server.mjs.map +1 -1
  47. package/dist/{standard-shim-BB0Lkg_C.d.ts → standard-shim-BK2nn2ZT.d.ts} +15 -8
  48. package/dist/{standard-shim-n5phZB1d.d.mts → standard-shim-DSMKHCxD.d.mts} +15 -8
  49. package/dist/{transaction-signer-7NaYmP5w.d.ts → transaction-signer-B3eCsMfI.d.mts} +1 -1
  50. package/dist/{transaction-signer-7NaYmP5w.d.mts → transaction-signer-B3eCsMfI.d.ts} +1 -1
  51. package/dist/{walletconnect-F2M3PAAN.js → walletconnect-FFPQ6PDH.js} +8 -8
  52. package/dist/{walletconnect-F2M3PAAN.js.map → walletconnect-FFPQ6PDH.js.map} +1 -1
  53. package/dist/walletconnect-HMQQB3YM.mjs +3 -0
  54. package/dist/{walletconnect-Z6LPGALR.mjs.map → walletconnect-HMQQB3YM.mjs.map} +1 -1
  55. package/package.json +40 -31
  56. package/dist/chunk-A7WQ3K75.mjs.map +0 -1
  57. package/dist/chunk-E3DAIOYS.mjs.map +0 -1
  58. package/dist/chunk-KE3IEBN2.mjs.map +0 -1
  59. package/dist/chunk-NLPEO5GT.js.map +0 -1
  60. package/dist/chunk-POESNTBI.js.map +0 -1
  61. package/dist/chunk-QST7XLMB.js.map +0 -1
  62. package/dist/chunk-R3IOWWA7.js.map +0 -1
  63. package/dist/chunk-SIVITWXE.mjs.map +0 -1
  64. package/dist/walletconnect-Z6LPGALR.mjs +0 -3
package/dist/remote.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkQST7XLMB_js = require('./chunk-QST7XLMB.js');
3
+ var chunkPNZYYZZS_js = require('./chunk-PNZYYZZS.js');
4
4
 
5
5
  // src/remote/remote-wallet.ts
6
6
  var DEFAULT_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAzMCAyOC4zMzE5IiBmaWxsPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGc+PHJlY3QgaGVpZ2h0PSIyNS4wODU1IiBvcGFjaXR5PSIwIiB3aWR0aD0iMjYuNTYyNSIgeD0iMCIgeT0iMCIvPjxwYXRoIGQ9Ik0xNy42NzgzIDE1LjEyNzdDMTcuNzc2MSAxNi41MzcgMTguNTE0NyAxNy43NzA5IDE5LjY1ODIgMTguNTI0MkwxOS42NTgyIDIxLjMxNjlDMTkuNjU1MSAyMS4zMTcxIDE5LjY1MTggMjEuMzE3MSAxOS42NDg0IDIxLjMxNzFMNi41NTI3MyAyMS4zMTcxQzUuNTA3ODEgMjEuMzE3MSA0Ljg4MjgxIDIwLjgyODkgNC44ODI4MSAyMC4wMTgzQzQuODgyODEgMTcuNDk4OCA4LjAzNzExIDE0LjAyMjIgMTMuMDk1NyAxNC4wMjIyQzE0Ljg4MDkgMTQuMDIyMiAxNi40Mjg2IDE0LjQ1MzUgMTcuNjc4MyAxNS4xMjc3Wk0xNy4wMTE3IDcuOTU3NzdDMTcuMDExNyAxMC4zOTkyIDE1LjE5NTMgMTIuMjc0MiAxMy4xMDU1IDEyLjI3NDJDMTEuMDA1OSAxMi4yNzQyIDkuMTk5MjIgMTAuMzk5MiA5LjE5OTIyIDcuOTc3M0M5LjE5OTIyIDUuNTg0NzIgMTEuMDE1NiAzLjc1ODU1IDEzLjEwNTUgMy43NTg1NUMxNS4xOTUzIDMuNzU4NTUgMTcuMDExNyA1LjU0NTY2IDE3LjAxMTcgNy45NTc3N1oiIGZpbGwtb3BhY2l0eT0iMC44NSIvPjxwYXRoIGQ9Ik0yMi4xMTkxIDExLjY5OEMyMC4zODA5IDExLjY5OCAxOS4wMDM5IDEzLjA5NDUgMTkuMDAzOSAxNC44MDM1QzE5LjAwMzkgMTYuMTMxNiAxOS43ODUyIDE3LjI1NDYgMjAuOTg2MyAxNy43MjM0TDIwLjk4NjMgMjIuNTU3NEMyMC45ODYzIDIyLjY3NDYgMjEuMDQ0OSAyMi43NjI1IDIxLjEyMyAyMi44NjAxTDIxLjk0MzQgMjMuNjgwNEMyMi4wNDEgMjMuNzc4MSAyMi4xNzc3IDIzLjc4NzggMjIuMjg1MiAyMy42ODA0TDIzLjgzNzkgMjIuMTM3NUMyMy45MzU1IDIyLjAzIDIzLjkzNTUgMjEuODkzMyAyMy44Mzc5IDIxLjc5NTdMMjIuODcxMSAyMC44Mjg5TDI0LjIwOSAxOS41MjAzQzI0LjMwNjYgMTkuNDMyNCAyNC4zMDY2IDE5LjI4NTkgMjQuMTg5NSAxOS4xNjg3TDIyLjg4MDkgMTcuODY5OUMyNC4zODQ4IDE3LjI1NDYgMjUuMjI0NiAxNi4xNjA5IDI1LjIyNDYgMTQuODAzNUMyNS4yMjQ2IDEzLjA5NDUgMjMuODM3OSAxMS42OTggMjIuMTE5MSAxMS42OThaTTIyLjEwOTQgMTMuMTUzMUMyMi42MzY3IDEzLjE1MzEgMjMuMDY2NCAxMy41ODI4IDIzLjA2NjQgMTQuMTEwMUMyMy4wNjY0IDE0LjY1NyAyMi42MzY3IDE1LjA4NjcgMjIuMTA5NCAxNS4wODY3QzIxLjU4MiAxNS4wODY3IDIxLjE0MjYgMTQuNjU3IDIxLjE0MjYgMTQuMTEwMUMyMS4xNDI2IDEzLjU4MjggMjEuNTcyMyAxMy4xNTMxIDIyLjEwOTQgMTMuMTUzMVoiIGZpbGwtb3BhY2l0eT0iMC44NSIvPjwvZz48L3N2Zz4=", DEFAULT_CHAINS = ["solana:mainnet", "solana:devnet"], RemoteWalletError = class extends Error {
@@ -26,8 +26,8 @@ function createRemoteSignerWallet(config) {
26
26
  headers,
27
27
  body: body ? JSON.stringify(body) : void 0
28
28
  }), data = await response.json();
29
- if (!response.ok || chunkQST7XLMB_js.isErrorResponse(data)) {
30
- let errorData = chunkQST7XLMB_js.isErrorResponse(data) ? data.error : { code: "UNKNOWN", message: "Request failed", details: void 0 };
29
+ if (!response.ok || chunkPNZYYZZS_js.isErrorResponse(data)) {
30
+ let errorData = chunkPNZYYZZS_js.isErrorResponse(data) ? data.error : { code: "UNKNOWN", message: "Request failed", details: void 0 };
31
31
  throw new RemoteWalletError(errorData.message, errorData.code, errorData.details);
32
32
  }
33
33
  return data;
@@ -91,10 +91,10 @@ function createRemoteSignerWallet(config) {
91
91
  for (let input of inputs) {
92
92
  let txBytes = input.transaction, req = {
93
93
  operation: "signTransaction",
94
- transaction: chunkQST7XLMB_js.encodeBase64(txBytes)
94
+ transaction: chunkPNZYYZZS_js.encodeBase64(txBytes)
95
95
  }, response = await request("POST", req);
96
96
  results.push({
97
- signedTransaction: chunkQST7XLMB_js.decodeBase64(response.signedTransaction)
97
+ signedTransaction: chunkPNZYYZZS_js.decodeBase64(response.signedTransaction)
98
98
  });
99
99
  }
100
100
  return results;
@@ -112,10 +112,10 @@ function createRemoteSignerWallet(config) {
112
112
  allTxBytes.push(input.transaction);
113
113
  let req = {
114
114
  operation: "signAllTransactions",
115
- transactions: allTxBytes.map((tx) => chunkQST7XLMB_js.encodeBase64(tx))
115
+ transactions: allTxBytes.map((tx) => chunkPNZYYZZS_js.encodeBase64(tx))
116
116
  };
117
117
  return (await request("POST", req)).signedTransactions.map((signedTx) => ({
118
- signedTransaction: chunkQST7XLMB_js.decodeBase64(signedTx)
118
+ signedTransaction: chunkPNZYYZZS_js.decodeBase64(signedTx)
119
119
  }));
120
120
  }
121
121
  },
@@ -129,11 +129,11 @@ function createRemoteSignerWallet(config) {
129
129
  for (let input of inputs) {
130
130
  let req = {
131
131
  operation: "signMessage",
132
- message: chunkQST7XLMB_js.encodeBase64(input.message)
132
+ message: chunkPNZYYZZS_js.encodeBase64(input.message)
133
133
  }, response = await request("POST", req);
134
134
  results.push({
135
135
  signedMessage: input.message,
136
- signature: chunkQST7XLMB_js.decodeBase64(response.signature)
136
+ signature: chunkPNZYYZZS_js.decodeBase64(response.signature)
137
137
  });
138
138
  }
139
139
  return results;
@@ -155,7 +155,7 @@ function createRemoteSignerWallet(config) {
155
155
  for (let input of inputs) {
156
156
  let req = {
157
157
  operation: "signAndSendTransaction",
158
- transaction: chunkQST7XLMB_js.encodeBase64(input.transaction),
158
+ transaction: chunkPNZYYZZS_js.encodeBase64(input.transaction),
159
159
  options: input.options
160
160
  }, response = await request("POST", req), sigBytes = base58ToBytes(response.signature);
161
161
  results.push({ signature: sigBytes });
@@ -196,15 +196,15 @@ function base58ToBytes(base58) {
196
196
 
197
197
  Object.defineProperty(exports, "decodeBase64", {
198
198
  enumerable: true,
199
- get: function () { return chunkQST7XLMB_js.decodeBase64; }
199
+ get: function () { return chunkPNZYYZZS_js.decodeBase64; }
200
200
  });
201
201
  Object.defineProperty(exports, "encodeBase64", {
202
202
  enumerable: true,
203
- get: function () { return chunkQST7XLMB_js.encodeBase64; }
203
+ get: function () { return chunkPNZYYZZS_js.encodeBase64; }
204
204
  });
205
205
  Object.defineProperty(exports, "isErrorResponse", {
206
206
  enumerable: true,
207
- get: function () { return chunkQST7XLMB_js.isErrorResponse; }
207
+ get: function () { return chunkPNZYYZZS_js.isErrorResponse; }
208
208
  });
209
209
  exports.RemoteWalletError = RemoteWalletError;
210
210
  exports.createRemoteSignerWallet = createRemoteSignerWallet;
package/dist/remote.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { encodeBase64, decodeBase64, isErrorResponse } from './chunk-E3DAIOYS.mjs';
2
- export { decodeBase64, encodeBase64, isErrorResponse } from './chunk-E3DAIOYS.mjs';
1
+ import { encodeBase64, decodeBase64, isErrorResponse } from './chunk-GM3PZ3WK.mjs';
2
+ export { decodeBase64, encodeBase64, isErrorResponse } from './chunk-GM3PZ3WK.mjs';
3
3
 
4
4
  // src/remote/remote-wallet.ts
5
5
  var DEFAULT_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAzMCAyOC4zMzE5IiBmaWxsPSJjdXJyZW50Q29sb3IiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGc+PHJlY3QgaGVpZ2h0PSIyNS4wODU1IiBvcGFjaXR5PSIwIiB3aWR0aD0iMjYuNTYyNSIgeD0iMCIgeT0iMCIvPjxwYXRoIGQ9Ik0xNy42NzgzIDE1LjEyNzdDMTcuNzc2MSAxNi41MzcgMTguNTE0NyAxNy43NzA5IDE5LjY1ODIgMTguNTI0MkwxOS42NTgyIDIxLjMxNjlDMTkuNjU1MSAyMS4zMTcxIDE5LjY1MTggMjEuMzE3MSAxOS42NDg0IDIxLjMxNzFMNi41NTI3MyAyMS4zMTcxQzUuNTA3ODEgMjEuMzE3MSA0Ljg4MjgxIDIwLjgyODkgNC44ODI4MSAyMC4wMTgzQzQuODgyODEgMTcuNDk4OCA4LjAzNzExIDE0LjAyMjIgMTMuMDk1NyAxNC4wMjIyQzE0Ljg4MDkgMTQuMDIyMiAxNi40Mjg2IDE0LjQ1MzUgMTcuNjc4MyAxNS4xMjc3Wk0xNy4wMTE3IDcuOTU3NzdDMTcuMDExNyAxMC4zOTkyIDE1LjE5NTMgMTIuMjc0MiAxMy4xMDU1IDEyLjI3NDJDMTEuMDA1OSAxMi4yNzQyIDkuMTk5MjIgMTAuMzk5MiA5LjE5OTIyIDcuOTc3M0M5LjE5OTIyIDUuNTg0NzIgMTEuMDE1NiAzLjc1ODU1IDEzLjEwNTUgMy43NTg1NUMxNS4xOTUzIDMuNzU4NTUgMTcuMDExNyA1LjU0NTY2IDE3LjAxMTcgNy45NTc3N1oiIGZpbGwtb3BhY2l0eT0iMC44NSIvPjxwYXRoIGQ9Ik0yMi4xMTkxIDExLjY5OEMyMC4zODA5IDExLjY5OCAxOS4wMDM5IDEzLjA5NDUgMTkuMDAzOSAxNC44MDM1QzE5LjAwMzkgMTYuMTMxNiAxOS43ODUyIDE3LjI1NDYgMjAuOTg2MyAxNy43MjM0TDIwLjk4NjMgMjIuNTU3NEMyMC45ODYzIDIyLjY3NDYgMjEuMDQ0OSAyMi43NjI1IDIxLjEyMyAyMi44NjAxTDIxLjk0MzQgMjMuNjgwNEMyMi4wNDEgMjMuNzc4MSAyMi4xNzc3IDIzLjc4NzggMjIuMjg1MiAyMy42ODA0TDIzLjgzNzkgMjIuMTM3NUMyMy45MzU1IDIyLjAzIDIzLjkzNTUgMjEuODkzMyAyMy44Mzc5IDIxLjc5NTdMMjIuODcxMSAyMC44Mjg5TDI0LjIwOSAxOS41MjAzQzI0LjMwNjYgMTkuNDMyNCAyNC4zMDY2IDE5LjI4NTkgMjQuMTg5NSAxOS4xNjg3TDIyLjg4MDkgMTcuODY5OUMyNC4zODQ4IDE3LjI1NDYgMjUuMjI0NiAxNi4xNjA5IDI1LjIyNDYgMTQuODAzNUMyNS4yMjQ2IDEzLjA5NDUgMjMuODM3OSAxMS42OTggMjIuMTE5MSAxMS42OThaTTIyLjEwOTQgMTMuMTUzMUMyMi42MzY3IDEzLjE1MzEgMjMuMDY2NCAxMy41ODI4IDIzLjA2NjQgMTQuMTEwMUMyMy4wNjY0IDE0LjY1NyAyMi42MzY3IDE1LjA4NjcgMjIuMTA5NCAxNS4wODY3QzIxLjU4MiAxNS4wODY3IDIxLjE0MjYgMTQuNjU3IDIxLjE0MjYgMTQuMTEwMUMyMS4xNDI2IDEzLjU4MjggMjEuNTcyMyAxMy4xNTMxIDIyLjEwOTQgMTMuMTUzMVoiIGZpbGwtb3BhY2l0eT0iMC44NSIvPjwvZz48L3N2Zz4=", DEFAULT_CHAINS = ["solana:mainnet", "solana:devnet"], RemoteWalletError = class extends Error {
package/dist/server.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { b as RemoteSignerCapabilities, l as RemoteSignerErrorCode, k as RemoteSignerErrorResponse, a as RemoteSignerMetadata, c as RemoteSignerRequest } from './protocol-G-z1lRqo.mjs';
1
+ export { a as RemoteSignerCapabilities, b as RemoteSignerErrorCode, c as RemoteSignerErrorResponse, d as RemoteSignerMetadata, e as RemoteSignerRequest } from './protocol-nWSt9TTV.mjs';
2
2
 
3
3
  /**
4
4
  * @solana/connector/server - Route Handlers
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { b as RemoteSignerCapabilities, l as RemoteSignerErrorCode, k as RemoteSignerErrorResponse, a as RemoteSignerMetadata, c as RemoteSignerRequest } from './protocol-G-z1lRqo.js';
1
+ export { a as RemoteSignerCapabilities, b as RemoteSignerErrorCode, c as RemoteSignerErrorResponse, d as RemoteSignerMetadata, e as RemoteSignerRequest } from './protocol-nWSt9TTV.js';
2
2
 
3
3
  /**
4
4
  * @solana/connector/server - Route Handlers
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkQST7XLMB_js = require('./chunk-QST7XLMB.js');
3
+ var chunkPNZYYZZS_js = require('./chunk-PNZYYZZS.js');
4
4
 
5
5
  // src/server/route-handlers.ts
6
6
  function jsonResponse(data, status = 200) {
@@ -14,8 +14,11 @@ function errorResponse(code, message, status = 400, details) {
14
14
  error: { code, message, details }
15
15
  }, status);
16
16
  }
17
+ function getEnv(name) {
18
+ return globalThis.process?.env?.[name];
19
+ }
17
20
  function defaultAuthorize(request) {
18
- let token = process.env.CONNECTOR_SIGNER_TOKEN;
21
+ let token = getEnv("CONNECTOR_SIGNER_TOKEN");
19
22
  if (!token)
20
23
  return console.warn("[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests"), false;
21
24
  let authHeader = request.headers.get("Authorization");
@@ -25,7 +28,7 @@ function defaultAuthorize(request) {
25
28
  return (parts.length === 2 && parts[0].toLowerCase() === "bearer" ? parts[1] : authHeader) === token;
26
29
  }
27
30
  async function sendTransaction(rpc, signedTxBytes) {
28
- let base64Tx = chunkQST7XLMB_js.encodeBase64(signedTxBytes), result = await (await fetch(rpc.url, {
31
+ let base64Tx = chunkPNZYYZZS_js.encodeBase64(signedTxBytes), result = await (await fetch(rpc.url, {
29
32
  method: "POST",
30
33
  headers: { "Content-Type": "application/json" },
31
34
  body: JSON.stringify({
@@ -117,36 +120,36 @@ function createRemoteSignerRouteHandlers(config) {
117
120
  case "signTransaction": {
118
121
  if (!body.transaction)
119
122
  return errorResponse("INVALID_REQUEST", "Missing transaction field", 400);
120
- let txBytes = chunkQST7XLMB_js.decodeBase64(body.transaction);
123
+ let txBytes = chunkPNZYYZZS_js.decodeBase64(body.transaction);
121
124
  if (policy?.validateTransaction && !await policy.validateTransaction(txBytes, request))
122
125
  return errorResponse("POLICY_VIOLATION", "Transaction rejected by policy", 403);
123
126
  let signedTx = await signer.signTransaction(txBytes), response = {
124
- signedTransaction: chunkQST7XLMB_js.encodeBase64(signedTx)
127
+ signedTransaction: chunkPNZYYZZS_js.encodeBase64(signedTx)
125
128
  };
126
129
  return jsonResponse(response);
127
130
  }
128
131
  case "signAllTransactions": {
129
132
  if (!body.transactions || !Array.isArray(body.transactions))
130
133
  return errorResponse("INVALID_REQUEST", "Missing transactions array", 400);
131
- let txBytesArray = body.transactions.map((tx) => chunkQST7XLMB_js.decodeBase64(tx));
134
+ let txBytesArray = body.transactions.map((tx) => chunkPNZYYZZS_js.decodeBase64(tx));
132
135
  if (policy?.validateTransaction) {
133
136
  for (let txBytes of txBytesArray)
134
137
  if (!await policy.validateTransaction(txBytes, request))
135
138
  return errorResponse("POLICY_VIOLATION", "Transaction rejected by policy", 403);
136
139
  }
137
140
  let response = {
138
- signedTransactions: (await signer.signAllTransactions(txBytesArray)).map((tx) => chunkQST7XLMB_js.encodeBase64(tx))
141
+ signedTransactions: (await signer.signAllTransactions(txBytesArray)).map((tx) => chunkPNZYYZZS_js.encodeBase64(tx))
139
142
  };
140
143
  return jsonResponse(response);
141
144
  }
142
145
  case "signMessage": {
143
146
  if (!body.message)
144
147
  return errorResponse("INVALID_REQUEST", "Missing message field", 400);
145
- let messageBytes = chunkQST7XLMB_js.decodeBase64(body.message);
148
+ let messageBytes = chunkPNZYYZZS_js.decodeBase64(body.message);
146
149
  if (policy?.validateMessage && !await policy.validateMessage(messageBytes, request))
147
150
  return errorResponse("POLICY_VIOLATION", "Message rejected by policy", 403);
148
151
  let signature = await signer.signMessage(messageBytes), response = {
149
- signature: chunkQST7XLMB_js.encodeBase64(signature)
152
+ signature: chunkPNZYYZZS_js.encodeBase64(signature)
150
153
  };
151
154
  return jsonResponse(response);
152
155
  }
@@ -155,7 +158,7 @@ function createRemoteSignerRouteHandlers(config) {
155
158
  return errorResponse("INVALID_OPERATION", "signAndSendTransaction not enabled", 400);
156
159
  if (!body.transaction)
157
160
  return errorResponse("INVALID_REQUEST", "Missing transaction field", 400);
158
- let txBytes = chunkQST7XLMB_js.decodeBase64(body.transaction);
161
+ let txBytes = chunkPNZYYZZS_js.decodeBase64(body.transaction);
159
162
  if (policy?.validateTransaction && !await policy.validateTransaction(txBytes, request))
160
163
  return errorResponse("POLICY_VIOLATION", "Transaction rejected by policy", 403);
161
164
  let signedTx = await signer.signTransaction(txBytes);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/route-handlers.ts"],"names":["encodeBase64","decodeBase64"],"mappings":"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","file":"server.js","sourcesContent":["/**\n * @solana/connector/server - Route Handlers\n *\n * Creates Next.js Route Handler compatible GET/POST handlers for remote signing.\n * Designed for Node.js runtime (not Edge) to support crypto operations.\n */\n\nimport type {\n RemoteSignerMetadata,\n RemoteSignerCapabilities,\n RemoteSignerRequest,\n SignTransactionResponse,\n SignAllTransactionsResponse,\n SignMessageResponse,\n SignAndSendTransactionResponse,\n RemoteSignerErrorCode,\n RemoteSignerErrorResponse,\n} from '../remote/protocol';\nimport { decodeBase64, encodeBase64 } from '../remote/protocol';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Signer interface that providers must implement\n */\nexport interface RemoteSigner {\n /** Signer's Solana address (base58) */\n readonly address: string;\n\n /** Sign transaction bytes, return signed transaction bytes */\n signTransaction(transactionBytes: Uint8Array): Promise<Uint8Array>;\n\n /** Sign multiple transactions */\n signAllTransactions(transactions: Uint8Array[]): Promise<Uint8Array[]>;\n\n /** Sign a message, return 64-byte signature */\n signMessage(message: Uint8Array): Promise<Uint8Array>;\n\n /** Check if signer is available/healthy */\n isAvailable(): Promise<boolean>;\n}\n\n/**\n * Provider configuration\n */\nexport type ProviderType = 'fireblocks' | 'privy' | 'custom';\n\nexport interface FireblocksProviderConfig {\n type: 'fireblocks';\n /** Fireblocks API key */\n apiKey: string;\n /** RSA private key PEM for JWT signing */\n privateKeyPem: string;\n /** Vault account ID */\n vaultAccountId: string;\n /** Asset ID (default: 'SOL') */\n assetId?: string;\n /** API base URL (default: https://api.fireblocks.io) */\n apiBaseUrl?: string;\n}\n\nexport interface PrivyProviderConfig {\n type: 'privy';\n /** Privy app ID */\n appId: string;\n /** Privy app secret */\n appSecret: string;\n /** Privy wallet ID */\n walletId: string;\n /** API base URL (default: https://api.privy.io/v1) */\n apiBaseUrl?: string;\n}\n\nexport interface CustomProviderConfig {\n type: 'custom';\n /** Custom signer implementation */\n signer: RemoteSigner;\n}\n\nexport type ProviderConfig = FireblocksProviderConfig | PrivyProviderConfig | CustomProviderConfig;\n\n/**\n * Authorization callback\n */\nexport type AuthorizeCallback = (request: Request) => Promise<boolean> | boolean;\n\n/**\n * Policy validation callback\n */\nexport interface PolicyHooks {\n /** Validate a transaction before signing (return false to reject) */\n validateTransaction?: (transactionBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n /** Validate a message before signing (return false to reject) */\n validateMessage?: (messageBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n}\n\n/**\n * RPC configuration for sign+send operations\n */\nexport interface RpcConfig {\n /** Solana RPC endpoint URL */\n url: string;\n /** Commitment level for confirmations */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Route handler configuration\n */\nexport interface RemoteSignerRouteHandlersConfig {\n /** Provider configuration */\n provider: ProviderConfig;\n /**\n * Authorization callback. Default: checks for Authorization header matching CONNECTOR_SIGNER_TOKEN env var.\n * Return true to allow, false to reject.\n */\n authorize?: AuthorizeCallback;\n /** Policy hooks for transaction/message validation */\n policy?: PolicyHooks;\n /** RPC configuration (required for signAndSendTransaction) */\n rpc?: RpcConfig;\n /** Supported chains (default: ['solana:mainnet', 'solana:devnet']) */\n chains?: string[];\n /** Wallet name shown in metadata */\n name?: string;\n /** Wallet icon URL */\n icon?: string;\n}\n\n/**\n * Next.js compatible request/response types\n */\nexport interface NextRequest extends Request {\n // Next.js adds extra properties, but we only need standard Request\n}\n\nexport type NextResponse = Response;\n\n/**\n * Route handlers object returned by the factory\n */\nexport interface RouteHandlers {\n GET: (request: NextRequest) => Promise<NextResponse>;\n POST: (request: NextRequest) => Promise<NextResponse>;\n}\n\n// ============================================================================\n// Helper functions\n// ============================================================================\n\nfunction jsonResponse(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\nfunction errorResponse(code: RemoteSignerErrorCode, message: string, status = 400, details?: unknown): Response {\n const body: RemoteSignerErrorResponse = {\n error: { code, message, details },\n };\n return jsonResponse(body, status);\n}\n\n/**\n * Default authorization: check Authorization header against CONNECTOR_SIGNER_TOKEN env var\n */\nfunction defaultAuthorize(request: Request): boolean {\n const token = process.env.CONNECTOR_SIGNER_TOKEN;\n if (!token) {\n // No token configured = reject all (safe default)\n console.warn('[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests');\n return false;\n }\n\n const authHeader = request.headers.get('Authorization');\n if (!authHeader) {\n return false;\n }\n\n // Support \"Bearer <token>\" format\n const parts = authHeader.split(' ');\n const providedToken = parts.length === 2 && parts[0].toLowerCase() === 'bearer' ? parts[1] : authHeader;\n\n return providedToken === token;\n}\n\n/**\n * Send a signed transaction to Solana RPC\n */\nasync function sendTransaction(rpc: RpcConfig, signedTxBytes: Uint8Array): Promise<string> {\n const base64Tx = encodeBase64(signedTxBytes);\n\n const response = await fetch(rpc.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'sendTransaction',\n params: [\n base64Tx,\n {\n encoding: 'base64',\n skipPreflight: false,\n preflightCommitment: rpc.commitment || 'confirmed',\n },\n ],\n }),\n });\n\n const result = await response.json();\n\n if (result.error) {\n throw new Error(result.error.message || 'RPC error');\n }\n\n return result.result as string;\n}\n\n// ============================================================================\n// Provider loader\n// ============================================================================\n\nlet cachedSigner: RemoteSigner | null = null;\n\nasync function loadSigner(config: ProviderConfig): Promise<RemoteSigner> {\n if (cachedSigner) {\n return cachedSigner;\n }\n\n if (config.type === 'custom') {\n cachedSigner = config.signer;\n return cachedSigner;\n }\n\n if (config.type === 'fireblocks') {\n const { loadFireblocksSigner } = await import('./providers/fireblocks');\n cachedSigner = await loadFireblocksSigner(config);\n return cachedSigner;\n }\n\n if (config.type === 'privy') {\n const { loadPrivySigner } = await import('./providers/privy');\n cachedSigner = await loadPrivySigner(config);\n return cachedSigner;\n }\n\n throw new Error(`Unknown provider type: ${(config as ProviderConfig).type}`);\n}\n\n// ============================================================================\n// Route Handler Factory\n// ============================================================================\n\n/**\n * Create Next.js Route Handlers for remote signing\n *\n * @example\n * ```typescript\n * // app/api/connector-signer/route.ts\n * import { createRemoteSignerRouteHandlers } from '@solana/connector/server';\n *\n * const { GET, POST } = createRemoteSignerRouteHandlers({\n * provider: {\n * type: 'fireblocks',\n * apiKey: process.env.FIREBLOCKS_API_KEY!,\n * privateKeyPem: process.env.FIREBLOCKS_PRIVATE_KEY!,\n * vaultAccountId: process.env.FIREBLOCKS_VAULT_ID!,\n * },\n * rpc: {\n * url: process.env.SOLANA_RPC_URL!,\n * },\n * });\n *\n * export { GET, POST };\n * export const runtime = 'nodejs';\n * ```\n */\nexport function createRemoteSignerRouteHandlers(config: RemoteSignerRouteHandlersConfig): RouteHandlers {\n const {\n provider,\n authorize = defaultAuthorize,\n policy,\n rpc,\n chains = ['solana:mainnet', 'solana:devnet'],\n name = 'Remote Signer',\n icon,\n } = config;\n\n // GET handler: return signer metadata\n async function GET(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Check availability\n const available = await signer.isAvailable();\n if (!available) {\n return errorResponse('PROVIDER_ERROR', 'Signer not available', 503);\n }\n\n // Build capabilities\n const capabilities: RemoteSignerCapabilities = {\n signTransaction: true,\n signAllTransactions: true,\n signMessage: true,\n signAndSendTransaction: Boolean(rpc),\n };\n\n // Build metadata response\n const metadata: RemoteSignerMetadata = {\n address: signer.address,\n chains,\n capabilities,\n name,\n icon,\n };\n\n return jsonResponse(metadata);\n } catch (error) {\n console.error('[connector/server] GET error:', error);\n return errorResponse(\n 'INTERNAL_ERROR',\n error instanceof Error ? error.message : 'Internal server error',\n 500,\n );\n }\n }\n\n // POST handler: handle signing operations\n async function POST(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Parse request body\n let body: RemoteSignerRequest;\n try {\n body = await request.json();\n } catch {\n return errorResponse('INVALID_REQUEST', 'Invalid JSON body', 400);\n }\n\n if (!body.operation) {\n return errorResponse('INVALID_REQUEST', 'Missing operation field', 400);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Handle operations\n switch (body.operation) {\n case 'signTransaction': {\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n const signedTx = await signer.signTransaction(txBytes);\n const response: SignTransactionResponse = {\n signedTransaction: encodeBase64(signedTx),\n };\n return jsonResponse(response);\n }\n\n case 'signAllTransactions': {\n if (!body.transactions || !Array.isArray(body.transactions)) {\n return errorResponse('INVALID_REQUEST', 'Missing transactions array', 400);\n }\n\n const txBytesArray = body.transactions.map(tx => decodeBase64(tx));\n\n // Policy check for each transaction\n if (policy?.validateTransaction) {\n for (const txBytes of txBytesArray) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n }\n\n const signedTxs = await signer.signAllTransactions(txBytesArray);\n const response: SignAllTransactionsResponse = {\n signedTransactions: signedTxs.map(tx => encodeBase64(tx)),\n };\n return jsonResponse(response);\n }\n\n case 'signMessage': {\n if (!body.message) {\n return errorResponse('INVALID_REQUEST', 'Missing message field', 400);\n }\n\n const messageBytes = decodeBase64(body.message);\n\n // Policy check\n if (policy?.validateMessage) {\n const allowed = await policy.validateMessage(messageBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Message rejected by policy', 403);\n }\n }\n\n const signature = await signer.signMessage(messageBytes);\n const response: SignMessageResponse = {\n signature: encodeBase64(signature),\n };\n return jsonResponse(response);\n }\n\n case 'signAndSendTransaction': {\n if (!rpc) {\n return errorResponse('INVALID_OPERATION', 'signAndSendTransaction not enabled', 400);\n }\n\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n // Sign\n const signedTx = await signer.signTransaction(txBytes);\n\n // Send\n try {\n const signature = await sendTransaction(rpc, signedTx);\n const response: SignAndSendTransactionResponse = { signature };\n return jsonResponse(response);\n } catch (error) {\n return errorResponse(\n 'SEND_FAILED',\n error instanceof Error ? error.message : 'Failed to send transaction',\n 500,\n );\n }\n }\n\n default:\n return errorResponse(\n 'INVALID_OPERATION',\n `Unknown operation: ${(body as { operation: string }).operation}`,\n 400,\n );\n }\n } catch (error) {\n console.error('[connector/server] POST error:', error);\n\n // Check for known signer errors\n if (error instanceof Error) {\n if (error.message.includes('rate limit') || error.message.includes('429')) {\n return errorResponse('PROVIDER_ERROR', 'Rate limited, please retry', 429);\n }\n }\n\n return errorResponse('SIGNING_FAILED', error instanceof Error ? error.message : 'Signing failed', 500);\n }\n }\n\n return { GET, POST };\n}\n"]}
1
+ {"version":3,"sources":["../src/server/route-handlers.ts"],"names":["encodeBase64","decodeBase64"],"mappings":"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","file":"server.js","sourcesContent":["/**\n * @solana/connector/server - Route Handlers\n *\n * Creates Next.js Route Handler compatible GET/POST handlers for remote signing.\n * Designed for Node.js runtime (not Edge) to support crypto operations.\n */\n\nimport type {\n RemoteSignerMetadata,\n RemoteSignerCapabilities,\n RemoteSignerRequest,\n SignTransactionResponse,\n SignAllTransactionsResponse,\n SignMessageResponse,\n SignAndSendTransactionResponse,\n RemoteSignerErrorCode,\n RemoteSignerErrorResponse,\n} from '../remote/protocol';\nimport { decodeBase64, encodeBase64 } from '../remote/protocol';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Signer interface that providers must implement\n */\nexport interface RemoteSigner {\n /** Signer's Solana address (base58) */\n readonly address: string;\n\n /** Sign transaction bytes, return signed transaction bytes */\n signTransaction(transactionBytes: Uint8Array): Promise<Uint8Array>;\n\n /** Sign multiple transactions */\n signAllTransactions(transactions: Uint8Array[]): Promise<Uint8Array[]>;\n\n /** Sign a message, return 64-byte signature */\n signMessage(message: Uint8Array): Promise<Uint8Array>;\n\n /** Check if signer is available/healthy */\n isAvailable(): Promise<boolean>;\n}\n\n/**\n * Provider configuration\n */\nexport type ProviderType = 'fireblocks' | 'privy' | 'custom';\n\nexport interface FireblocksProviderConfig {\n type: 'fireblocks';\n /** Fireblocks API key */\n apiKey: string;\n /** RSA private key PEM for JWT signing */\n privateKeyPem: string;\n /** Vault account ID */\n vaultAccountId: string;\n /** Asset ID (default: 'SOL') */\n assetId?: string;\n /** API base URL (default: https://api.fireblocks.io) */\n apiBaseUrl?: string;\n}\n\nexport interface PrivyProviderConfig {\n type: 'privy';\n /** Privy app ID */\n appId: string;\n /** Privy app secret */\n appSecret: string;\n /** Privy wallet ID */\n walletId: string;\n /** API base URL (default: https://api.privy.io/v1) */\n apiBaseUrl?: string;\n}\n\nexport interface CustomProviderConfig {\n type: 'custom';\n /** Custom signer implementation */\n signer: RemoteSigner;\n}\n\nexport type ProviderConfig = FireblocksProviderConfig | PrivyProviderConfig | CustomProviderConfig;\n\n/**\n * Authorization callback\n */\nexport type AuthorizeCallback = (request: Request) => Promise<boolean> | boolean;\n\n/**\n * Policy validation callback\n */\nexport interface PolicyHooks {\n /** Validate a transaction before signing (return false to reject) */\n validateTransaction?: (transactionBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n /** Validate a message before signing (return false to reject) */\n validateMessage?: (messageBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n}\n\n/**\n * RPC configuration for sign+send operations\n */\nexport interface RpcConfig {\n /** Solana RPC endpoint URL */\n url: string;\n /** Commitment level for confirmations */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Route handler configuration\n */\nexport interface RemoteSignerRouteHandlersConfig {\n /** Provider configuration */\n provider: ProviderConfig;\n /**\n * Authorization callback. Default: checks for Authorization header matching CONNECTOR_SIGNER_TOKEN env var.\n * Return true to allow, false to reject.\n */\n authorize?: AuthorizeCallback;\n /** Policy hooks for transaction/message validation */\n policy?: PolicyHooks;\n /** RPC configuration (required for signAndSendTransaction) */\n rpc?: RpcConfig;\n /** Supported chains (default: ['solana:mainnet', 'solana:devnet']) */\n chains?: string[];\n /** Wallet name shown in metadata */\n name?: string;\n /** Wallet icon URL */\n icon?: string;\n}\n\n/**\n * Next.js compatible request/response types\n */\nexport interface NextRequest extends Request {\n // Next.js adds extra properties, but we only need standard Request\n}\n\nexport type NextResponse = Response;\n\n/**\n * Route handlers object returned by the factory\n */\nexport interface RouteHandlers {\n GET: (request: NextRequest) => Promise<NextResponse>;\n POST: (request: NextRequest) => Promise<NextResponse>;\n}\n\n// ============================================================================\n// Helper functions\n// ============================================================================\n\nfunction jsonResponse(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\nfunction errorResponse(code: RemoteSignerErrorCode, message: string, status = 400, details?: unknown): Response {\n const body: RemoteSignerErrorResponse = {\n error: { code, message, details },\n };\n return jsonResponse(body, status);\n}\n\nfunction getEnv(name: string): string | undefined {\n return (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.[name];\n}\n\n/**\n * Default authorization: check Authorization header against CONNECTOR_SIGNER_TOKEN env var\n */\nfunction defaultAuthorize(request: Request): boolean {\n const token = getEnv('CONNECTOR_SIGNER_TOKEN');\n if (!token) {\n // No token configured = reject all (safe default)\n console.warn('[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests');\n return false;\n }\n\n const authHeader = request.headers.get('Authorization');\n if (!authHeader) {\n return false;\n }\n\n // Support \"Bearer <token>\" format\n const parts = authHeader.split(' ');\n const providedToken = parts.length === 2 && parts[0].toLowerCase() === 'bearer' ? parts[1] : authHeader;\n\n return providedToken === token;\n}\n\n/**\n * Send a signed transaction to Solana RPC\n */\nasync function sendTransaction(rpc: RpcConfig, signedTxBytes: Uint8Array): Promise<string> {\n const base64Tx = encodeBase64(signedTxBytes);\n\n const response = await fetch(rpc.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'sendTransaction',\n params: [\n base64Tx,\n {\n encoding: 'base64',\n skipPreflight: false,\n preflightCommitment: rpc.commitment || 'confirmed',\n },\n ],\n }),\n });\n\n const result = await response.json();\n\n if (result.error) {\n throw new Error(result.error.message || 'RPC error');\n }\n\n return result.result as string;\n}\n\n// ============================================================================\n// Provider loader\n// ============================================================================\n\nlet cachedSigner: RemoteSigner | null = null;\n\nasync function loadSigner(config: ProviderConfig): Promise<RemoteSigner> {\n if (cachedSigner) {\n return cachedSigner;\n }\n\n if (config.type === 'custom') {\n cachedSigner = config.signer;\n return cachedSigner;\n }\n\n if (config.type === 'fireblocks') {\n const { loadFireblocksSigner } = await import('./providers/fireblocks');\n cachedSigner = await loadFireblocksSigner(config);\n return cachedSigner;\n }\n\n if (config.type === 'privy') {\n const { loadPrivySigner } = await import('./providers/privy');\n cachedSigner = await loadPrivySigner(config);\n return cachedSigner;\n }\n\n throw new Error(`Unknown provider type: ${(config as ProviderConfig).type}`);\n}\n\n// ============================================================================\n// Route Handler Factory\n// ============================================================================\n\n/**\n * Create Next.js Route Handlers for remote signing\n *\n * @example\n * ```typescript\n * // app/api/connector-signer/route.ts\n * import { createRemoteSignerRouteHandlers } from '@solana/connector/server';\n *\n * const { GET, POST } = createRemoteSignerRouteHandlers({\n * provider: {\n * type: 'fireblocks',\n * apiKey: process.env.FIREBLOCKS_API_KEY!,\n * privateKeyPem: process.env.FIREBLOCKS_PRIVATE_KEY!,\n * vaultAccountId: process.env.FIREBLOCKS_VAULT_ID!,\n * },\n * rpc: {\n * url: process.env.SOLANA_RPC_URL!,\n * },\n * });\n *\n * export { GET, POST };\n * export const runtime = 'nodejs';\n * ```\n */\nexport function createRemoteSignerRouteHandlers(config: RemoteSignerRouteHandlersConfig): RouteHandlers {\n const {\n provider,\n authorize = defaultAuthorize,\n policy,\n rpc,\n chains = ['solana:mainnet', 'solana:devnet'],\n name = 'Remote Signer',\n icon,\n } = config;\n\n // GET handler: return signer metadata\n async function GET(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Check availability\n const available = await signer.isAvailable();\n if (!available) {\n return errorResponse('PROVIDER_ERROR', 'Signer not available', 503);\n }\n\n // Build capabilities\n const capabilities: RemoteSignerCapabilities = {\n signTransaction: true,\n signAllTransactions: true,\n signMessage: true,\n signAndSendTransaction: Boolean(rpc),\n };\n\n // Build metadata response\n const metadata: RemoteSignerMetadata = {\n address: signer.address,\n chains,\n capabilities,\n name,\n icon,\n };\n\n return jsonResponse(metadata);\n } catch (error) {\n console.error('[connector/server] GET error:', error);\n return errorResponse(\n 'INTERNAL_ERROR',\n error instanceof Error ? error.message : 'Internal server error',\n 500,\n );\n }\n }\n\n // POST handler: handle signing operations\n async function POST(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Parse request body\n let body: RemoteSignerRequest;\n try {\n body = await request.json();\n } catch {\n return errorResponse('INVALID_REQUEST', 'Invalid JSON body', 400);\n }\n\n if (!body.operation) {\n return errorResponse('INVALID_REQUEST', 'Missing operation field', 400);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Handle operations\n switch (body.operation) {\n case 'signTransaction': {\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n const signedTx = await signer.signTransaction(txBytes);\n const response: SignTransactionResponse = {\n signedTransaction: encodeBase64(signedTx),\n };\n return jsonResponse(response);\n }\n\n case 'signAllTransactions': {\n if (!body.transactions || !Array.isArray(body.transactions)) {\n return errorResponse('INVALID_REQUEST', 'Missing transactions array', 400);\n }\n\n const txBytesArray = body.transactions.map(tx => decodeBase64(tx));\n\n // Policy check for each transaction\n if (policy?.validateTransaction) {\n for (const txBytes of txBytesArray) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n }\n\n const signedTxs = await signer.signAllTransactions(txBytesArray);\n const response: SignAllTransactionsResponse = {\n signedTransactions: signedTxs.map(tx => encodeBase64(tx)),\n };\n return jsonResponse(response);\n }\n\n case 'signMessage': {\n if (!body.message) {\n return errorResponse('INVALID_REQUEST', 'Missing message field', 400);\n }\n\n const messageBytes = decodeBase64(body.message);\n\n // Policy check\n if (policy?.validateMessage) {\n const allowed = await policy.validateMessage(messageBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Message rejected by policy', 403);\n }\n }\n\n const signature = await signer.signMessage(messageBytes);\n const response: SignMessageResponse = {\n signature: encodeBase64(signature),\n };\n return jsonResponse(response);\n }\n\n case 'signAndSendTransaction': {\n if (!rpc) {\n return errorResponse('INVALID_OPERATION', 'signAndSendTransaction not enabled', 400);\n }\n\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n // Sign\n const signedTx = await signer.signTransaction(txBytes);\n\n // Send\n try {\n const signature = await sendTransaction(rpc, signedTx);\n const response: SignAndSendTransactionResponse = { signature };\n return jsonResponse(response);\n } catch (error) {\n return errorResponse(\n 'SEND_FAILED',\n error instanceof Error ? error.message : 'Failed to send transaction',\n 500,\n );\n }\n }\n\n default:\n return errorResponse(\n 'INVALID_OPERATION',\n `Unknown operation: ${(body as { operation: string }).operation}`,\n 400,\n );\n }\n } catch (error) {\n console.error('[connector/server] POST error:', error);\n\n // Check for known signer errors\n if (error instanceof Error) {\n if (error.message.includes('rate limit') || error.message.includes('429')) {\n return errorResponse('PROVIDER_ERROR', 'Rate limited, please retry', 429);\n }\n }\n\n return errorResponse('SIGNING_FAILED', error instanceof Error ? error.message : 'Signing failed', 500);\n }\n }\n\n return { GET, POST };\n}\n"]}
package/dist/server.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { decodeBase64, encodeBase64 } from './chunk-E3DAIOYS.mjs';
1
+ import { decodeBase64, encodeBase64 } from './chunk-GM3PZ3WK.mjs';
2
2
 
3
3
  // src/server/route-handlers.ts
4
4
  function jsonResponse(data, status = 200) {
@@ -12,8 +12,11 @@ function errorResponse(code, message, status = 400, details) {
12
12
  error: { code, message, details }
13
13
  }, status);
14
14
  }
15
+ function getEnv(name) {
16
+ return globalThis.process?.env?.[name];
17
+ }
15
18
  function defaultAuthorize(request) {
16
- let token = process.env.CONNECTOR_SIGNER_TOKEN;
19
+ let token = getEnv("CONNECTOR_SIGNER_TOKEN");
17
20
  if (!token)
18
21
  return console.warn("[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests"), false;
19
22
  let authHeader = request.headers.get("Authorization");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/route-handlers.ts"],"names":[],"mappings":"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","file":"server.mjs","sourcesContent":["/**\n * @solana/connector/server - Route Handlers\n *\n * Creates Next.js Route Handler compatible GET/POST handlers for remote signing.\n * Designed for Node.js runtime (not Edge) to support crypto operations.\n */\n\nimport type {\n RemoteSignerMetadata,\n RemoteSignerCapabilities,\n RemoteSignerRequest,\n SignTransactionResponse,\n SignAllTransactionsResponse,\n SignMessageResponse,\n SignAndSendTransactionResponse,\n RemoteSignerErrorCode,\n RemoteSignerErrorResponse,\n} from '../remote/protocol';\nimport { decodeBase64, encodeBase64 } from '../remote/protocol';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Signer interface that providers must implement\n */\nexport interface RemoteSigner {\n /** Signer's Solana address (base58) */\n readonly address: string;\n\n /** Sign transaction bytes, return signed transaction bytes */\n signTransaction(transactionBytes: Uint8Array): Promise<Uint8Array>;\n\n /** Sign multiple transactions */\n signAllTransactions(transactions: Uint8Array[]): Promise<Uint8Array[]>;\n\n /** Sign a message, return 64-byte signature */\n signMessage(message: Uint8Array): Promise<Uint8Array>;\n\n /** Check if signer is available/healthy */\n isAvailable(): Promise<boolean>;\n}\n\n/**\n * Provider configuration\n */\nexport type ProviderType = 'fireblocks' | 'privy' | 'custom';\n\nexport interface FireblocksProviderConfig {\n type: 'fireblocks';\n /** Fireblocks API key */\n apiKey: string;\n /** RSA private key PEM for JWT signing */\n privateKeyPem: string;\n /** Vault account ID */\n vaultAccountId: string;\n /** Asset ID (default: 'SOL') */\n assetId?: string;\n /** API base URL (default: https://api.fireblocks.io) */\n apiBaseUrl?: string;\n}\n\nexport interface PrivyProviderConfig {\n type: 'privy';\n /** Privy app ID */\n appId: string;\n /** Privy app secret */\n appSecret: string;\n /** Privy wallet ID */\n walletId: string;\n /** API base URL (default: https://api.privy.io/v1) */\n apiBaseUrl?: string;\n}\n\nexport interface CustomProviderConfig {\n type: 'custom';\n /** Custom signer implementation */\n signer: RemoteSigner;\n}\n\nexport type ProviderConfig = FireblocksProviderConfig | PrivyProviderConfig | CustomProviderConfig;\n\n/**\n * Authorization callback\n */\nexport type AuthorizeCallback = (request: Request) => Promise<boolean> | boolean;\n\n/**\n * Policy validation callback\n */\nexport interface PolicyHooks {\n /** Validate a transaction before signing (return false to reject) */\n validateTransaction?: (transactionBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n /** Validate a message before signing (return false to reject) */\n validateMessage?: (messageBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n}\n\n/**\n * RPC configuration for sign+send operations\n */\nexport interface RpcConfig {\n /** Solana RPC endpoint URL */\n url: string;\n /** Commitment level for confirmations */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Route handler configuration\n */\nexport interface RemoteSignerRouteHandlersConfig {\n /** Provider configuration */\n provider: ProviderConfig;\n /**\n * Authorization callback. Default: checks for Authorization header matching CONNECTOR_SIGNER_TOKEN env var.\n * Return true to allow, false to reject.\n */\n authorize?: AuthorizeCallback;\n /** Policy hooks for transaction/message validation */\n policy?: PolicyHooks;\n /** RPC configuration (required for signAndSendTransaction) */\n rpc?: RpcConfig;\n /** Supported chains (default: ['solana:mainnet', 'solana:devnet']) */\n chains?: string[];\n /** Wallet name shown in metadata */\n name?: string;\n /** Wallet icon URL */\n icon?: string;\n}\n\n/**\n * Next.js compatible request/response types\n */\nexport interface NextRequest extends Request {\n // Next.js adds extra properties, but we only need standard Request\n}\n\nexport type NextResponse = Response;\n\n/**\n * Route handlers object returned by the factory\n */\nexport interface RouteHandlers {\n GET: (request: NextRequest) => Promise<NextResponse>;\n POST: (request: NextRequest) => Promise<NextResponse>;\n}\n\n// ============================================================================\n// Helper functions\n// ============================================================================\n\nfunction jsonResponse(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\nfunction errorResponse(code: RemoteSignerErrorCode, message: string, status = 400, details?: unknown): Response {\n const body: RemoteSignerErrorResponse = {\n error: { code, message, details },\n };\n return jsonResponse(body, status);\n}\n\n/**\n * Default authorization: check Authorization header against CONNECTOR_SIGNER_TOKEN env var\n */\nfunction defaultAuthorize(request: Request): boolean {\n const token = process.env.CONNECTOR_SIGNER_TOKEN;\n if (!token) {\n // No token configured = reject all (safe default)\n console.warn('[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests');\n return false;\n }\n\n const authHeader = request.headers.get('Authorization');\n if (!authHeader) {\n return false;\n }\n\n // Support \"Bearer <token>\" format\n const parts = authHeader.split(' ');\n const providedToken = parts.length === 2 && parts[0].toLowerCase() === 'bearer' ? parts[1] : authHeader;\n\n return providedToken === token;\n}\n\n/**\n * Send a signed transaction to Solana RPC\n */\nasync function sendTransaction(rpc: RpcConfig, signedTxBytes: Uint8Array): Promise<string> {\n const base64Tx = encodeBase64(signedTxBytes);\n\n const response = await fetch(rpc.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'sendTransaction',\n params: [\n base64Tx,\n {\n encoding: 'base64',\n skipPreflight: false,\n preflightCommitment: rpc.commitment || 'confirmed',\n },\n ],\n }),\n });\n\n const result = await response.json();\n\n if (result.error) {\n throw new Error(result.error.message || 'RPC error');\n }\n\n return result.result as string;\n}\n\n// ============================================================================\n// Provider loader\n// ============================================================================\n\nlet cachedSigner: RemoteSigner | null = null;\n\nasync function loadSigner(config: ProviderConfig): Promise<RemoteSigner> {\n if (cachedSigner) {\n return cachedSigner;\n }\n\n if (config.type === 'custom') {\n cachedSigner = config.signer;\n return cachedSigner;\n }\n\n if (config.type === 'fireblocks') {\n const { loadFireblocksSigner } = await import('./providers/fireblocks');\n cachedSigner = await loadFireblocksSigner(config);\n return cachedSigner;\n }\n\n if (config.type === 'privy') {\n const { loadPrivySigner } = await import('./providers/privy');\n cachedSigner = await loadPrivySigner(config);\n return cachedSigner;\n }\n\n throw new Error(`Unknown provider type: ${(config as ProviderConfig).type}`);\n}\n\n// ============================================================================\n// Route Handler Factory\n// ============================================================================\n\n/**\n * Create Next.js Route Handlers for remote signing\n *\n * @example\n * ```typescript\n * // app/api/connector-signer/route.ts\n * import { createRemoteSignerRouteHandlers } from '@solana/connector/server';\n *\n * const { GET, POST } = createRemoteSignerRouteHandlers({\n * provider: {\n * type: 'fireblocks',\n * apiKey: process.env.FIREBLOCKS_API_KEY!,\n * privateKeyPem: process.env.FIREBLOCKS_PRIVATE_KEY!,\n * vaultAccountId: process.env.FIREBLOCKS_VAULT_ID!,\n * },\n * rpc: {\n * url: process.env.SOLANA_RPC_URL!,\n * },\n * });\n *\n * export { GET, POST };\n * export const runtime = 'nodejs';\n * ```\n */\nexport function createRemoteSignerRouteHandlers(config: RemoteSignerRouteHandlersConfig): RouteHandlers {\n const {\n provider,\n authorize = defaultAuthorize,\n policy,\n rpc,\n chains = ['solana:mainnet', 'solana:devnet'],\n name = 'Remote Signer',\n icon,\n } = config;\n\n // GET handler: return signer metadata\n async function GET(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Check availability\n const available = await signer.isAvailable();\n if (!available) {\n return errorResponse('PROVIDER_ERROR', 'Signer not available', 503);\n }\n\n // Build capabilities\n const capabilities: RemoteSignerCapabilities = {\n signTransaction: true,\n signAllTransactions: true,\n signMessage: true,\n signAndSendTransaction: Boolean(rpc),\n };\n\n // Build metadata response\n const metadata: RemoteSignerMetadata = {\n address: signer.address,\n chains,\n capabilities,\n name,\n icon,\n };\n\n return jsonResponse(metadata);\n } catch (error) {\n console.error('[connector/server] GET error:', error);\n return errorResponse(\n 'INTERNAL_ERROR',\n error instanceof Error ? error.message : 'Internal server error',\n 500,\n );\n }\n }\n\n // POST handler: handle signing operations\n async function POST(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Parse request body\n let body: RemoteSignerRequest;\n try {\n body = await request.json();\n } catch {\n return errorResponse('INVALID_REQUEST', 'Invalid JSON body', 400);\n }\n\n if (!body.operation) {\n return errorResponse('INVALID_REQUEST', 'Missing operation field', 400);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Handle operations\n switch (body.operation) {\n case 'signTransaction': {\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n const signedTx = await signer.signTransaction(txBytes);\n const response: SignTransactionResponse = {\n signedTransaction: encodeBase64(signedTx),\n };\n return jsonResponse(response);\n }\n\n case 'signAllTransactions': {\n if (!body.transactions || !Array.isArray(body.transactions)) {\n return errorResponse('INVALID_REQUEST', 'Missing transactions array', 400);\n }\n\n const txBytesArray = body.transactions.map(tx => decodeBase64(tx));\n\n // Policy check for each transaction\n if (policy?.validateTransaction) {\n for (const txBytes of txBytesArray) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n }\n\n const signedTxs = await signer.signAllTransactions(txBytesArray);\n const response: SignAllTransactionsResponse = {\n signedTransactions: signedTxs.map(tx => encodeBase64(tx)),\n };\n return jsonResponse(response);\n }\n\n case 'signMessage': {\n if (!body.message) {\n return errorResponse('INVALID_REQUEST', 'Missing message field', 400);\n }\n\n const messageBytes = decodeBase64(body.message);\n\n // Policy check\n if (policy?.validateMessage) {\n const allowed = await policy.validateMessage(messageBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Message rejected by policy', 403);\n }\n }\n\n const signature = await signer.signMessage(messageBytes);\n const response: SignMessageResponse = {\n signature: encodeBase64(signature),\n };\n return jsonResponse(response);\n }\n\n case 'signAndSendTransaction': {\n if (!rpc) {\n return errorResponse('INVALID_OPERATION', 'signAndSendTransaction not enabled', 400);\n }\n\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n // Sign\n const signedTx = await signer.signTransaction(txBytes);\n\n // Send\n try {\n const signature = await sendTransaction(rpc, signedTx);\n const response: SignAndSendTransactionResponse = { signature };\n return jsonResponse(response);\n } catch (error) {\n return errorResponse(\n 'SEND_FAILED',\n error instanceof Error ? error.message : 'Failed to send transaction',\n 500,\n );\n }\n }\n\n default:\n return errorResponse(\n 'INVALID_OPERATION',\n `Unknown operation: ${(body as { operation: string }).operation}`,\n 400,\n );\n }\n } catch (error) {\n console.error('[connector/server] POST error:', error);\n\n // Check for known signer errors\n if (error instanceof Error) {\n if (error.message.includes('rate limit') || error.message.includes('429')) {\n return errorResponse('PROVIDER_ERROR', 'Rate limited, please retry', 429);\n }\n }\n\n return errorResponse('SIGNING_FAILED', error instanceof Error ? error.message : 'Signing failed', 500);\n }\n }\n\n return { GET, POST };\n}\n"]}
1
+ {"version":3,"sources":["../src/server/route-handlers.ts"],"names":[],"mappings":"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","file":"server.mjs","sourcesContent":["/**\n * @solana/connector/server - Route Handlers\n *\n * Creates Next.js Route Handler compatible GET/POST handlers for remote signing.\n * Designed for Node.js runtime (not Edge) to support crypto operations.\n */\n\nimport type {\n RemoteSignerMetadata,\n RemoteSignerCapabilities,\n RemoteSignerRequest,\n SignTransactionResponse,\n SignAllTransactionsResponse,\n SignMessageResponse,\n SignAndSendTransactionResponse,\n RemoteSignerErrorCode,\n RemoteSignerErrorResponse,\n} from '../remote/protocol';\nimport { decodeBase64, encodeBase64 } from '../remote/protocol';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Signer interface that providers must implement\n */\nexport interface RemoteSigner {\n /** Signer's Solana address (base58) */\n readonly address: string;\n\n /** Sign transaction bytes, return signed transaction bytes */\n signTransaction(transactionBytes: Uint8Array): Promise<Uint8Array>;\n\n /** Sign multiple transactions */\n signAllTransactions(transactions: Uint8Array[]): Promise<Uint8Array[]>;\n\n /** Sign a message, return 64-byte signature */\n signMessage(message: Uint8Array): Promise<Uint8Array>;\n\n /** Check if signer is available/healthy */\n isAvailable(): Promise<boolean>;\n}\n\n/**\n * Provider configuration\n */\nexport type ProviderType = 'fireblocks' | 'privy' | 'custom';\n\nexport interface FireblocksProviderConfig {\n type: 'fireblocks';\n /** Fireblocks API key */\n apiKey: string;\n /** RSA private key PEM for JWT signing */\n privateKeyPem: string;\n /** Vault account ID */\n vaultAccountId: string;\n /** Asset ID (default: 'SOL') */\n assetId?: string;\n /** API base URL (default: https://api.fireblocks.io) */\n apiBaseUrl?: string;\n}\n\nexport interface PrivyProviderConfig {\n type: 'privy';\n /** Privy app ID */\n appId: string;\n /** Privy app secret */\n appSecret: string;\n /** Privy wallet ID */\n walletId: string;\n /** API base URL (default: https://api.privy.io/v1) */\n apiBaseUrl?: string;\n}\n\nexport interface CustomProviderConfig {\n type: 'custom';\n /** Custom signer implementation */\n signer: RemoteSigner;\n}\n\nexport type ProviderConfig = FireblocksProviderConfig | PrivyProviderConfig | CustomProviderConfig;\n\n/**\n * Authorization callback\n */\nexport type AuthorizeCallback = (request: Request) => Promise<boolean> | boolean;\n\n/**\n * Policy validation callback\n */\nexport interface PolicyHooks {\n /** Validate a transaction before signing (return false to reject) */\n validateTransaction?: (transactionBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n /** Validate a message before signing (return false to reject) */\n validateMessage?: (messageBytes: Uint8Array, request: Request) => Promise<boolean> | boolean;\n}\n\n/**\n * RPC configuration for sign+send operations\n */\nexport interface RpcConfig {\n /** Solana RPC endpoint URL */\n url: string;\n /** Commitment level for confirmations */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Route handler configuration\n */\nexport interface RemoteSignerRouteHandlersConfig {\n /** Provider configuration */\n provider: ProviderConfig;\n /**\n * Authorization callback. Default: checks for Authorization header matching CONNECTOR_SIGNER_TOKEN env var.\n * Return true to allow, false to reject.\n */\n authorize?: AuthorizeCallback;\n /** Policy hooks for transaction/message validation */\n policy?: PolicyHooks;\n /** RPC configuration (required for signAndSendTransaction) */\n rpc?: RpcConfig;\n /** Supported chains (default: ['solana:mainnet', 'solana:devnet']) */\n chains?: string[];\n /** Wallet name shown in metadata */\n name?: string;\n /** Wallet icon URL */\n icon?: string;\n}\n\n/**\n * Next.js compatible request/response types\n */\nexport interface NextRequest extends Request {\n // Next.js adds extra properties, but we only need standard Request\n}\n\nexport type NextResponse = Response;\n\n/**\n * Route handlers object returned by the factory\n */\nexport interface RouteHandlers {\n GET: (request: NextRequest) => Promise<NextResponse>;\n POST: (request: NextRequest) => Promise<NextResponse>;\n}\n\n// ============================================================================\n// Helper functions\n// ============================================================================\n\nfunction jsonResponse(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\nfunction errorResponse(code: RemoteSignerErrorCode, message: string, status = 400, details?: unknown): Response {\n const body: RemoteSignerErrorResponse = {\n error: { code, message, details },\n };\n return jsonResponse(body, status);\n}\n\nfunction getEnv(name: string): string | undefined {\n return (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.[name];\n}\n\n/**\n * Default authorization: check Authorization header against CONNECTOR_SIGNER_TOKEN env var\n */\nfunction defaultAuthorize(request: Request): boolean {\n const token = getEnv('CONNECTOR_SIGNER_TOKEN');\n if (!token) {\n // No token configured = reject all (safe default)\n console.warn('[connector/server] CONNECTOR_SIGNER_TOKEN not set - rejecting all requests');\n return false;\n }\n\n const authHeader = request.headers.get('Authorization');\n if (!authHeader) {\n return false;\n }\n\n // Support \"Bearer <token>\" format\n const parts = authHeader.split(' ');\n const providedToken = parts.length === 2 && parts[0].toLowerCase() === 'bearer' ? parts[1] : authHeader;\n\n return providedToken === token;\n}\n\n/**\n * Send a signed transaction to Solana RPC\n */\nasync function sendTransaction(rpc: RpcConfig, signedTxBytes: Uint8Array): Promise<string> {\n const base64Tx = encodeBase64(signedTxBytes);\n\n const response = await fetch(rpc.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'sendTransaction',\n params: [\n base64Tx,\n {\n encoding: 'base64',\n skipPreflight: false,\n preflightCommitment: rpc.commitment || 'confirmed',\n },\n ],\n }),\n });\n\n const result = await response.json();\n\n if (result.error) {\n throw new Error(result.error.message || 'RPC error');\n }\n\n return result.result as string;\n}\n\n// ============================================================================\n// Provider loader\n// ============================================================================\n\nlet cachedSigner: RemoteSigner | null = null;\n\nasync function loadSigner(config: ProviderConfig): Promise<RemoteSigner> {\n if (cachedSigner) {\n return cachedSigner;\n }\n\n if (config.type === 'custom') {\n cachedSigner = config.signer;\n return cachedSigner;\n }\n\n if (config.type === 'fireblocks') {\n const { loadFireblocksSigner } = await import('./providers/fireblocks');\n cachedSigner = await loadFireblocksSigner(config);\n return cachedSigner;\n }\n\n if (config.type === 'privy') {\n const { loadPrivySigner } = await import('./providers/privy');\n cachedSigner = await loadPrivySigner(config);\n return cachedSigner;\n }\n\n throw new Error(`Unknown provider type: ${(config as ProviderConfig).type}`);\n}\n\n// ============================================================================\n// Route Handler Factory\n// ============================================================================\n\n/**\n * Create Next.js Route Handlers for remote signing\n *\n * @example\n * ```typescript\n * // app/api/connector-signer/route.ts\n * import { createRemoteSignerRouteHandlers } from '@solana/connector/server';\n *\n * const { GET, POST } = createRemoteSignerRouteHandlers({\n * provider: {\n * type: 'fireblocks',\n * apiKey: process.env.FIREBLOCKS_API_KEY!,\n * privateKeyPem: process.env.FIREBLOCKS_PRIVATE_KEY!,\n * vaultAccountId: process.env.FIREBLOCKS_VAULT_ID!,\n * },\n * rpc: {\n * url: process.env.SOLANA_RPC_URL!,\n * },\n * });\n *\n * export { GET, POST };\n * export const runtime = 'nodejs';\n * ```\n */\nexport function createRemoteSignerRouteHandlers(config: RemoteSignerRouteHandlersConfig): RouteHandlers {\n const {\n provider,\n authorize = defaultAuthorize,\n policy,\n rpc,\n chains = ['solana:mainnet', 'solana:devnet'],\n name = 'Remote Signer',\n icon,\n } = config;\n\n // GET handler: return signer metadata\n async function GET(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Check availability\n const available = await signer.isAvailable();\n if (!available) {\n return errorResponse('PROVIDER_ERROR', 'Signer not available', 503);\n }\n\n // Build capabilities\n const capabilities: RemoteSignerCapabilities = {\n signTransaction: true,\n signAllTransactions: true,\n signMessage: true,\n signAndSendTransaction: Boolean(rpc),\n };\n\n // Build metadata response\n const metadata: RemoteSignerMetadata = {\n address: signer.address,\n chains,\n capabilities,\n name,\n icon,\n };\n\n return jsonResponse(metadata);\n } catch (error) {\n console.error('[connector/server] GET error:', error);\n return errorResponse(\n 'INTERNAL_ERROR',\n error instanceof Error ? error.message : 'Internal server error',\n 500,\n );\n }\n }\n\n // POST handler: handle signing operations\n async function POST(request: NextRequest): Promise<NextResponse> {\n try {\n // Check authorization\n const authorized = await authorize(request);\n if (!authorized) {\n return errorResponse('UNAUTHORIZED', 'Unauthorized', 401);\n }\n\n // Parse request body\n let body: RemoteSignerRequest;\n try {\n body = await request.json();\n } catch {\n return errorResponse('INVALID_REQUEST', 'Invalid JSON body', 400);\n }\n\n if (!body.operation) {\n return errorResponse('INVALID_REQUEST', 'Missing operation field', 400);\n }\n\n // Load signer\n const signer = await loadSigner(provider);\n\n // Handle operations\n switch (body.operation) {\n case 'signTransaction': {\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n const signedTx = await signer.signTransaction(txBytes);\n const response: SignTransactionResponse = {\n signedTransaction: encodeBase64(signedTx),\n };\n return jsonResponse(response);\n }\n\n case 'signAllTransactions': {\n if (!body.transactions || !Array.isArray(body.transactions)) {\n return errorResponse('INVALID_REQUEST', 'Missing transactions array', 400);\n }\n\n const txBytesArray = body.transactions.map(tx => decodeBase64(tx));\n\n // Policy check for each transaction\n if (policy?.validateTransaction) {\n for (const txBytes of txBytesArray) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n }\n\n const signedTxs = await signer.signAllTransactions(txBytesArray);\n const response: SignAllTransactionsResponse = {\n signedTransactions: signedTxs.map(tx => encodeBase64(tx)),\n };\n return jsonResponse(response);\n }\n\n case 'signMessage': {\n if (!body.message) {\n return errorResponse('INVALID_REQUEST', 'Missing message field', 400);\n }\n\n const messageBytes = decodeBase64(body.message);\n\n // Policy check\n if (policy?.validateMessage) {\n const allowed = await policy.validateMessage(messageBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Message rejected by policy', 403);\n }\n }\n\n const signature = await signer.signMessage(messageBytes);\n const response: SignMessageResponse = {\n signature: encodeBase64(signature),\n };\n return jsonResponse(response);\n }\n\n case 'signAndSendTransaction': {\n if (!rpc) {\n return errorResponse('INVALID_OPERATION', 'signAndSendTransaction not enabled', 400);\n }\n\n if (!body.transaction) {\n return errorResponse('INVALID_REQUEST', 'Missing transaction field', 400);\n }\n\n const txBytes = decodeBase64(body.transaction);\n\n // Policy check\n if (policy?.validateTransaction) {\n const allowed = await policy.validateTransaction(txBytes, request);\n if (!allowed) {\n return errorResponse('POLICY_VIOLATION', 'Transaction rejected by policy', 403);\n }\n }\n\n // Sign\n const signedTx = await signer.signTransaction(txBytes);\n\n // Send\n try {\n const signature = await sendTransaction(rpc, signedTx);\n const response: SignAndSendTransactionResponse = { signature };\n return jsonResponse(response);\n } catch (error) {\n return errorResponse(\n 'SEND_FAILED',\n error instanceof Error ? error.message : 'Failed to send transaction',\n 500,\n );\n }\n }\n\n default:\n return errorResponse(\n 'INVALID_OPERATION',\n `Unknown operation: ${(body as { operation: string }).operation}`,\n 400,\n );\n }\n } catch (error) {\n console.error('[connector/server] POST error:', error);\n\n // Check for known signer errors\n if (error instanceof Error) {\n if (error.message.includes('rate limit') || error.message.includes('429')) {\n return errorResponse('PROVIDER_ERROR', 'Rate limited, please retry', 429);\n }\n }\n\n return errorResponse('SIGNING_FAILED', error instanceof Error ? error.message : 'Signing failed', 500);\n }\n }\n\n return { GET, POST };\n}\n"]}
@@ -1,8 +1,7 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React, { ReactNode } from 'react';
1
+ import React__default, { ReactNode } from 'react';
3
2
  import * as _wallet_standard_base from '@wallet-standard/base';
4
3
  import { Wallet, WalletAccount, IdentifierArray } from '@wallet-standard/base';
5
- import { w as TransactionActivity, x as TransactionActivityStatus } from './transaction-signer-7NaYmP5w.js';
4
+ import { T as TransactionActivity, g as TransactionActivityStatus, f as SolanaTransaction } from './transaction-signer-B3eCsMfI.js';
6
5
  import { SolanaClusterId, SolanaCluster } from '@wallet-ui/core';
7
6
  import { Address } from '@solana/addresses';
8
7
  import { Signature } from '@solana/keys';
@@ -930,6 +929,14 @@ declare class ConnectorClient {
930
929
  offAll(): void;
931
930
  emitEvent(event: ConnectorEvent): void;
932
931
  trackTransaction(activity: Omit<TransactionActivity, 'timestamp' | 'cluster'>): void;
932
+ /**
933
+ * Emit a pre-send transaction preview event for devtools.
934
+ *
935
+ * This does not sign or send the transaction. It exists so apps that do not
936
+ * use the connector transaction signer can still surface wire bytes in the
937
+ * debugger (e.g. to simulate before sending).
938
+ */
939
+ previewTransaction(transaction: SolanaTransaction): void;
933
940
  updateTransactionStatus(signature: string, status: TransactionActivity['status'], error?: string): void;
934
941
  clearTransactionHistory(): void;
935
942
  getHealth(): ConnectorHealth;
@@ -971,7 +978,7 @@ interface DefaultConfigOptions {
971
978
  /** Maximum retry attempts for error recovery (default: 3) */
972
979
  maxRetries?: number;
973
980
  /** Custom error handler */
974
- onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
981
+ onError?: (error: Error, errorInfo: React__default.ErrorInfo) => void;
975
982
  /**
976
983
  * Image proxy URL prefix for token images.
977
984
  * When set, token image URLs will be transformed to: `${imageProxy}${encodeURIComponent(originalUrl)}`
@@ -1075,9 +1082,9 @@ interface ExtendedConnectorConfig extends ConnectorConfig {
1075
1082
  /** Maximum retry attempts (default: 3) */
1076
1083
  maxRetries?: number;
1077
1084
  /** Custom error handler */
1078
- onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
1085
+ onError?: (error: Error, errorInfo: React__default.ErrorInfo) => void;
1079
1086
  /** Custom fallback component */
1080
- fallback?: (error: Error, retry: () => void) => React.ReactNode;
1087
+ fallback?: (error: Error, retry: () => void) => React__default.ReactNode;
1081
1088
  };
1082
1089
  /**
1083
1090
  * Image proxy URL prefix for token images.
@@ -1206,7 +1213,7 @@ declare function ConnectorProvider({ children, config, mobile, }: {
1206
1213
  children: ReactNode;
1207
1214
  config?: ExtendedConnectorConfig;
1208
1215
  mobile?: MobileWalletAdapterConfig;
1209
- }): react_jsx_runtime.JSX.Element;
1216
+ }): React__default.JSX.Element;
1210
1217
  declare function useConnector(): ConnectorSnapshot;
1211
1218
  declare function useConnectorClient(): ConnectorClient | null;
1212
1219
 
@@ -1617,4 +1624,4 @@ declare const ready: Promise<void>;
1617
1624
  */
1618
1625
  declare function getWalletsRegistry(): WalletsRegistry;
1619
1626
 
1620
- export { type WalletConnectConfig as $, type AccountInfo as A, isStatusError as B, ConnectorProvider as C, type DefaultConfigOptions as D, type ExtendedConnectorConfig as E, isWalletStatusError as F, toLegacyWalletState as G, type WalletConnector as H, INITIAL_WALLET_STATUS as I, type WalletStatusDisconnected as J, type WalletStatusConnecting as K, type WalletStatusConnected as L, type MobileWalletAdapterConfig as M, type WalletStatusError as N, WalletErrorType as O, isWalletError as P, createWalletError as Q, type RegisterMwaConfig as R, type SimplifiedWalletConnectConfig as S, type WalletError as T, getPublicSolanaRpcUrl as U, createSolanaClient as V, type WalletInfo as W, type SolanaClusterMoniker as X, type ModifiedClusterUrl as Y, type SolanaClient as Z, type CreateSolanaClientArgs as _, useConnectorClient as a, type WalletConnectMetadata as a0, type WalletConnectTransport as a1, type WalletName as a2, type AccountAddress as a3, isWalletName as a4, isAccountAddress as a5, type CoinGeckoConfig as a6, type ConnectorHealth as a7, type ConnectorDebugMetrics as a8, type ConnectorDebugState as a9, getClusterRpcUrl as aA, getClusterExplorerUrl as aB, getTransactionUrl as aC, getAddressUrl as aD, getTokenUrl as aE, getBlockUrl as aF, isMainnetCluster as aG, isDevnetCluster as aH, isTestnetCluster as aI, isLocalCluster as aJ, getClusterName as aK, getClusterType as aL, getClusterChainId as aM, getChainIdForWalletStandard as aN, type Listener as aa, type ConnectorEvent as ab, type ConnectorEventListener as ac, type StorageAdapter as ad, type StorageOptions as ae, type EnhancedStorageAccountOptions as af, type EnhancedStorageClusterOptions as ag, type EnhancedStorageWalletOptions as ah, type EnhancedStorageWalletStateOptions as ai, type PersistedWalletState as aj, type WalletConnectSolanaAccount as ak, type WalletConnectSignMessageParams as al, type WalletConnectSignMessageResult as am, type WalletConnectSignTransactionParams as an, type WalletConnectSignTransactionResult as ao, type WalletConnectSignAllTransactionsParams as ap, type WalletConnectSignAllTransactionsResult as aq, type WalletConnectSignAndSendTransactionParams as ar, type WalletConnectSignAndSendTransactionResult as as, ClipboardErrorType as at, type ClipboardResult as au, type CopyOptions as av, isClipboardAvailable as aw, copyToClipboard as ax, copyAddressToClipboard as ay, copySignatureToClipboard as az, getDefaultMobileConfig as b, type ConnectorSnapshot as c, type ConnectorConfig as d, type ConnectorState as e, type WalletDisplayConfig as f, getDefaultConfig as g, type WalletStandardWallet as h, type WalletStandardAccount as i, type WalletConnectorId as j, type WalletConnectorMetadata as k, type WalletSession as l, type WalletStatus as m, type SessionAccount as n, type ConnectOptions as o, createConnectorId as p, isWalletConnectorId as q, isConnected as r, isConnecting as s, isDisconnected as t, useConnector as u, type ClusterType as v, ConnectorClient as w, getWalletsRegistry as x, ready as y, getWalletNameFromConnectorId as z };
1627
+ export { type WalletError as $, type AccountAddress as A, type StorageOptions as B, ClipboardErrorType as C, type DefaultConfigOptions as D, type EnhancedStorageAccountOptions as E, type WalletConnectMetadata as F, type WalletConnectSignAllTransactionsParams as G, type WalletConnectSignAllTransactionsResult as H, INITIAL_WALLET_STATUS as I, type WalletConnectSignAndSendTransactionParams as J, type WalletConnectSignAndSendTransactionResult as K, type Listener as L, type MobileWalletAdapterConfig as M, type WalletConnectSignMessageParams as N, type WalletConnectSignMessageResult as O, type PersistedWalletState as P, type WalletConnectSignTransactionParams as Q, type RegisterMwaConfig as R, type SessionAccount as S, type WalletConnectSignTransactionResult as T, type WalletConnectSolanaAccount as U, type WalletConnectTransport as V, type WalletConnectConfig as W, type WalletConnector as X, type WalletConnectorId as Y, type WalletConnectorMetadata as Z, type WalletDisplayConfig as _, type AccountInfo as a, WalletErrorType as a0, type WalletInfo as a1, type WalletName as a2, type WalletSession as a3, type WalletStandardAccount as a4, type WalletStandardWallet as a5, type WalletStatus as a6, type WalletStatusConnected as a7, type WalletStatusConnecting as a8, type WalletStatusDisconnected as a9, isDevnetCluster as aA, isDisconnected as aB, isLocalCluster as aC, isMainnetCluster as aD, isStatusError as aE, isTestnetCluster as aF, isWalletConnectorId as aG, isWalletError as aH, isWalletName as aI, isWalletStatusError as aJ, ready as aK, toLegacyWalletState as aL, useConnector as aM, useConnectorClient as aN, type WalletStatusError as aa, copyAddressToClipboard as ab, copySignatureToClipboard as ac, copyToClipboard as ad, createConnectorId as ae, createSolanaClient as af, createWalletError as ag, getAddressUrl as ah, getBlockUrl as ai, getChainIdForWalletStandard as aj, getClusterChainId as ak, getClusterExplorerUrl as al, getClusterName as am, getClusterRpcUrl as an, getClusterType as ao, getDefaultConfig as ap, getDefaultMobileConfig as aq, getPublicSolanaRpcUrl as ar, getTokenUrl as as, getTransactionUrl as at, getWalletNameFromConnectorId as au, getWalletsRegistry as av, isAccountAddress as aw, isClipboardAvailable as ax, isConnected as ay, isConnecting as az, type ClipboardResult as b, type ClusterType as c, type CoinGeckoConfig as d, type ConnectOptions as e, ConnectorClient as f, type ConnectorConfig as g, type ConnectorDebugMetrics as h, type ConnectorDebugState as i, type ConnectorEvent as j, type ConnectorEventListener as k, type ConnectorHealth as l, ConnectorProvider as m, type ConnectorSnapshot as n, type ConnectorState as o, type CopyOptions as p, type CreateSolanaClientArgs as q, type EnhancedStorageClusterOptions as r, type EnhancedStorageWalletOptions as s, type EnhancedStorageWalletStateOptions as t, type ExtendedConnectorConfig as u, type ModifiedClusterUrl as v, type SimplifiedWalletConnectConfig as w, type SolanaClient as x, type SolanaClusterMoniker as y, type StorageAdapter as z };