@vleap/warps-adapter-solana 0.1.0-beta.5 → 0.1.0-beta.7

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
@@ -65,6 +65,11 @@ var SolanaExplorerNames = {
65
65
  devnet: ["solscan_devnet" /* SolscanDevnet */, "solana_explorer_devnet" /* SolanaExplorerDevnet */]
66
66
  };
67
67
  var SolanaExplorerUrls = ExplorerUrls;
68
+ var X402SolanaNetworkIdentifiers = {
69
+ Mainnet: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
70
+ Devnet: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
71
+ };
72
+ var SupportedX402SolanaNetworks = [X402SolanaNetworkIdentifiers.Mainnet, X402SolanaNetworkIdentifiers.Devnet];
68
73
 
69
74
  // src/tokens/solana.ts
70
75
  import { WarpChainName } from "@vleap/warps";
@@ -1243,24 +1248,49 @@ var WarpSolanaExplorer = class {
1243
1248
  };
1244
1249
 
1245
1250
  // src/WarpSolanaWallet.ts
1251
+ import { createKeyPairSignerFromBytes } from "@solana/kit";
1252
+ import { Connection as Connection6, Transaction as Transaction4, VersionedTransaction as VersionedTransaction3 } from "@solana/web3.js";
1246
1253
  import {
1247
1254
  getProviderConfig as getProviderConfig4,
1248
- getWarpWalletMnemonicFromConfig,
1249
- getWarpWalletPrivateKeyFromConfig
1255
+ initializeWalletCache
1250
1256
  } from "@vleap/warps";
1251
- import { Connection as Connection4, Keypair, Transaction as Transaction2, VersionedTransaction } from "@solana/web3.js";
1257
+ import { registerExactSvmScheme } from "@x402/svm/exact/client";
1258
+
1259
+ // src/providers/MnemonicWalletProvider.ts
1252
1260
  import * as bip39 from "@scure/bip39";
1253
1261
  import { wordlist } from "@scure/bip39/wordlists/english.js";
1262
+ import { Keypair, Transaction as Transaction2, VersionedTransaction } from "@solana/web3.js";
1263
+ import {
1264
+ getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig3,
1265
+ getWarpWalletMnemonicFromConfig
1266
+ } from "@vleap/warps";
1254
1267
  import bs582 from "bs58";
1255
- var WarpSolanaWallet = class {
1256
- constructor(config, chain) {
1268
+ var MnemonicWalletProvider = class {
1269
+ constructor(config, chain, connection) {
1257
1270
  this.config = config;
1258
1271
  this.chain = chain;
1259
- const providerConfig = getProviderConfig4(config, chain.name, config.env, chain.defaultApiUrl);
1260
- this.connection = new Connection4(providerConfig.url, "confirmed");
1272
+ this.connection = connection;
1273
+ this.keypair = null;
1274
+ }
1275
+ async getAddress() {
1276
+ const address = getWarpWalletAddressFromConfig3(this.config, this.chain.name);
1277
+ if (address) return address;
1278
+ try {
1279
+ const keypair = this.getKeypair();
1280
+ return keypair.publicKey.toBase58();
1281
+ } catch {
1282
+ return null;
1283
+ }
1284
+ }
1285
+ async getPublicKey() {
1286
+ try {
1287
+ const keypair = this.getKeypair();
1288
+ return keypair.publicKey.toBase58();
1289
+ } catch {
1290
+ return null;
1291
+ }
1261
1292
  }
1262
1293
  async signTransaction(tx) {
1263
- if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
1264
1294
  const keypair = this.getKeypair();
1265
1295
  if (tx instanceof VersionedTransaction) {
1266
1296
  tx.sign([keypair]);
@@ -1287,28 +1317,6 @@ var WarpSolanaWallet = class {
1287
1317
  }
1288
1318
  throw new Error("Invalid transaction format");
1289
1319
  }
1290
- async signTransactions(txs) {
1291
- if (txs.length === 0) return [];
1292
- const keypair = this.getKeypair();
1293
- return Promise.all(
1294
- txs.map(async (tx) => {
1295
- if (tx instanceof VersionedTransaction) {
1296
- tx.sign([keypair]);
1297
- return tx;
1298
- }
1299
- if (tx instanceof Transaction2) {
1300
- tx.sign(keypair);
1301
- return tx;
1302
- }
1303
- if (tx.transaction && typeof tx.transaction === "object") {
1304
- const transaction = Transaction2.from(tx.transaction);
1305
- transaction.sign(keypair);
1306
- return { ...tx, transaction: transaction.serialize() };
1307
- }
1308
- throw new Error("Invalid transaction format");
1309
- })
1310
- );
1311
- }
1312
1320
  async signMessage(message) {
1313
1321
  const keypair = this.getKeypair();
1314
1322
  const messageBytes = new TextEncoder().encode(message);
@@ -1325,45 +1333,14 @@ var WarpSolanaWallet = class {
1325
1333
  const signature = nacl.sign.detached(messageBytes, privateKeyBytes);
1326
1334
  return bs582.encode(signature);
1327
1335
  }
1328
- async sendTransaction(tx) {
1329
- if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
1330
- let transaction;
1331
- if (tx instanceof VersionedTransaction) {
1332
- transaction = tx;
1333
- } else if (tx instanceof Transaction2) {
1334
- transaction = tx;
1335
- } else if (tx.transaction) {
1336
- if (tx.transaction instanceof Transaction2) {
1337
- transaction = tx.transaction;
1338
- } else if (tx.transaction instanceof VersionedTransaction) {
1339
- transaction = tx.transaction;
1340
- } else if (typeof tx.transaction === "object") {
1341
- try {
1342
- transaction = Transaction2.from(tx.transaction);
1343
- } catch {
1344
- throw new Error("Invalid transaction format");
1345
- }
1346
- } else if (Buffer.isBuffer(tx.transaction) || typeof tx.transaction === "string") {
1347
- transaction = Transaction2.from(tx.transaction);
1348
- } else {
1349
- throw new Error("Transaction must be signed before sending");
1350
- }
1351
- } else {
1352
- throw new Error("Transaction must be signed before sending");
1353
- }
1354
- const signature = await this.connection.sendRawTransaction(transaction.serialize(), {
1355
- skipPreflight: true,
1356
- maxRetries: 3
1357
- });
1358
- return signature;
1359
- }
1360
- async sendTransactions(txs) {
1361
- return Promise.all(txs.map(async (tx) => this.sendTransaction(tx)));
1336
+ getKeypairInstance() {
1337
+ return this.getKeypair();
1362
1338
  }
1363
1339
  create(mnemonic) {
1364
1340
  const seed = bip39.mnemonicToSeedSync(mnemonic);
1365
1341
  const keypair = Keypair.fromSeed(seed.slice(0, 32));
1366
1342
  return {
1343
+ provider: "mnemonic",
1367
1344
  address: keypair.publicKey.toBase58(),
1368
1345
  privateKey: bs582.encode(keypair.secretKey),
1369
1346
  mnemonic
@@ -1374,12 +1351,41 @@ var WarpSolanaWallet = class {
1374
1351
  const entropy = keypair.secretKey.slice(0, 16);
1375
1352
  const mnemonic = bip39.entropyToMnemonic(entropy, wordlist);
1376
1353
  return {
1354
+ provider: "mnemonic",
1377
1355
  address: keypair.publicKey.toBase58(),
1378
1356
  privateKey: bs582.encode(keypair.secretKey),
1379
1357
  mnemonic
1380
1358
  };
1381
1359
  }
1382
- getAddress() {
1360
+ getKeypair() {
1361
+ if (this.keypair) return this.keypair;
1362
+ const mnemonic = getWarpWalletMnemonicFromConfig(this.config, this.chain.name);
1363
+ if (!mnemonic) throw new Error("No mnemonic provided");
1364
+ const seed = bip39.mnemonicToSeedSync(mnemonic);
1365
+ this.keypair = Keypair.fromSeed(seed.slice(0, 32));
1366
+ return this.keypair;
1367
+ }
1368
+ };
1369
+
1370
+ // src/providers/PrivateKeyWalletProvider.ts
1371
+ import * as bip392 from "@scure/bip39";
1372
+ import { wordlist as wordlist2 } from "@scure/bip39/wordlists/english.js";
1373
+ import { Keypair as Keypair2, Transaction as Transaction3, VersionedTransaction as VersionedTransaction2 } from "@solana/web3.js";
1374
+ import {
1375
+ getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig4,
1376
+ getWarpWalletPrivateKeyFromConfig
1377
+ } from "@vleap/warps";
1378
+ import bs583 from "bs58";
1379
+ var PrivateKeyWalletProvider = class {
1380
+ constructor(config, chain, connection) {
1381
+ this.config = config;
1382
+ this.chain = chain;
1383
+ this.connection = connection;
1384
+ this.keypair = null;
1385
+ }
1386
+ async getAddress() {
1387
+ const address = getWarpWalletAddressFromConfig4(this.config, this.chain.name);
1388
+ if (address) return address;
1383
1389
  try {
1384
1390
  const keypair = this.getKeypair();
1385
1391
  return keypair.publicKey.toBase58();
@@ -1387,7 +1393,7 @@ var WarpSolanaWallet = class {
1387
1393
  return null;
1388
1394
  }
1389
1395
  }
1390
- getPublicKey() {
1396
+ async getPublicKey() {
1391
1397
  try {
1392
1398
  const keypair = this.getKeypair();
1393
1399
  return keypair.publicKey.toBase58();
@@ -1395,31 +1401,203 @@ var WarpSolanaWallet = class {
1395
1401
  return null;
1396
1402
  }
1397
1403
  }
1404
+ async signTransaction(tx) {
1405
+ const keypair = this.getKeypair();
1406
+ if (tx instanceof VersionedTransaction2) {
1407
+ tx.sign([keypair]);
1408
+ return tx;
1409
+ }
1410
+ if (tx instanceof Transaction3) {
1411
+ tx.sign(keypair);
1412
+ return tx;
1413
+ }
1414
+ if (tx.transaction) {
1415
+ if (tx.transaction instanceof Transaction3) {
1416
+ tx.transaction.sign(keypair);
1417
+ return { ...tx, transaction: tx.transaction.serialize() };
1418
+ }
1419
+ if (typeof tx.transaction === "object") {
1420
+ try {
1421
+ const transaction = Transaction3.from(tx.transaction);
1422
+ transaction.sign(keypair);
1423
+ return { ...tx, transaction: transaction.serialize(), signature: transaction.signature };
1424
+ } catch {
1425
+ throw new Error("Invalid transaction format");
1426
+ }
1427
+ }
1428
+ }
1429
+ throw new Error("Invalid transaction format");
1430
+ }
1431
+ async signMessage(message) {
1432
+ const keypair = this.getKeypair();
1433
+ const messageBytes = new TextEncoder().encode(message);
1434
+ const nacl = await import("tweetnacl");
1435
+ const secretKey = keypair.secretKey;
1436
+ if (secretKey.length !== 64) {
1437
+ throw new Error(`Invalid secret key length: expected 64, got ${secretKey.length}`);
1438
+ }
1439
+ const privateKeySlice = secretKey.slice(0, 32);
1440
+ const privateKeyBytes = new Uint8Array(privateKeySlice);
1441
+ if (privateKeyBytes.length !== 32) {
1442
+ throw new Error(`Invalid private key length: expected 32, got ${privateKeyBytes.length}`);
1443
+ }
1444
+ const signature = nacl.sign.detached(messageBytes, privateKeyBytes);
1445
+ return bs583.encode(signature);
1446
+ }
1447
+ getKeypairInstance() {
1448
+ return this.getKeypair();
1449
+ }
1450
+ create(mnemonic) {
1451
+ const seed = bip392.mnemonicToSeedSync(mnemonic);
1452
+ const keypair = Keypair2.fromSeed(seed.slice(0, 32));
1453
+ return {
1454
+ provider: "privateKey",
1455
+ address: keypair.publicKey.toBase58(),
1456
+ privateKey: bs583.encode(keypair.secretKey),
1457
+ mnemonic
1458
+ };
1459
+ }
1460
+ generate() {
1461
+ const keypair = Keypair2.generate();
1462
+ const entropy = keypair.secretKey.slice(0, 16);
1463
+ const mnemonic = bip392.entropyToMnemonic(entropy, wordlist2);
1464
+ return {
1465
+ provider: "privateKey",
1466
+ address: keypair.publicKey.toBase58(),
1467
+ privateKey: bs583.encode(keypair.secretKey),
1468
+ mnemonic
1469
+ };
1470
+ }
1398
1471
  getKeypair() {
1472
+ if (this.keypair) return this.keypair;
1399
1473
  const privateKey = getWarpWalletPrivateKeyFromConfig(this.config, this.chain.name);
1400
- if (privateKey) {
1401
- try {
1402
- const secretKey = bs582.decode(privateKey);
1403
- if (secretKey.length === 64) {
1404
- return Keypair.fromSecretKey(secretKey);
1405
- } else if (secretKey.length === 32) {
1406
- return Keypair.fromSeed(secretKey);
1407
- } else {
1408
- throw new Error(`Invalid private key length: expected 32 or 64 bytes, got ${secretKey.length}`);
1409
- }
1410
- } catch (error) {
1411
- if (error instanceof Error) {
1412
- throw new Error(`Invalid private key format: ${error.message}`);
1474
+ if (!privateKey) throw new Error("No private key provided");
1475
+ try {
1476
+ const secretKey = bs583.decode(privateKey);
1477
+ if (secretKey.length === 64) {
1478
+ this.keypair = Keypair2.fromSecretKey(secretKey);
1479
+ return this.keypair;
1480
+ } else if (secretKey.length === 32) {
1481
+ this.keypair = Keypair2.fromSeed(secretKey);
1482
+ return this.keypair;
1483
+ } else {
1484
+ throw new Error(`Invalid private key length: expected 32 or 64 bytes, got ${secretKey.length}`);
1485
+ }
1486
+ } catch (error) {
1487
+ if (error instanceof Error) {
1488
+ throw new Error(`Invalid private key format: ${error.message}`);
1489
+ }
1490
+ throw new Error("Invalid private key format");
1491
+ }
1492
+ }
1493
+ };
1494
+
1495
+ // src/WarpSolanaWallet.ts
1496
+ var WarpSolanaWallet = class {
1497
+ constructor(config, chain) {
1498
+ this.config = config;
1499
+ this.chain = chain;
1500
+ this.cachedAddress = null;
1501
+ this.cachedPublicKey = null;
1502
+ const providerConfig = getProviderConfig4(config, chain.name, config.env, chain.defaultApiUrl);
1503
+ this.connection = new Connection6(providerConfig.url, "confirmed");
1504
+ this.walletProvider = this.createProvider();
1505
+ this.initializeCache();
1506
+ }
1507
+ createProvider() {
1508
+ const wallet = this.config.user?.wallets?.[this.chain.name];
1509
+ if (!wallet) return null;
1510
+ if (typeof wallet === "string") throw new Error(`Wallet can not be used for signing: ${wallet}`);
1511
+ const customWalletProviders = this.config.walletProviders?.[this.chain.name];
1512
+ const providerFactory = customWalletProviders?.[wallet.provider];
1513
+ if (providerFactory) return providerFactory(this.config, this.chain);
1514
+ if (wallet.provider === "privateKey") return new PrivateKeyWalletProvider(this.config, this.chain, this.connection);
1515
+ if (wallet.provider === "mnemonic") return new MnemonicWalletProvider(this.config, this.chain, this.connection);
1516
+ throw new Error(`Unsupported wallet provider for ${this.chain.name}: ${wallet.provider}`);
1517
+ }
1518
+ initializeCache() {
1519
+ initializeWalletCache(this.walletProvider).then((cache) => {
1520
+ this.cachedAddress = cache.address;
1521
+ this.cachedPublicKey = cache.publicKey;
1522
+ });
1523
+ }
1524
+ async signTransaction(tx) {
1525
+ if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
1526
+ if (!this.walletProvider) throw new Error("No wallet provider available");
1527
+ return await this.walletProvider.signTransaction(tx);
1528
+ }
1529
+ async signTransactions(txs) {
1530
+ if (txs.length === 0) return [];
1531
+ return Promise.all(txs.map(async (tx) => this.signTransaction(tx)));
1532
+ }
1533
+ async signMessage(message) {
1534
+ if (!this.walletProvider) throw new Error("No wallet provider available");
1535
+ return await this.walletProvider.signMessage(message);
1536
+ }
1537
+ async sendTransaction(tx) {
1538
+ if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
1539
+ let transaction;
1540
+ if (tx instanceof VersionedTransaction3) {
1541
+ transaction = tx;
1542
+ } else if (tx instanceof Transaction4) {
1543
+ transaction = tx;
1544
+ } else if (tx.transaction) {
1545
+ if (tx.transaction instanceof Transaction4) {
1546
+ transaction = tx.transaction;
1547
+ } else if (tx.transaction instanceof VersionedTransaction3) {
1548
+ transaction = tx.transaction;
1549
+ } else if (typeof tx.transaction === "object") {
1550
+ try {
1551
+ transaction = Transaction4.from(tx.transaction);
1552
+ } catch {
1553
+ throw new Error("Invalid transaction format");
1413
1554
  }
1414
- throw new Error("Invalid private key format");
1555
+ } else if (Buffer.isBuffer(tx.transaction) || typeof tx.transaction === "string") {
1556
+ transaction = Transaction4.from(tx.transaction);
1557
+ } else {
1558
+ throw new Error("Transaction must be signed before sending");
1415
1559
  }
1560
+ } else {
1561
+ throw new Error("Transaction must be signed before sending");
1416
1562
  }
1417
- const mnemonic = getWarpWalletMnemonicFromConfig(this.config, this.chain.name);
1418
- if (mnemonic) {
1419
- const seed = bip39.mnemonicToSeedSync(mnemonic);
1420
- return Keypair.fromSeed(seed.slice(0, 32));
1563
+ const signature = await this.connection.sendRawTransaction(transaction.serialize(), {
1564
+ skipPreflight: true,
1565
+ maxRetries: 3
1566
+ });
1567
+ return signature;
1568
+ }
1569
+ async sendTransactions(txs) {
1570
+ return Promise.all(txs.map(async (tx) => this.sendTransaction(tx)));
1571
+ }
1572
+ create(mnemonic) {
1573
+ if (!this.walletProvider) throw new Error("No wallet provider available");
1574
+ return this.walletProvider.create(mnemonic);
1575
+ }
1576
+ generate() {
1577
+ if (!this.walletProvider) throw new Error("No wallet provider available");
1578
+ return this.walletProvider.generate();
1579
+ }
1580
+ getAddress() {
1581
+ return this.cachedAddress;
1582
+ }
1583
+ getPublicKey() {
1584
+ return this.cachedPublicKey;
1585
+ }
1586
+ async registerX402Handlers(client) {
1587
+ if (!this.walletProvider) return {};
1588
+ const provider = this.walletProvider;
1589
+ const getKeypair = provider.getKeypairInstance;
1590
+ if (typeof getKeypair !== "function") return {};
1591
+ const keypair = getKeypair();
1592
+ if (!keypair || !keypair.secretKey) return {};
1593
+ const signer = await createKeyPairSignerFromBytes(keypair.secretKey);
1594
+ const handlers = {};
1595
+ for (const network of SupportedX402SolanaNetworks) {
1596
+ handlers[network] = () => {
1597
+ registerExactSvmScheme(client, { signer });
1598
+ };
1421
1599
  }
1422
- throw new Error("No private key or mnemonic provided");
1600
+ return handlers;
1423
1601
  }
1424
1602
  };
1425
1603
 
@@ -1452,7 +1630,7 @@ var NativeTokenSol = {
1452
1630
  decimals: 9,
1453
1631
  logoUrl: "https://joai.ai/images/tokens/sol.svg"
1454
1632
  };
1455
- var getSolanaAdapter = createSolanaAdapter(WarpChainName2.Solana, {
1633
+ var SolanaAdapter = createSolanaAdapter(WarpChainName2.Solana, {
1456
1634
  mainnet: {
1457
1635
  name: WarpChainName2.Solana,
1458
1636
  displayName: "Solana Mainnet",
@@ -1488,10 +1666,12 @@ export {
1488
1666
  ExplorerUrls,
1489
1667
  KnownTokens,
1490
1668
  NativeTokenSol,
1669
+ SolanaAdapter,
1491
1670
  SolanaExplorerMap,
1492
1671
  SolanaExplorerNames,
1493
1672
  SolanaExplorerUrls,
1494
1673
  SolanaExplorers,
1674
+ SupportedX402SolanaNetworks,
1495
1675
  WarpSolanaConstants,
1496
1676
  WarpSolanaDataLoader,
1497
1677
  WarpSolanaExecutor,
@@ -1499,8 +1679,8 @@ export {
1499
1679
  WarpSolanaOutput,
1500
1680
  WarpSolanaSerializer,
1501
1681
  WarpSolanaWallet,
1682
+ X402SolanaNetworkIdentifiers,
1502
1683
  findKnownTokenById,
1503
- getKnownTokensForChain,
1504
- getSolanaAdapter
1684
+ getKnownTokensForChain
1505
1685
  };
1506
1686
  //# sourceMappingURL=index.mjs.map