@joai/warps-adapter-solana 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -57,8 +57,7 @@ var import_warps13 = require("@joai/warps");
57
57
 
58
58
  // src/WarpSolanaDataLoader.ts
59
59
  var import_warps5 = require("@joai/warps");
60
- var import_web3 = require("@solana/web3.js");
61
- var import_spl_token = require("@solana/spl-token");
60
+ var import_web32 = require("@solana/web3.js");
62
61
 
63
62
  // src/constants.ts
64
63
  var WarpSolanaConstants = {
@@ -120,6 +119,58 @@ var X402SolanaNetworkIdentifiers = {
120
119
  };
121
120
  var SupportedX402SolanaNetworks = [X402SolanaNetworkIdentifiers.Mainnet, X402SolanaNetworkIdentifiers.Devnet];
122
121
 
122
+ // src/tokenProgram.ts
123
+ var import_web3 = require("@solana/web3.js");
124
+ var MINT_SIZE = 82;
125
+ var TOKEN_TRANSFER_INSTRUCTION = 3;
126
+ var TOKEN_PROGRAM_ID = new import_web3.PublicKey(WarpSolanaConstants.Programs.TokenProgram);
127
+ var ASSOCIATED_TOKEN_PROGRAM_ID = new import_web3.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
128
+ var getAssociatedTokenAddress = async (mint, owner, allowOwnerOffCurve = false, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) => getAssociatedTokenAddressSync(mint, owner, allowOwnerOffCurve, programId, associatedTokenProgramId);
129
+ var getAssociatedTokenAddressSync = (mint, owner, allowOwnerOffCurve = false, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) => {
130
+ if (!allowOwnerOffCurve && !import_web3.PublicKey.isOnCurve(owner.toBuffer())) {
131
+ throw new Error("Owner cannot be a PDA");
132
+ }
133
+ const [address] = import_web3.PublicKey.findProgramAddressSync([owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], associatedTokenProgramId);
134
+ return address;
135
+ };
136
+ var createAssociatedTokenAccountInstruction = (payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) => new import_web3.TransactionInstruction({
137
+ keys: [
138
+ { pubkey: payer, isSigner: true, isWritable: true },
139
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
140
+ { pubkey: owner, isSigner: false, isWritable: false },
141
+ { pubkey: mint, isSigner: false, isWritable: false },
142
+ { pubkey: import_web3.SystemProgram.programId, isSigner: false, isWritable: false },
143
+ { pubkey: programId, isSigner: false, isWritable: false }
144
+ ],
145
+ programId: associatedTokenProgramId,
146
+ data: Buffer.alloc(0)
147
+ });
148
+ var createTransferInstruction = (source, destination, owner, amount, programId = TOKEN_PROGRAM_ID) => {
149
+ const data = Buffer.alloc(9);
150
+ data.writeUInt8(TOKEN_TRANSFER_INSTRUCTION, 0);
151
+ data.writeBigUInt64LE(BigInt(amount), 1);
152
+ return new import_web3.TransactionInstruction({
153
+ keys: [
154
+ { pubkey: source, isSigner: false, isWritable: true },
155
+ { pubkey: destination, isSigner: false, isWritable: true },
156
+ { pubkey: owner, isSigner: true, isWritable: false }
157
+ ],
158
+ programId,
159
+ data
160
+ });
161
+ };
162
+ var getMint = async (connection, address, commitment, programId = TOKEN_PROGRAM_ID) => {
163
+ const info = await connection.getAccountInfo(address, commitment);
164
+ if (!info) throw new Error("Token mint account not found");
165
+ if (!info.owner.equals(programId)) throw new Error("Token mint account owner mismatch");
166
+ if (info.data.length < MINT_SIZE) throw new Error("Token mint account has invalid size");
167
+ return {
168
+ address,
169
+ decimals: info.data.readUInt8(44),
170
+ isInitialized: info.data.readUInt8(45) !== 0
171
+ };
172
+ };
173
+
123
174
  // src/tokens.ts
124
175
  var import_warps4 = require("@joai/warps");
125
176
 
@@ -323,12 +374,12 @@ var WarpSolanaDataLoader = class {
323
374
  this.config = config;
324
375
  this.chain = chain;
325
376
  const providerConfig = (0, import_warps5.getProviderConfig)(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
326
- this.connection = new import_web3.Connection(providerConfig.url, "confirmed");
377
+ this.connection = new import_web32.Connection(providerConfig.url, "confirmed");
327
378
  this.cache = new import_warps5.WarpCache(config.env, config.cache);
328
379
  }
329
380
  async getAccount(address) {
330
381
  try {
331
- const publicKey = new import_web3.PublicKey(address);
382
+ const publicKey = new import_web32.PublicKey(address);
332
383
  const balance = await this.connection.getBalance(publicKey);
333
384
  return {
334
385
  chain: this.chain.name,
@@ -426,9 +477,9 @@ var WarpSolanaDataLoader = class {
426
477
  }
427
478
  async getTokenBalances(address) {
428
479
  try {
429
- const publicKey = new import_web3.PublicKey(address);
480
+ const publicKey = new import_web32.PublicKey(address);
430
481
  const tokenAccounts = await this.connection.getParsedTokenAccountsByOwner(publicKey, {
431
- programId: new import_web3.PublicKey(WarpSolanaConstants.Programs.TokenProgram)
482
+ programId: new import_web32.PublicKey(WarpSolanaConstants.Programs.TokenProgram)
432
483
  });
433
484
  const env = this.config.env === "mainnet" ? "mainnet" : this.config.env === "devnet" ? "devnet" : "testnet";
434
485
  const knownTokens = getKnownTokensForChain(this.chain.name, env);
@@ -470,8 +521,8 @@ var WarpSolanaDataLoader = class {
470
521
  }
471
522
  async getTokenMetadata(tokenAddress) {
472
523
  try {
473
- const mintPublicKey = new import_web3.PublicKey(tokenAddress);
474
- const mintInfo = await (0, import_spl_token.getMint)(this.connection, mintPublicKey);
524
+ const mintPublicKey = new import_web32.PublicKey(tokenAddress);
525
+ const mintInfo = await getMint(this.connection, mintPublicKey);
475
526
  return {
476
527
  name: "Unknown Token",
477
528
  symbol: "UNKNOWN",
@@ -620,17 +671,16 @@ var WarpSolanaDataLoader = class {
620
671
  };
621
672
 
622
673
  // src/WarpSolanaExecutor.ts
623
- var import_spl_token2 = require("@solana/spl-token");
624
- var import_web34 = require("@solana/web3.js");
674
+ var import_web35 = require("@solana/web3.js");
625
675
  var import_warps8 = require("@joai/warps");
626
676
 
627
677
  // src/WarpSolanaOutput.ts
628
678
  var import_warps7 = require("@joai/warps");
629
- var import_web33 = require("@solana/web3.js");
679
+ var import_web34 = require("@solana/web3.js");
630
680
 
631
681
  // src/WarpSolanaSerializer.ts
632
682
  var import_warps6 = require("@joai/warps");
633
- var import_web32 = require("@solana/web3.js");
683
+ var import_web33 = require("@solana/web3.js");
634
684
  var import_bs58 = __toESM(require("bs58"), 1);
635
685
  var WarpSolanaSerializer = class {
636
686
  constructor() {
@@ -643,7 +693,7 @@ var WarpSolanaSerializer = class {
643
693
  if (typeof value === "string") {
644
694
  if (value.length >= 32 && value.length <= 44) {
645
695
  try {
646
- const pubkey = new import_web32.PublicKey(value);
696
+ const pubkey = new import_web33.PublicKey(value);
647
697
  if (pubkey.toBase58() === value && /^[1-9A-HJ-NP-Za-km-z]+$/.test(value)) {
648
698
  return `address:${value}`;
649
699
  }
@@ -670,7 +720,7 @@ var WarpSolanaSerializer = class {
670
720
  if (typeof value === "boolean") {
671
721
  return `boolean:${value}`;
672
722
  }
673
- if (value instanceof import_web32.PublicKey) {
723
+ if (value instanceof import_web33.PublicKey) {
674
724
  return `address:${value.toBase58()}`;
675
725
  }
676
726
  if (value instanceof Uint8Array) {
@@ -820,7 +870,7 @@ var WarpSolanaOutput = class {
820
870
  this.chain = chain;
821
871
  this.serializer = new WarpSolanaSerializer();
822
872
  const providerConfig = (0, import_warps7.getProviderConfig)(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
823
- this.connection = new import_web33.Connection(providerConfig.url, "confirmed");
873
+ this.connection = new import_web34.Connection(providerConfig.url, "confirmed");
824
874
  this.cache = new import_warps7.WarpCache(config.env, config.cache);
825
875
  }
826
876
  async getActionExecution(warp, actionIndex, tx) {
@@ -947,7 +997,7 @@ var WarpSolanaOutput = class {
947
997
  output[key] = path;
948
998
  }
949
999
  }
950
- return { values, output: await (0, import_warps7.evaluateOutputCommon)(warp, output, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
1000
+ return { values, output: await (0, import_warps7.evaluateOutputCommon)(warp, output, nativeValues, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
951
1001
  }
952
1002
  async getTransactionStatus(txHash) {
953
1003
  try {
@@ -996,7 +1046,7 @@ var WarpSolanaExecutor = class {
996
1046
  this.chain = chain;
997
1047
  this.serializer = new WarpSolanaSerializer();
998
1048
  const providerConfig = (0, import_warps8.getProviderConfig)(this.config, chain.name, this.config.env, this.chain.defaultApiUrl);
999
- this.connection = new import_web34.Connection(providerConfig.url, "confirmed");
1049
+ this.connection = new import_web35.Connection(providerConfig.url, "confirmed");
1000
1050
  this.output = new WarpSolanaOutput(config, this.chain);
1001
1051
  }
1002
1052
  async createTransaction(executable) {
@@ -1025,14 +1075,14 @@ var WarpSolanaExecutor = class {
1025
1075
  }
1026
1076
  const instructions = [];
1027
1077
  if (executable.value > 0n) {
1028
- instructions.push(import_web34.SystemProgram.transfer({ fromPubkey, toPubkey: destinationPubkey, lamports: Number(executable.value) }));
1078
+ instructions.push(import_web35.SystemProgram.transfer({ fromPubkey, toPubkey: destinationPubkey, lamports: Number(executable.value) }));
1029
1079
  }
1030
1080
  if (executable.data) {
1031
1081
  const data = this.serializer.stringToTyped(executable.data);
1032
1082
  if (data && typeof data === "string") {
1033
1083
  const dataBuffer = Buffer.from(data, "base64");
1034
1084
  instructions.push(
1035
- new import_web34.TransactionInstruction({
1085
+ new import_web35.TransactionInstruction({
1036
1086
  keys: [
1037
1087
  { pubkey: fromPubkey, isSigner: true, isWritable: true },
1038
1088
  { pubkey: destinationPubkey, isSigner: false, isWritable: true }
@@ -1057,33 +1107,43 @@ var WarpSolanaExecutor = class {
1057
1107
  const argsToUse = this.extractContractArgs(executable);
1058
1108
  const nativeArgs = argsToUse.map((arg) => this.serializer.coreSerializer.stringToNative(arg)[1]);
1059
1109
  const instructionData = this.buildInstructionData(action, nativeArgs);
1060
- const accounts = await this.buildInstructionAccounts(action, executable, fromPubkey, programId);
1061
- await this.ensureATAs(action, accounts, fromPubkey, instructions);
1062
- instructions.push(new import_web34.TransactionInstruction({ keys: accounts, programId, data: instructionData }));
1110
+ const parsedAbi = this.parseAbi(action);
1111
+ const abiAccounts = parsedAbi?.instructions?.[action.func]?.accounts ?? null;
1112
+ const accounts = await this.buildInstructionAccounts(action, executable, fromPubkey, programId, abiAccounts);
1113
+ await this.ensureATAs(abiAccounts, accounts, fromPubkey, instructions);
1114
+ instructions.push(new import_web35.TransactionInstruction({ keys: accounts, programId, data: instructionData }));
1063
1115
  if (executable.value > 0n) {
1064
- instructions.push(import_web34.SystemProgram.transfer({ fromPubkey, toPubkey: programId, lamports: Number(executable.value) }));
1116
+ instructions.push(import_web35.SystemProgram.transfer({ fromPubkey, toPubkey: programId, lamports: Number(executable.value) }));
1065
1117
  }
1066
1118
  return this.setTransactionDefaults(instructions, fromPubkey);
1067
1119
  }
1068
- async ensureATAs(action, accounts, fromPubkey, instructions) {
1069
- if (!action.accounts || !Array.isArray(action.accounts)) return;
1120
+ parseAbi(action) {
1121
+ if (!action.abi || typeof action.abi !== "string") return null;
1122
+ try {
1123
+ return JSON.parse(action.abi);
1124
+ } catch {
1125
+ return null;
1126
+ }
1127
+ }
1128
+ async ensureATAs(abiAccounts, accounts, fromPubkey, instructions) {
1129
+ if (!abiAccounts || !Array.isArray(abiAccounts)) return;
1070
1130
  const createdATAs = /* @__PURE__ */ new Set();
1071
- for (let idx = 0; idx < action.accounts.length; idx++) {
1072
- const accountDef = action.accounts[idx];
1131
+ for (let idx = 0; idx < abiAccounts.length; idx++) {
1132
+ const accountDef = abiAccounts[idx];
1073
1133
  const accountStr = typeof accountDef === "string" ? accountDef : JSON.stringify(accountDef);
1074
1134
  if (accountStr.includes("{{USER_ATA:")) {
1075
1135
  const match = accountStr.match(/USER_ATA[:\s]*([^"}\s]+)/);
1076
1136
  if (match) {
1077
1137
  const mintAddress = match[1];
1078
1138
  try {
1079
- const mintPubkey = new import_web34.PublicKey(mintAddress);
1080
- const expectedAta = await (0, import_spl_token2.getAssociatedTokenAddress)(mintPubkey, fromPubkey);
1139
+ const mintPubkey = new import_web35.PublicKey(mintAddress);
1140
+ const expectedAta = await getAssociatedTokenAddress(mintPubkey, fromPubkey);
1081
1141
  const ataKey = expectedAta.toBase58();
1082
1142
  if (!createdATAs.has(ataKey)) {
1083
1143
  createdATAs.add(ataKey);
1084
1144
  const ataInfo = await this.connection.getAccountInfo(expectedAta);
1085
1145
  if (!ataInfo) {
1086
- instructions.push((0, import_spl_token2.createAssociatedTokenAccountInstruction)(fromPubkey, expectedAta, fromPubkey, mintPubkey));
1146
+ instructions.push(createAssociatedTokenAccountInstruction(fromPubkey, expectedAta, fromPubkey, mintPubkey));
1087
1147
  }
1088
1148
  }
1089
1149
  } catch {
@@ -1097,15 +1157,15 @@ var WarpSolanaExecutor = class {
1097
1157
  const mintAddress = match[1];
1098
1158
  const receiverAddress = match[2];
1099
1159
  try {
1100
- const mintPubkey = new import_web34.PublicKey(mintAddress);
1101
- const receiverPubkey = new import_web34.PublicKey(receiverAddress);
1102
- const expectedAta = await (0, import_spl_token2.getAssociatedTokenAddress)(mintPubkey, receiverPubkey);
1160
+ const mintPubkey = new import_web35.PublicKey(mintAddress);
1161
+ const receiverPubkey = new import_web35.PublicKey(receiverAddress);
1162
+ const expectedAta = await getAssociatedTokenAddress(mintPubkey, receiverPubkey);
1103
1163
  const ataKey = expectedAta.toBase58();
1104
1164
  if (!createdATAs.has(ataKey)) {
1105
1165
  createdATAs.add(ataKey);
1106
1166
  const ataInfo = await this.connection.getAccountInfo(expectedAta);
1107
1167
  if (!ataInfo) {
1108
- instructions.push((0, import_spl_token2.createAssociatedTokenAccountInstruction)(fromPubkey, expectedAta, receiverPubkey, mintPubkey));
1168
+ instructions.push(createAssociatedTokenAccountInstruction(fromPubkey, expectedAta, receiverPubkey, mintPubkey));
1109
1169
  }
1110
1170
  }
1111
1171
  } catch {
@@ -1182,7 +1242,7 @@ var WarpSolanaExecutor = class {
1182
1242
  buffers.push(Buffer.from(String(arg), "utf8"));
1183
1243
  } else if (def.type === "publicKey" || def.type === "pubkey") {
1184
1244
  try {
1185
- const pubkey = new import_web34.PublicKey(arg);
1245
+ const pubkey = new import_web35.PublicKey(arg);
1186
1246
  buffers.push(Buffer.from(pubkey.toBuffer()));
1187
1247
  } catch {
1188
1248
  buffers.push(Buffer.from(String(arg), "utf8"));
@@ -1193,7 +1253,7 @@ var WarpSolanaExecutor = class {
1193
1253
  }
1194
1254
  return Buffer.concat(buffers);
1195
1255
  }
1196
- async buildInstructionAccounts(action, executable, fromPubkey, programId) {
1256
+ async buildInstructionAccounts(action, executable, fromPubkey, programId, abiAccounts) {
1197
1257
  const accounts = [];
1198
1258
  const accountInputs = this.extractAccountInputs(action, executable);
1199
1259
  if (accountInputs.length > 0) {
@@ -1207,13 +1267,11 @@ var WarpSolanaExecutor = class {
1207
1267
  }
1208
1268
  return accounts;
1209
1269
  }
1210
- if (!action.accounts || !Array.isArray(action.accounts)) return accounts;
1211
- for (let idx = 0; idx < action.accounts.length; idx++) {
1212
- const accountDef = action.accounts[idx];
1270
+ if (!abiAccounts || !Array.isArray(abiAccounts)) return accounts;
1271
+ for (let idx = 0; idx < abiAccounts.length; idx++) {
1272
+ const accountDef = abiAccounts[idx];
1213
1273
  let address = this.extractAccountAddress(accountDef);
1214
- if (address === "[object Object]" || typeof accountDef === "string" && accountDef === "[object Object]") {
1215
- address = fromPubkey.toBase58();
1216
- } else if (!address || address.length === 0) {
1274
+ if (!address || address.length === 0) {
1217
1275
  throw new Error(`Invalid account definition at index ${idx}: ${JSON.stringify(accountDef)}`);
1218
1276
  }
1219
1277
  if (address === "{{USER_WALLET}}" || typeof address === "string" && address.includes("{{USER_WALLET}}")) {
@@ -1265,7 +1323,7 @@ var WarpSolanaExecutor = class {
1265
1323
  if (accountInput.input.as?.startsWith("USER_ATA:") || accountInput.input.as?.startsWith("RECEIVER_ATA:")) {
1266
1324
  return await this.resolveAccountPubkey(`{{${accountInput.input.as}}}`, fromPubkey);
1267
1325
  }
1268
- return new import_web34.PublicKey(address);
1326
+ return new import_web35.PublicKey(address);
1269
1327
  }
1270
1328
  interpolateAccountAddress(address, resolvedInputs) {
1271
1329
  if (!address.includes("{{")) return address;
@@ -1295,6 +1353,22 @@ var WarpSolanaExecutor = class {
1295
1353
  }
1296
1354
  }
1297
1355
  }
1356
+ if (address.includes("{{USER_ATA:") || address.includes("{{RECEIVER_ATA:")) {
1357
+ for (const resolved of resolvedInputs) {
1358
+ if (!resolved.input?.as) continue;
1359
+ const key = resolved.input.as.toUpperCase();
1360
+ if (address.includes(key)) {
1361
+ let value = resolved.value;
1362
+ if (typeof value === "string" && value.includes(":")) {
1363
+ value = value.split(":")[1];
1364
+ }
1365
+ if (value) {
1366
+ address = address.replace(new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), String(value));
1367
+ }
1368
+ }
1369
+ }
1370
+ return address;
1371
+ }
1298
1372
  return address;
1299
1373
  }
1300
1374
  async createTokenTransferTransaction(executable, userWallet, destinationPubkey) {
@@ -1306,8 +1380,8 @@ var WarpSolanaExecutor = class {
1306
1380
  if (nativeTokenTransfers.length === 1 && splTokenTransfers.length === 0) {
1307
1381
  const transfer = nativeTokenTransfers[0];
1308
1382
  if (transfer.amount <= 0n) throw new Error("WarpSolanaExecutor: Native token transfer amount must be positive");
1309
- const fromPubkey = new import_web34.PublicKey(userWallet);
1310
- return this.setTransactionDefaults([import_web34.SystemProgram.transfer({ fromPubkey, toPubkey: destinationPubkey, lamports: Number(transfer.amount) })], fromPubkey);
1383
+ const fromPubkey = new import_web35.PublicKey(userWallet);
1384
+ return this.setTransactionDefaults([import_web35.SystemProgram.transfer({ fromPubkey, toPubkey: destinationPubkey, lamports: Number(transfer.amount) })], fromPubkey);
1311
1385
  }
1312
1386
  if (nativeTokenTransfers.length === 0 && splTokenTransfers.length === 1) {
1313
1387
  return this.createSingleTokenTransfer(executable, splTokenTransfers[0], userWallet, destinationPubkey);
@@ -1316,18 +1390,18 @@ var WarpSolanaExecutor = class {
1316
1390
  throw new Error("WarpSolanaExecutor: Invalid transfer configuration");
1317
1391
  }
1318
1392
  async createSingleTokenTransfer(executable, transfer, userWallet, destinationPubkey) {
1319
- const mintAddress = new import_web34.PublicKey(transfer.identifier);
1320
- const fromPubkey = new import_web34.PublicKey(userWallet);
1321
- const sourceTokenAccount = await (0, import_spl_token2.getAssociatedTokenAddress)(mintAddress, fromPubkey);
1322
- const destinationTokenAccount = await (0, import_spl_token2.getAssociatedTokenAddress)(mintAddress, destinationPubkey);
1393
+ const mintAddress = new import_web35.PublicKey(transfer.identifier);
1394
+ const fromPubkey = new import_web35.PublicKey(userWallet);
1395
+ const sourceTokenAccount = await getAssociatedTokenAddress(mintAddress, fromPubkey);
1396
+ const destinationTokenAccount = await getAssociatedTokenAddress(mintAddress, destinationPubkey);
1323
1397
  if (!await this.connection.getAccountInfo(sourceTokenAccount)) {
1324
1398
  throw new Error("WarpSolanaExecutor: Source token account does not exist");
1325
1399
  }
1326
1400
  const instructions = [];
1327
1401
  if (!await this.connection.getAccountInfo(destinationTokenAccount)) {
1328
- instructions.push((0, import_spl_token2.createAssociatedTokenAccountInstruction)(fromPubkey, destinationTokenAccount, destinationPubkey, mintAddress));
1402
+ instructions.push(createAssociatedTokenAccountInstruction(fromPubkey, destinationTokenAccount, destinationPubkey, mintAddress));
1329
1403
  }
1330
- instructions.push((0, import_spl_token2.createTransferInstruction)(sourceTokenAccount, destinationTokenAccount, fromPubkey, Number(transfer.amount)));
1404
+ instructions.push(createTransferInstruction(sourceTokenAccount, destinationTokenAccount, fromPubkey, Number(transfer.amount)));
1331
1405
  return this.setTransactionDefaults(instructions, fromPubkey);
1332
1406
  }
1333
1407
  async executeQuery(executable) {
@@ -1335,7 +1409,7 @@ var WarpSolanaExecutor = class {
1335
1409
  if (action.type !== "query") throw new Error(`WarpSolanaExecutor: Invalid action type for executeQuery: ${action.type}`);
1336
1410
  if (!action.func) throw new Error("WarpSolanaExecutor: Query action must have a function name");
1337
1411
  if (!executable.destination) throw new Error("WarpSolanaExecutor: Query address is required");
1338
- const queryAddress = new import_web34.PublicKey(executable.destination);
1412
+ const queryAddress = new import_web35.PublicKey(executable.destination);
1339
1413
  const nativeArgs = executable.args.map((arg) => this.serializer.coreSerializer.stringToNative(arg)[1]);
1340
1414
  let decodedResult = [];
1341
1415
  let isSuccess = true;
@@ -1391,32 +1465,19 @@ var WarpSolanaExecutor = class {
1391
1465
  resolvedInputs
1392
1466
  };
1393
1467
  }
1394
- async verifyMessage(message, signature) {
1395
- try {
1396
- const messageBytes = new TextEncoder().encode(message);
1397
- const signatureBytes = Buffer.from(signature, "base64");
1398
- return "";
1399
- } catch (error) {
1400
- throw new Error(`Failed to verify message: ${error}`);
1401
- }
1402
- }
1403
1468
  async setTransactionDefaults(instructions, fromPubkey) {
1404
1469
  const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
1405
1470
  const allInstructions = this.addComputeBudgetInstructions(instructions);
1406
- const accountMetaMap = this.buildAccountMetaMap(allInstructions, fromPubkey);
1407
- const { signedAccounts, unsignedAccounts } = this.sortAccounts(accountMetaMap);
1408
- const { staticAccountKeys, accountIndexMap } = this.buildAccountIndexMap(signedAccounts, unsignedAccounts);
1409
- const compiledInstructions = this.compileInstructions(allInstructions, accountIndexMap);
1410
- const messageV0 = this.buildMessageV0(blockhash, signedAccounts, unsignedAccounts, accountMetaMap, staticAccountKeys, compiledInstructions);
1411
- const versionedTx = new import_web34.VersionedTransaction(messageV0);
1412
- if (versionedTx.version !== 0) {
1413
- throw new Error(`Expected VersionedTransaction v0, got version: ${versionedTx.version}`);
1414
- }
1415
- return versionedTx;
1471
+ const messageV0 = import_web35.MessageV0.compile({
1472
+ payerKey: fromPubkey,
1473
+ instructions: allInstructions,
1474
+ recentBlockhash: blockhash
1475
+ });
1476
+ return new import_web35.VersionedTransaction(messageV0);
1416
1477
  }
1417
1478
  toPublicKey(address, errorMsg) {
1418
1479
  try {
1419
- return new import_web34.PublicKey(address);
1480
+ return new import_web35.PublicKey(address);
1420
1481
  } catch {
1421
1482
  throw new Error(`WarpSolanaExecutor: ${errorMsg}`);
1422
1483
  }
@@ -1452,20 +1513,8 @@ var WarpSolanaExecutor = class {
1452
1513
  extractAccountAddress(accountDef) {
1453
1514
  if (typeof accountDef === "string") return accountDef;
1454
1515
  if (!accountDef || typeof accountDef !== "object") return void 0;
1455
- const str = JSON.stringify(accountDef);
1456
- if (str.includes("USER_WALLET") || str.includes("{{USER_WALLET}}")) return "{{USER_WALLET}}";
1457
- if (str.includes("RECEIVER_ADDRESS") || str.includes("{{RECEIVER_ADDRESS}}")) return "{{RECEIVER_ADDRESS}}";
1458
- if (str.includes("USER_ATA")) {
1459
- const match = str.match(/USER_ATA[:\s]*([^"}\s]+)/);
1460
- if (match) return `{{USER_ATA:${match[1]}}}`;
1461
- }
1462
- const addrValue = accountDef.address || accountDef.pubkey || accountDef.value;
1463
- if (typeof addrValue === "string") return addrValue;
1464
- if (addrValue?.toBase58) return addrValue.toBase58();
1465
- if (addrValue?.identifier) return addrValue.identifier;
1466
- if (addrValue?.value) return addrValue.value;
1467
- const keys = Object.keys(accountDef);
1468
- if (keys.length === 1 && typeof accountDef[keys[0]] === "string") return accountDef[keys[0]];
1516
+ const address = accountDef.address || accountDef.pubkey;
1517
+ if (typeof address === "string") return address;
1469
1518
  return void 0;
1470
1519
  }
1471
1520
  async resolveAccountPubkey(address, fromPubkey) {
@@ -1477,8 +1526,8 @@ var WarpSolanaExecutor = class {
1477
1526
  if (!mintAddress || mintAddress.includes("{{")) {
1478
1527
  throw new Error(`Invalid USER_ATA placeholder: ${address}. Mint address must be resolved first.`);
1479
1528
  }
1480
- const mintPubkey = new import_web34.PublicKey(mintAddress);
1481
- return await (0, import_spl_token2.getAssociatedTokenAddress)(mintPubkey, fromPubkey);
1529
+ const mintPubkey = new import_web35.PublicKey(mintAddress);
1530
+ return await getAssociatedTokenAddress(mintPubkey, fromPubkey);
1482
1531
  }
1483
1532
  if (address.startsWith("{{RECEIVER_ATA:") && address.endsWith("}}")) {
1484
1533
  const content = address.slice(15, -2);
@@ -1491,12 +1540,12 @@ var WarpSolanaExecutor = class {
1491
1540
  }
1492
1541
  if (mintAddress.includes(":")) mintAddress = mintAddress.split(":")[1];
1493
1542
  if (receiverAddress.includes(":")) receiverAddress = receiverAddress.split(":")[1];
1494
- const mintPubkey = new import_web34.PublicKey(mintAddress);
1495
- const receiverPubkey = new import_web34.PublicKey(receiverAddress);
1496
- return await (0, import_spl_token2.getAssociatedTokenAddress)(mintPubkey, receiverPubkey);
1543
+ const mintPubkey = new import_web35.PublicKey(mintAddress);
1544
+ const receiverPubkey = new import_web35.PublicKey(receiverAddress);
1545
+ return await getAssociatedTokenAddress(mintPubkey, receiverPubkey);
1497
1546
  }
1498
1547
  }
1499
- return new import_web34.PublicKey(address);
1548
+ return new import_web35.PublicKey(address);
1500
1549
  }
1501
1550
  determineAccountFlags(accountDef, pubkey, fromPubkey) {
1502
1551
  const accountMeta = typeof accountDef === "object" ? accountDef : {};
@@ -1510,85 +1559,10 @@ var WarpSolanaExecutor = class {
1510
1559
  addComputeBudgetInstructions(instructions) {
1511
1560
  const hasTokenTransfer = instructions.some((ix) => ix.programId.toBase58() === WarpSolanaConstants.Programs.TokenProgram);
1512
1561
  const computeUnits = hasTokenTransfer ? WarpSolanaConstants.ComputeUnitLimit.TokenTransfer : WarpSolanaConstants.ComputeUnitLimit.Default;
1513
- const computeUnitLimitIx = import_web34.ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnits });
1514
- const computeUnitPriceIx = import_web34.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: WarpSolanaConstants.PriorityFee.Default });
1562
+ const computeUnitLimitIx = import_web35.ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnits });
1563
+ const computeUnitPriceIx = import_web35.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: WarpSolanaConstants.PriorityFee.Default });
1515
1564
  return [computeUnitLimitIx, computeUnitPriceIx, ...instructions];
1516
1565
  }
1517
- buildAccountMetaMap(instructions, fromPubkey) {
1518
- const accountMetaMap = /* @__PURE__ */ new Map();
1519
- if (fromPubkey) {
1520
- accountMetaMap.set(fromPubkey.toBase58(), { pubkey: fromPubkey, isSigner: true, isWritable: true });
1521
- }
1522
- for (const ix of instructions) {
1523
- const programIdStr = ix.programId.toBase58();
1524
- if (!accountMetaMap.has(programIdStr)) {
1525
- accountMetaMap.set(programIdStr, { pubkey: ix.programId, isSigner: false, isWritable: false });
1526
- }
1527
- for (const key of ix.keys) {
1528
- const keyStr = key.pubkey.toBase58();
1529
- const existing = accountMetaMap.get(keyStr);
1530
- if (existing) {
1531
- accountMetaMap.set(keyStr, {
1532
- pubkey: key.pubkey,
1533
- isSigner: existing.isSigner || key.isSigner,
1534
- isWritable: existing.isWritable || key.isWritable
1535
- });
1536
- } else {
1537
- accountMetaMap.set(keyStr, {
1538
- pubkey: key.pubkey,
1539
- isSigner: key.isSigner,
1540
- isWritable: key.isWritable
1541
- });
1542
- }
1543
- }
1544
- }
1545
- return accountMetaMap;
1546
- }
1547
- sortAccounts(accountMetaMap) {
1548
- const signedAccounts = [];
1549
- const unsignedAccounts = [];
1550
- for (const meta of accountMetaMap.values()) {
1551
- ;
1552
- (meta.isSigner ? signedAccounts : unsignedAccounts).push(meta.pubkey);
1553
- }
1554
- const sortByWritable = (a, b) => (accountMetaMap.get(a.toBase58()).isWritable ? 0 : 1) - (accountMetaMap.get(b.toBase58()).isWritable ? 0 : 1);
1555
- signedAccounts.sort(sortByWritable);
1556
- unsignedAccounts.sort(sortByWritable);
1557
- return { signedAccounts, unsignedAccounts };
1558
- }
1559
- buildAccountIndexMap(signedAccounts, unsignedAccounts) {
1560
- const staticAccountKeys = [...signedAccounts, ...unsignedAccounts];
1561
- const accountIndexMap = /* @__PURE__ */ new Map();
1562
- staticAccountKeys.forEach((key, index) => {
1563
- accountIndexMap.set(key.toBase58(), index);
1564
- });
1565
- return { staticAccountKeys, accountIndexMap };
1566
- }
1567
- compileInstructions(instructions, accountIndexMap) {
1568
- return instructions.map((ix) => {
1569
- const programIdIndex = accountIndexMap.get(ix.programId.toBase58());
1570
- const accountKeyIndexes = ix.keys.map((key) => accountIndexMap.get(key.pubkey.toBase58()));
1571
- return {
1572
- programIdIndex,
1573
- accountKeyIndexes,
1574
- data: Uint8Array.from(ix.data)
1575
- };
1576
- });
1577
- }
1578
- buildMessageV0(blockhash, signedAccounts, unsignedAccounts, accountMetaMap, staticAccountKeys, compiledInstructions) {
1579
- const getWritable = (key) => accountMetaMap.get(key.toBase58()).isWritable;
1580
- return new import_web34.MessageV0({
1581
- header: {
1582
- numRequiredSignatures: signedAccounts.length,
1583
- numReadonlySignedAccounts: signedAccounts.filter((k) => !getWritable(k)).length,
1584
- numReadonlyUnsignedAccounts: unsignedAccounts.filter((k) => !getWritable(k)).length
1585
- },
1586
- staticAccountKeys,
1587
- recentBlockhash: blockhash,
1588
- compiledInstructions,
1589
- addressTableLookups: []
1590
- });
1591
- }
1592
1566
  };
1593
1567
 
1594
1568
  // src/WarpSolanaExplorer.ts
@@ -1739,13 +1713,13 @@ var WarpSolanaExplorer = class {
1739
1713
  // src/WarpSolanaWallet.ts
1740
1714
  var import_warps12 = require("@joai/warps");
1741
1715
  var import_kit = require("@solana/kit");
1742
- var import_web37 = require("@solana/web3.js");
1716
+ var import_web38 = require("@solana/web3.js");
1743
1717
  var import_client = require("@x402/svm/exact/client");
1744
1718
 
1745
1719
  // src/providers/MnemonicWalletProvider.ts
1746
1720
  var bip39 = __toESM(require("@scure/bip39"), 1);
1747
1721
  var import_english = require("@scure/bip39/wordlists/english.js");
1748
- var import_web35 = require("@solana/web3.js");
1722
+ var import_web36 = require("@solana/web3.js");
1749
1723
  var import_warps9 = require("@joai/warps");
1750
1724
  var import_bs582 = __toESM(require("bs58"), 1);
1751
1725
  var _MnemonicWalletProvider = class _MnemonicWalletProvider {
@@ -1774,22 +1748,22 @@ var _MnemonicWalletProvider = class _MnemonicWalletProvider {
1774
1748
  }
1775
1749
  async signTransaction(tx) {
1776
1750
  const keypair = this.getKeypair();
1777
- if (tx instanceof import_web35.VersionedTransaction) {
1751
+ if (tx instanceof import_web36.VersionedTransaction) {
1778
1752
  tx.sign([keypair]);
1779
1753
  return tx;
1780
1754
  }
1781
- if (tx instanceof import_web35.Transaction) {
1755
+ if (tx instanceof import_web36.Transaction) {
1782
1756
  tx.sign(keypair);
1783
1757
  return tx;
1784
1758
  }
1785
1759
  if (tx.transaction) {
1786
- if (tx.transaction instanceof import_web35.Transaction) {
1760
+ if (tx.transaction instanceof import_web36.Transaction) {
1787
1761
  tx.transaction.sign(keypair);
1788
1762
  return { ...tx, transaction: tx.transaction.serialize() };
1789
1763
  }
1790
1764
  if (typeof tx.transaction === "object") {
1791
1765
  try {
1792
- const transaction = import_web35.Transaction.from(tx.transaction);
1766
+ const transaction = import_web36.Transaction.from(tx.transaction);
1793
1767
  transaction.sign(keypair);
1794
1768
  return { ...tx, transaction: transaction.serialize(), signature: transaction.signature };
1795
1769
  } catch {
@@ -1821,7 +1795,7 @@ var _MnemonicWalletProvider = class _MnemonicWalletProvider {
1821
1795
  async importFromMnemonic(mnemonic) {
1822
1796
  const trimmedMnemonic = (0, import_warps9.normalizeAndValidateMnemonic)(mnemonic);
1823
1797
  const seed = bip39.mnemonicToSeedSync(trimmedMnemonic);
1824
- const keypair = import_web35.Keypair.fromSeed(seed.slice(0, 32));
1798
+ const keypair = import_web36.Keypair.fromSeed(seed.slice(0, 32));
1825
1799
  const walletDetails = {
1826
1800
  provider: _MnemonicWalletProvider.PROVIDER_NAME,
1827
1801
  address: keypair.publicKey.toBase58(),
@@ -1832,7 +1806,7 @@ var _MnemonicWalletProvider = class _MnemonicWalletProvider {
1832
1806
  return walletDetails;
1833
1807
  }
1834
1808
  async importFromPrivateKey(privateKey) {
1835
- const keypair = import_web35.Keypair.fromSecretKey(import_bs582.default.decode(privateKey));
1809
+ const keypair = import_web36.Keypair.fromSecretKey(import_bs582.default.decode(privateKey));
1836
1810
  const walletDetails = {
1837
1811
  provider: _MnemonicWalletProvider.PROVIDER_NAME,
1838
1812
  address: keypair.publicKey.toBase58(),
@@ -1858,7 +1832,7 @@ var _MnemonicWalletProvider = class _MnemonicWalletProvider {
1858
1832
  const mnemonic = (0, import_warps9.normalizeMnemonic)(mnemonicRaw);
1859
1833
  (0, import_warps9.validateMnemonicLength)(mnemonic);
1860
1834
  const seed = bip39.mnemonicToSeedSync(mnemonic);
1861
- const keypair = import_web35.Keypair.fromSeed(seed.slice(0, 32));
1835
+ const keypair = import_web36.Keypair.fromSeed(seed.slice(0, 32));
1862
1836
  return {
1863
1837
  provider: _MnemonicWalletProvider.PROVIDER_NAME,
1864
1838
  address: keypair.publicKey.toBase58(),
@@ -1871,7 +1845,7 @@ var _MnemonicWalletProvider = class _MnemonicWalletProvider {
1871
1845
  const mnemonic = (0, import_warps9.getWarpWalletMnemonicFromConfig)(this.config, this.chain.name);
1872
1846
  if (!mnemonic) throw new Error("No mnemonic provided");
1873
1847
  const seed = bip39.mnemonicToSeedSync(mnemonic);
1874
- this.keypair = import_web35.Keypair.fromSeed(seed.slice(0, 32));
1848
+ this.keypair = import_web36.Keypair.fromSeed(seed.slice(0, 32));
1875
1849
  return this.keypair;
1876
1850
  }
1877
1851
  };
@@ -1879,7 +1853,7 @@ _MnemonicWalletProvider.PROVIDER_NAME = "mnemonic";
1879
1853
  var MnemonicWalletProvider = _MnemonicWalletProvider;
1880
1854
 
1881
1855
  // src/providers/PrivateKeyWalletProvider.ts
1882
- var import_web36 = require("@solana/web3.js");
1856
+ var import_web37 = require("@solana/web3.js");
1883
1857
  var import_warps10 = require("@joai/warps");
1884
1858
  var import_bs583 = __toESM(require("bs58"), 1);
1885
1859
  var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
@@ -1908,22 +1882,22 @@ var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
1908
1882
  }
1909
1883
  async signTransaction(tx) {
1910
1884
  const keypair = this.getKeypair();
1911
- if (tx instanceof import_web36.VersionedTransaction) {
1885
+ if (tx instanceof import_web37.VersionedTransaction) {
1912
1886
  tx.sign([keypair]);
1913
1887
  return tx;
1914
1888
  }
1915
- if (tx instanceof import_web36.Transaction) {
1889
+ if (tx instanceof import_web37.Transaction) {
1916
1890
  tx.sign(keypair);
1917
1891
  return tx;
1918
1892
  }
1919
1893
  if (tx.transaction) {
1920
- if (tx.transaction instanceof import_web36.Transaction) {
1894
+ if (tx.transaction instanceof import_web37.Transaction) {
1921
1895
  tx.transaction.sign(keypair);
1922
1896
  return { ...tx, transaction: tx.transaction.serialize() };
1923
1897
  }
1924
1898
  if (typeof tx.transaction === "object") {
1925
1899
  try {
1926
- const transaction = import_web36.Transaction.from(tx.transaction);
1900
+ const transaction = import_web37.Transaction.from(tx.transaction);
1927
1901
  transaction.sign(keypair);
1928
1902
  return { ...tx, transaction: transaction.serialize(), signature: transaction.signature };
1929
1903
  } catch {
@@ -1956,7 +1930,7 @@ var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
1956
1930
  throw new Error("PrivateKeyWalletProvider does not support importing from mnemonics. Use MnemonicWalletProvider instead.");
1957
1931
  }
1958
1932
  async importFromPrivateKey(privateKey) {
1959
- const keypair = import_web36.Keypair.fromSecretKey(import_bs583.default.decode(privateKey));
1933
+ const keypair = import_web37.Keypair.fromSecretKey(import_bs583.default.decode(privateKey));
1960
1934
  const walletDetails = {
1961
1935
  provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
1962
1936
  address: keypair.publicKey.toBase58(),
@@ -1978,7 +1952,7 @@ var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
1978
1952
  };
1979
1953
  }
1980
1954
  async generate() {
1981
- const keypair = import_web36.Keypair.generate();
1955
+ const keypair = import_web37.Keypair.generate();
1982
1956
  return {
1983
1957
  provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
1984
1958
  address: keypair.publicKey.toBase58(),
@@ -1993,10 +1967,10 @@ var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
1993
1967
  try {
1994
1968
  const secretKey = import_bs583.default.decode(privateKey);
1995
1969
  if (secretKey.length === 64) {
1996
- this.keypair = import_web36.Keypair.fromSecretKey(secretKey);
1970
+ this.keypair = import_web37.Keypair.fromSecretKey(secretKey);
1997
1971
  return this.keypair;
1998
1972
  } else if (secretKey.length === 32) {
1999
- this.keypair = import_web36.Keypair.fromSeed(secretKey);
1973
+ this.keypair = import_web37.Keypair.fromSeed(secretKey);
2000
1974
  return this.keypair;
2001
1975
  } else {
2002
1976
  throw new Error(`Invalid private key length: expected 32 or 64 bytes, got ${secretKey.length}`);
@@ -2059,7 +2033,7 @@ var WarpSolanaWallet = class {
2059
2033
  this.cachedAddress = null;
2060
2034
  this.cachedPublicKey = null;
2061
2035
  const providerConfig = (0, import_warps12.getProviderConfig)(config, chain.name, config.env, chain.defaultApiUrl);
2062
- this.connection = new import_web37.Connection(providerConfig.url, "confirmed");
2036
+ this.connection = new import_web38.Connection(providerConfig.url, "confirmed");
2063
2037
  this.walletProvider = this.createProvider();
2064
2038
  this.initializeCache();
2065
2039
  }
@@ -2160,29 +2134,51 @@ var WarpSolanaWallet = class {
2160
2134
  throw new Error(`Unsupported wallet provider for ${this.chain.name}: ${provider}`);
2161
2135
  }
2162
2136
  resolveTransaction(tx) {
2163
- if (tx instanceof import_web37.VersionedTransaction) {
2164
- if (tx.version === void 0 || tx.version === "legacy") {
2165
- throw new Error("Transaction must be a VersionedTransaction (v0), not legacy");
2166
- }
2167
- return tx;
2137
+ const directVersionedTransaction = this.asVersionedTransaction(tx);
2138
+ if (directVersionedTransaction) return directVersionedTransaction;
2139
+ if (tx instanceof import_web38.Transaction) {
2140
+ throw new Error("Legacy Transaction format is not supported. All transactions must use VersionedTransaction (v0).");
2168
2141
  }
2169
- if (tx instanceof import_web37.Transaction) {
2142
+ const nestedTransaction = tx.transaction;
2143
+ const nestedVersionedTransaction = this.asVersionedTransaction(nestedTransaction);
2144
+ if (nestedVersionedTransaction) return nestedVersionedTransaction;
2145
+ if (nestedTransaction instanceof import_web38.Transaction) {
2170
2146
  throw new Error("Legacy Transaction format is not supported. All transactions must use VersionedTransaction (v0).");
2171
2147
  }
2172
- if (tx.transaction instanceof import_web37.VersionedTransaction) {
2173
- if (tx.transaction.version === void 0 || tx.transaction.version === "legacy") {
2174
- throw new Error("Transaction must be a VersionedTransaction (v0), not legacy");
2148
+ const serializedTransaction = this.toSerializedTransactionBytes(nestedTransaction);
2149
+ if (serializedTransaction) {
2150
+ try {
2151
+ return this.asVersionedTransactionOrThrow(import_web38.VersionedTransaction.deserialize(serializedTransaction));
2152
+ } catch {
2153
+ throw new Error("Invalid serialized transaction format. Expected a VersionedTransaction payload.");
2175
2154
  }
2176
- return tx.transaction;
2177
- }
2178
- if (tx.transaction instanceof import_web37.Transaction) {
2179
- throw new Error("Legacy Transaction format is not supported. All transactions must use VersionedTransaction (v0).");
2180
2155
  }
2181
- if (!tx.transaction) {
2156
+ if (!nestedTransaction) {
2182
2157
  throw new Error("Transaction must be signed before sending");
2183
2158
  }
2184
2159
  throw new Error("Invalid transaction format - only VersionedTransaction is supported");
2185
2160
  }
2161
+ asVersionedTransaction(tx) {
2162
+ if (!(tx instanceof import_web38.VersionedTransaction)) return null;
2163
+ return this.asVersionedTransactionOrThrow(tx);
2164
+ }
2165
+ asVersionedTransactionOrThrow(tx) {
2166
+ if (tx.version === void 0 || tx.version === "legacy") {
2167
+ throw new Error("Transaction must be a VersionedTransaction (v0), not legacy");
2168
+ }
2169
+ return tx;
2170
+ }
2171
+ toSerializedTransactionBytes(value) {
2172
+ if (value instanceof Uint8Array) return value;
2173
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return new Uint8Array(value);
2174
+ if (Array.isArray(value) && value.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) {
2175
+ return Uint8Array.from(value);
2176
+ }
2177
+ if (typeof value === "string" && value.trim() !== "") {
2178
+ return Uint8Array.from(Buffer.from(value.trim(), "base64"));
2179
+ }
2180
+ return null;
2181
+ }
2186
2182
  async shouldSkipPreflight(transaction) {
2187
2183
  if (!transaction.signatures || transaction.signatures.length === 0 || !transaction.signatures.some((sig) => sig.some((b) => b !== 0))) {
2188
2184
  return false;