@joai/warps-adapter-solana 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -918,7 +918,7 @@ var WarpSolanaOutput = class {
918
918
  output[key] = path;
919
919
  }
920
920
  }
921
- return { values, output: await evaluateOutputCommon(warp, output, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
921
+ return { values, output: await evaluateOutputCommon(warp, output, nativeValues, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
922
922
  }
923
923
  async getTransactionStatus(txHash) {
924
924
  try {
@@ -1028,19 +1028,29 @@ var WarpSolanaExecutor = class {
1028
1028
  const argsToUse = this.extractContractArgs(executable);
1029
1029
  const nativeArgs = argsToUse.map((arg) => this.serializer.coreSerializer.stringToNative(arg)[1]);
1030
1030
  const instructionData = this.buildInstructionData(action, nativeArgs);
1031
- const accounts = await this.buildInstructionAccounts(action, executable, fromPubkey, programId);
1032
- await this.ensureATAs(action, accounts, fromPubkey, instructions);
1031
+ const parsedAbi = this.parseAbi(action);
1032
+ const abiAccounts = parsedAbi?.instructions?.[action.func]?.accounts ?? null;
1033
+ const accounts = await this.buildInstructionAccounts(action, executable, fromPubkey, programId, abiAccounts);
1034
+ await this.ensureATAs(abiAccounts, accounts, fromPubkey, instructions);
1033
1035
  instructions.push(new TransactionInstruction({ keys: accounts, programId, data: instructionData }));
1034
1036
  if (executable.value > 0n) {
1035
1037
  instructions.push(SystemProgram.transfer({ fromPubkey, toPubkey: programId, lamports: Number(executable.value) }));
1036
1038
  }
1037
1039
  return this.setTransactionDefaults(instructions, fromPubkey);
1038
1040
  }
1039
- async ensureATAs(action, accounts, fromPubkey, instructions) {
1040
- if (!action.accounts || !Array.isArray(action.accounts)) return;
1041
+ parseAbi(action) {
1042
+ if (!action.abi || typeof action.abi !== "string") return null;
1043
+ try {
1044
+ return JSON.parse(action.abi);
1045
+ } catch {
1046
+ return null;
1047
+ }
1048
+ }
1049
+ async ensureATAs(abiAccounts, accounts, fromPubkey, instructions) {
1050
+ if (!abiAccounts || !Array.isArray(abiAccounts)) return;
1041
1051
  const createdATAs = /* @__PURE__ */ new Set();
1042
- for (let idx = 0; idx < action.accounts.length; idx++) {
1043
- const accountDef = action.accounts[idx];
1052
+ for (let idx = 0; idx < abiAccounts.length; idx++) {
1053
+ const accountDef = abiAccounts[idx];
1044
1054
  const accountStr = typeof accountDef === "string" ? accountDef : JSON.stringify(accountDef);
1045
1055
  if (accountStr.includes("{{USER_ATA:")) {
1046
1056
  const match = accountStr.match(/USER_ATA[:\s]*([^"}\s]+)/);
@@ -1164,7 +1174,7 @@ var WarpSolanaExecutor = class {
1164
1174
  }
1165
1175
  return Buffer.concat(buffers);
1166
1176
  }
1167
- async buildInstructionAccounts(action, executable, fromPubkey, programId) {
1177
+ async buildInstructionAccounts(action, executable, fromPubkey, programId, abiAccounts) {
1168
1178
  const accounts = [];
1169
1179
  const accountInputs = this.extractAccountInputs(action, executable);
1170
1180
  if (accountInputs.length > 0) {
@@ -1178,13 +1188,11 @@ var WarpSolanaExecutor = class {
1178
1188
  }
1179
1189
  return accounts;
1180
1190
  }
1181
- if (!action.accounts || !Array.isArray(action.accounts)) return accounts;
1182
- for (let idx = 0; idx < action.accounts.length; idx++) {
1183
- const accountDef = action.accounts[idx];
1191
+ if (!abiAccounts || !Array.isArray(abiAccounts)) return accounts;
1192
+ for (let idx = 0; idx < abiAccounts.length; idx++) {
1193
+ const accountDef = abiAccounts[idx];
1184
1194
  let address = this.extractAccountAddress(accountDef);
1185
- if (address === "[object Object]" || typeof accountDef === "string" && accountDef === "[object Object]") {
1186
- address = fromPubkey.toBase58();
1187
- } else if (!address || address.length === 0) {
1195
+ if (!address || address.length === 0) {
1188
1196
  throw new Error(`Invalid account definition at index ${idx}: ${JSON.stringify(accountDef)}`);
1189
1197
  }
1190
1198
  if (address === "{{USER_WALLET}}" || typeof address === "string" && address.includes("{{USER_WALLET}}")) {
@@ -1266,6 +1274,22 @@ var WarpSolanaExecutor = class {
1266
1274
  }
1267
1275
  }
1268
1276
  }
1277
+ if (address.includes("{{USER_ATA:") || address.includes("{{RECEIVER_ATA:")) {
1278
+ for (const resolved of resolvedInputs) {
1279
+ if (!resolved.input?.as) continue;
1280
+ const key = resolved.input.as.toUpperCase();
1281
+ if (address.includes(key)) {
1282
+ let value = resolved.value;
1283
+ if (typeof value === "string" && value.includes(":")) {
1284
+ value = value.split(":")[1];
1285
+ }
1286
+ if (value) {
1287
+ address = address.replace(new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), String(value));
1288
+ }
1289
+ }
1290
+ }
1291
+ return address;
1292
+ }
1269
1293
  return address;
1270
1294
  }
1271
1295
  async createTokenTransferTransaction(executable, userWallet, destinationPubkey) {
@@ -1362,28 +1386,15 @@ var WarpSolanaExecutor = class {
1362
1386
  resolvedInputs
1363
1387
  };
1364
1388
  }
1365
- async verifyMessage(message, signature) {
1366
- try {
1367
- const messageBytes = new TextEncoder().encode(message);
1368
- const signatureBytes = Buffer.from(signature, "base64");
1369
- return "";
1370
- } catch (error) {
1371
- throw new Error(`Failed to verify message: ${error}`);
1372
- }
1373
- }
1374
1389
  async setTransactionDefaults(instructions, fromPubkey) {
1375
1390
  const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
1376
1391
  const allInstructions = this.addComputeBudgetInstructions(instructions);
1377
- const accountMetaMap = this.buildAccountMetaMap(allInstructions, fromPubkey);
1378
- const { signedAccounts, unsignedAccounts } = this.sortAccounts(accountMetaMap);
1379
- const { staticAccountKeys, accountIndexMap } = this.buildAccountIndexMap(signedAccounts, unsignedAccounts);
1380
- const compiledInstructions = this.compileInstructions(allInstructions, accountIndexMap);
1381
- const messageV0 = this.buildMessageV0(blockhash, signedAccounts, unsignedAccounts, accountMetaMap, staticAccountKeys, compiledInstructions);
1382
- const versionedTx = new VersionedTransaction(messageV0);
1383
- if (versionedTx.version !== 0) {
1384
- throw new Error(`Expected VersionedTransaction v0, got version: ${versionedTx.version}`);
1385
- }
1386
- return versionedTx;
1392
+ const messageV0 = MessageV0.compile({
1393
+ payerKey: fromPubkey,
1394
+ instructions: allInstructions,
1395
+ recentBlockhash: blockhash
1396
+ });
1397
+ return new VersionedTransaction(messageV0);
1387
1398
  }
1388
1399
  toPublicKey(address, errorMsg) {
1389
1400
  try {
@@ -1423,20 +1434,8 @@ var WarpSolanaExecutor = class {
1423
1434
  extractAccountAddress(accountDef) {
1424
1435
  if (typeof accountDef === "string") return accountDef;
1425
1436
  if (!accountDef || typeof accountDef !== "object") return void 0;
1426
- const str = JSON.stringify(accountDef);
1427
- if (str.includes("USER_WALLET") || str.includes("{{USER_WALLET}}")) return "{{USER_WALLET}}";
1428
- if (str.includes("RECEIVER_ADDRESS") || str.includes("{{RECEIVER_ADDRESS}}")) return "{{RECEIVER_ADDRESS}}";
1429
- if (str.includes("USER_ATA")) {
1430
- const match = str.match(/USER_ATA[:\s]*([^"}\s]+)/);
1431
- if (match) return `{{USER_ATA:${match[1]}}}`;
1432
- }
1433
- const addrValue = accountDef.address || accountDef.pubkey || accountDef.value;
1434
- if (typeof addrValue === "string") return addrValue;
1435
- if (addrValue?.toBase58) return addrValue.toBase58();
1436
- if (addrValue?.identifier) return addrValue.identifier;
1437
- if (addrValue?.value) return addrValue.value;
1438
- const keys = Object.keys(accountDef);
1439
- if (keys.length === 1 && typeof accountDef[keys[0]] === "string") return accountDef[keys[0]];
1437
+ const address = accountDef.address || accountDef.pubkey;
1438
+ if (typeof address === "string") return address;
1440
1439
  return void 0;
1441
1440
  }
1442
1441
  async resolveAccountPubkey(address, fromPubkey) {
@@ -1485,81 +1484,6 @@ var WarpSolanaExecutor = class {
1485
1484
  const computeUnitPriceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: WarpSolanaConstants.PriorityFee.Default });
1486
1485
  return [computeUnitLimitIx, computeUnitPriceIx, ...instructions];
1487
1486
  }
1488
- buildAccountMetaMap(instructions, fromPubkey) {
1489
- const accountMetaMap = /* @__PURE__ */ new Map();
1490
- if (fromPubkey) {
1491
- accountMetaMap.set(fromPubkey.toBase58(), { pubkey: fromPubkey, isSigner: true, isWritable: true });
1492
- }
1493
- for (const ix of instructions) {
1494
- const programIdStr = ix.programId.toBase58();
1495
- if (!accountMetaMap.has(programIdStr)) {
1496
- accountMetaMap.set(programIdStr, { pubkey: ix.programId, isSigner: false, isWritable: false });
1497
- }
1498
- for (const key of ix.keys) {
1499
- const keyStr = key.pubkey.toBase58();
1500
- const existing = accountMetaMap.get(keyStr);
1501
- if (existing) {
1502
- accountMetaMap.set(keyStr, {
1503
- pubkey: key.pubkey,
1504
- isSigner: existing.isSigner || key.isSigner,
1505
- isWritable: existing.isWritable || key.isWritable
1506
- });
1507
- } else {
1508
- accountMetaMap.set(keyStr, {
1509
- pubkey: key.pubkey,
1510
- isSigner: key.isSigner,
1511
- isWritable: key.isWritable
1512
- });
1513
- }
1514
- }
1515
- }
1516
- return accountMetaMap;
1517
- }
1518
- sortAccounts(accountMetaMap) {
1519
- const signedAccounts = [];
1520
- const unsignedAccounts = [];
1521
- for (const meta of accountMetaMap.values()) {
1522
- ;
1523
- (meta.isSigner ? signedAccounts : unsignedAccounts).push(meta.pubkey);
1524
- }
1525
- const sortByWritable = (a, b) => (accountMetaMap.get(a.toBase58()).isWritable ? 0 : 1) - (accountMetaMap.get(b.toBase58()).isWritable ? 0 : 1);
1526
- signedAccounts.sort(sortByWritable);
1527
- unsignedAccounts.sort(sortByWritable);
1528
- return { signedAccounts, unsignedAccounts };
1529
- }
1530
- buildAccountIndexMap(signedAccounts, unsignedAccounts) {
1531
- const staticAccountKeys = [...signedAccounts, ...unsignedAccounts];
1532
- const accountIndexMap = /* @__PURE__ */ new Map();
1533
- staticAccountKeys.forEach((key, index) => {
1534
- accountIndexMap.set(key.toBase58(), index);
1535
- });
1536
- return { staticAccountKeys, accountIndexMap };
1537
- }
1538
- compileInstructions(instructions, accountIndexMap) {
1539
- return instructions.map((ix) => {
1540
- const programIdIndex = accountIndexMap.get(ix.programId.toBase58());
1541
- const accountKeyIndexes = ix.keys.map((key) => accountIndexMap.get(key.pubkey.toBase58()));
1542
- return {
1543
- programIdIndex,
1544
- accountKeyIndexes,
1545
- data: Uint8Array.from(ix.data)
1546
- };
1547
- });
1548
- }
1549
- buildMessageV0(blockhash, signedAccounts, unsignedAccounts, accountMetaMap, staticAccountKeys, compiledInstructions) {
1550
- const getWritable = (key) => accountMetaMap.get(key.toBase58()).isWritable;
1551
- return new MessageV0({
1552
- header: {
1553
- numRequiredSignatures: signedAccounts.length,
1554
- numReadonlySignedAccounts: signedAccounts.filter((k) => !getWritable(k)).length,
1555
- numReadonlyUnsignedAccounts: unsignedAccounts.filter((k) => !getWritable(k)).length
1556
- },
1557
- staticAccountKeys,
1558
- recentBlockhash: blockhash,
1559
- compiledInstructions,
1560
- addressTableLookups: []
1561
- });
1562
- }
1563
1487
  };
1564
1488
 
1565
1489
  // src/WarpSolanaExplorer.ts