@deserialize/multi-vm-wallet 1.2.2 → 1.2.4

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 (42) hide show
  1. package/dist/IChainWallet.d.ts +6 -1
  2. package/dist/IChainWallet.js.map +1 -1
  3. package/dist/constant.js +32 -18
  4. package/dist/constant.js.map +1 -1
  5. package/dist/evm/evm.d.ts +5 -1
  6. package/dist/evm/evm.js +11 -2
  7. package/dist/evm/evm.js.map +1 -1
  8. package/dist/evm/transaction.utils.d.ts +362 -0
  9. package/dist/evm/transaction.utils.js +669 -0
  10. package/dist/evm/transaction.utils.js.map +1 -0
  11. package/dist/evm/transactionParsing.d.ts +1 -3633
  12. package/dist/evm/transactionParsing.js +0 -27
  13. package/dist/evm/transactionParsing.js.map +1 -1
  14. package/dist/evm/utils.d.ts +13 -1
  15. package/dist/evm/utils.js +101 -2
  16. package/dist/evm/utils.js.map +1 -1
  17. package/dist/helpers/index.d.ts +2 -1
  18. package/dist/helpers/index.js +5 -0
  19. package/dist/helpers/index.js.map +1 -1
  20. package/dist/svm/svm.d.ts +14 -4
  21. package/dist/svm/svm.js +25 -7
  22. package/dist/svm/svm.js.map +1 -1
  23. package/dist/svm/utils.d.ts +9 -3
  24. package/dist/svm/utils.js +94 -12
  25. package/dist/svm/utils.js.map +1 -1
  26. package/dist/test.d.ts +4 -0
  27. package/dist/test.js +38 -18
  28. package/dist/test.js.map +1 -1
  29. package/dist/types.d.ts +110 -0
  30. package/dist/types.js.map +1 -1
  31. package/package.json +5 -2
  32. package/utils/IChainWallet.ts +6 -3
  33. package/utils/constant.ts +34 -18
  34. package/utils/evm/evm.ts +17 -4
  35. package/utils/evm/transaction.utils.ts +824 -0
  36. package/utils/evm/transactionParsing.ts +0 -26
  37. package/utils/evm/utils.ts +110 -3
  38. package/utils/helpers/index.ts +7 -1
  39. package/utils/svm/svm.ts +40 -9
  40. package/utils/svm/utils.ts +131 -16
  41. package/utils/test.ts +48 -18
  42. package/utils/types.ts +140 -0
@@ -610,30 +610,4 @@ async function parseTransferLogs(
610
610
  return { tokens, nfts };
611
611
  }
612
612
 
613
- /**
614
- * Helper function to create a client
615
- */
616
- export function createEVMClient(rpcUrl: string) {
617
- return createPublicClient({
618
- transport: http(rpcUrl),
619
- });
620
- }
621
-
622
- // Example usage:
623
- /*
624
- import { mainnet } from 'viem/chains';
625
-
626
- const client = createPublicClient({
627
- chain: mainnet,
628
- transport: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY'),
629
- });
630
-
631
- const history = await getEVMTransactionHistoryWithAPI(
632
- client,
633
- '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb' as Address,
634
- 'https://api.etherscan.io/api',
635
- 'YOUR_ETHERSCAN_API_KEY'
636
- );
637
613
 
638
- console.log(history);
639
- */
@@ -1,7 +1,8 @@
1
- import { Balance, ChainWalletConfig, SUPPORTED_VM, UserTokenBalance, TokenInfo } from '../types'
2
- import { JsonRpcProvider, Contract, Wallet, TransactionRequest, TransactionResponse, TransactionReceipt, parseUnits, formatUnits } from 'ethers'
1
+ import { Balance, ChainWalletConfig, SUPPORTED_VM, UserTokenBalance, TokenInfo, EVMNFT, NFT } from '../types'
2
+ import { JsonRpcProvider, Contract, Wallet, TransactionRequest, TransactionResponse, TransactionReceipt, parseUnits, formatUnits, ethers } from 'ethers'
3
3
  import BN from 'bn.js'
4
4
  import { HelperAPI } from '../helpers';
5
+ import BigNumber from 'bignumber.js';
5
6
 
6
7
  const KYBER_BASE_URL = 'https://aggregator-api.kyberswap.com';
7
8
 
@@ -149,10 +150,11 @@ const ERC20_ABI = [
149
150
 
150
151
  export const getNativeBalance = async (address: string, provider: JsonRpcProvider): Promise<Balance> => {
151
152
  const balance = await provider.getBalance(address)
153
+ const final = ethers.formatEther(balance)
152
154
 
153
155
  return {
154
156
  balance: new BN(balance),
155
- formatted: Number(balance / 10n ** 18n),
157
+ formatted: Number(final),
156
158
  decimal: 18
157
159
  }
158
160
  }
@@ -654,6 +656,24 @@ export const discoverTokens = async (wallet: string, chain: ChainWalletConfig):
654
656
  return formatBalances
655
657
  }
656
658
 
659
+ export function calcGasTotal(gasLimit = '0', gasPrice = '0') {
660
+ return new BN(gasLimit, 16).mul(new BN(gasPrice, 16)).toString();
661
+ }
662
+ export function toPrecisionWithoutTrailingZeros(n: number, precision: number) {
663
+ return new BigNumber(n)
664
+ .toPrecision(precision)
665
+ .replace(/(\.[0-9]*[1-9])0*|(\.0*)/u, '$1');
666
+ }
667
+
668
+ /**
669
+ * @param {number|string|BigNumber} value
670
+ * @param {number=} decimals
671
+ * @returns {BigNumber}
672
+ */
673
+ export function calcTokenAmount(value: number | string | BigNumber, decimals?: number): BigNumber {
674
+ const divisor = new BigNumber(10).pow(decimals ?? 0);
675
+ return new BigNumber(String(value)).div(divisor);
676
+ }
657
677
  //swaps
658
678
 
659
679
 
@@ -934,4 +954,91 @@ export function prepareSwapParams(
934
954
 
935
955
  export function convertSlippageForDebonk(slippageBps: number): number {
936
956
  return slippageBps / 100;
957
+ }
958
+
959
+ export const transformEVMNFTToUnified = (nft: EVMNFT): NFT => {
960
+ // Extract image URL from various sources
961
+ const imageUrl = nft.image?.cachedUrl ||
962
+ nft.image?.thumbnailUrl ||
963
+ nft.image?.pngUrl ||
964
+ nft.image?.originalUrl ||
965
+ nft.openSeaMetadata?.imageUrl ||
966
+ nft.raw?.metadata?.image ||
967
+ undefined;
968
+
969
+ // Extract attributes
970
+ const attributes = nft.raw?.metadata?.attributes?.map(attr => ({
971
+ trait_type: attr.trait_type,
972
+ value: attr.value,
973
+ display_type: attr.display_type
974
+ }));
975
+
976
+ return {
977
+ id: `${nft.contract.address}:${nft.tokenId}`,
978
+ name: nft.name || nft.raw?.metadata?.name || 'Unknown',
979
+ symbol: nft.contract.symbol,
980
+ description: nft.description || nft.raw?.metadata?.description || '',
981
+ image: imageUrl,
982
+ uri: nft.raw?.tokenUri || '',
983
+ collection: {
984
+ address: nft.contract.address,
985
+ name: nft.openSeaMetadata?.collectionName || nft.contract.name,
986
+ verified: nft.openSeaMetadata?.safelistRequestStatus === 'verified'
987
+ },
988
+ chainType: 'EVM',
989
+ balance: nft.balance,
990
+ attributes,
991
+ tokenStandard: nft.tokenType,
992
+ isSpam: nft.contract.isSpam,
993
+ raw: {
994
+ evm: nft
995
+ }
996
+ };
997
+ };
998
+
999
+ export const discoverNFTs = async (wallet: string, chain: ChainWalletConfig): Promise<NFT[]> => {
1000
+ console.log('discoverNFTs: Starting NFT discovery');
1001
+ console.log('Wallet:', wallet);
1002
+ console.log('Chain:', chain.name, 'ChainId:', chain.chainId);
1003
+
1004
+ try {
1005
+ const response = await HelperAPI.getUserNFTs(wallet, chain.vmType ?? "EVM", chain.chainId);
1006
+
1007
+ console.log('discoverNFTs: Successfully fetched', response.data.length, 'NFTs');
1008
+
1009
+ // Filter out spam NFTs if desired (optional)
1010
+ const evmNfts = response.data.filter(nft => !nft.contract.isSpam);
1011
+
1012
+ console.log('discoverNFTs: After spam filtering:', evmNfts.length, 'NFTs');
1013
+
1014
+ // Transform to unified NFT format
1015
+ const nfts = evmNfts.map(transformEVMNFTToUnified);
1016
+
1017
+ return nfts;
1018
+ } catch (error) {
1019
+ console.error('discoverNFTs: Error fetching NFTs:', error);
1020
+ console.error('Error details:', error instanceof Error ? error.message : 'Unknown error');
1021
+ throw error;
1022
+ }
1023
+ }
1024
+
1025
+ export const discoverAllNFTs = async (wallet: string, chain: ChainWalletConfig): Promise<NFT[]> => {
1026
+ console.log('discoverAllNFTs: Starting NFT discovery (including spam)');
1027
+ console.log('Wallet:', wallet);
1028
+ console.log('Chain:', chain.name, 'ChainId:', chain.chainId);
1029
+
1030
+ try {
1031
+ const response = await HelperAPI.getUserNFTs(wallet, chain.vmType ?? "EVM", chain.chainId);
1032
+
1033
+ console.log('discoverAllNFTs: Successfully fetched', response.data.length, 'NFTs (including spam)');
1034
+
1035
+ // Transform to unified NFT format
1036
+ const nfts = response.data.map(transformEVMNFTToUnified);
1037
+
1038
+ return nfts;
1039
+ } catch (error) {
1040
+ console.error('discoverAllNFTs: Error fetching NFTs:', error);
1041
+ console.error('Error details:', error instanceof Error ? error.message : 'Unknown error');
1042
+ throw error;
1043
+ }
937
1044
  }
@@ -1,4 +1,4 @@
1
- import { vmTypes } from "../types";
1
+ import { vmTypes, EVMNFTResponse } from "../types";
2
2
 
3
3
  const BASE_URL = "https://helper.decane.app"
4
4
 
@@ -8,4 +8,10 @@ export class HelperAPI {
8
8
  const data = await res.json();
9
9
  return data;
10
10
  }
11
+
12
+ static async getUserNFTs(wallet: string, vm: vmTypes, chainId: number): Promise<EVMNFTResponse> {
13
+ const res = await fetch("" + BASE_URL + `/${vm}/nfts/discover?wallet=${wallet}&chainId=${chainId}`);
14
+ const data = await res.json();
15
+ return data;
16
+ }
11
17
  }
package/utils/svm/svm.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Connection, Keypair, PublicKey } from "@solana/web3.js";
1
+ import { Connection, Keypair, PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js";
2
2
  import { SVMDeriveChildPrivateKey } from "../walletBip32";
3
3
  import { VM } from "../vm";
4
4
  import { ChainWallet } from "../IChainWallet";
5
- import { Balance, ChainWalletConfig, UserTokenBalance, TokenInfo, TransactionResult } from "../types";
5
+ import { Balance, ChainWalletConfig, UserTokenBalance, TokenInfo, TransactionResult, NFT } from "../types";
6
6
  import {
7
7
  getSvmNativeBalance,
8
8
  getTokenBalance,
@@ -16,7 +16,10 @@ import {
16
16
  validateJupiterTokens,
17
17
  JupiterQuoteResponse,
18
18
  getTokenInfo,
19
- discoverTokens
19
+ discoverTokens,
20
+ signTransaction,
21
+ sendTransaction,
22
+ fetchWalletNfts
20
23
  } from "./utils";
21
24
  import BN from "bn.js";
22
25
  import nacl from "tweetnacl";
@@ -26,6 +29,7 @@ import { getSVMTransactionHistory, SVMTransactionHistoryItem } from "./transacti
26
29
 
27
30
  export class SVMVM extends VM<PublicKey, Keypair, Connection> {
28
31
  getTokenInfo = getTokenInfo
32
+ static getTokenInfo = getTokenInfo
29
33
  static validateAddress(address: PublicKey): boolean {
30
34
  try {
31
35
  new PublicKey(address)
@@ -54,6 +58,10 @@ export class SVMVM extends VM<PublicKey, Keypair, Connection> {
54
58
 
55
59
  static signAndSendTransaction = signAndSendTransaction
56
60
 
61
+ static signTransaction = signTransaction
62
+
63
+ static sendTransaction = sendTransaction
64
+
57
65
 
58
66
  generatePrivateKey(index: number, seed?: string, mnemonic?: string, derivationPath = this.derivationPath) {
59
67
  let _seed: string
@@ -91,6 +99,8 @@ export class SVMChainWallet extends ChainWallet<PublicKey, Keypair, Connection>
91
99
  return await SVMVM.getNativeBalance(this.address, this.connection!)
92
100
  }
93
101
 
102
+
103
+
94
104
  async getTokenBalance(tokenAddress: PublicKey): Promise<Balance> {
95
105
  // Implement token balance retrieval logic here
96
106
  return await SVMVM.getTokenBalance(this.address, (tokenAddress), this.connection!);
@@ -101,25 +111,47 @@ export class SVMChainWallet extends ChainWallet<PublicKey, Keypair, Connection>
101
111
  return tokens
102
112
  }
103
113
 
114
+ async discoverNFT(): Promise<NFT[]> {
115
+ // Implement NFT discovery logic here
116
+ const nfts = await fetchWalletNfts(this.address, this.connection!)
117
+ return nfts
118
+ }
119
+
104
120
  async transferNative(to: PublicKey, amount: number): Promise<TransactionResult> {
105
121
  // Implement native transfer logic here
106
122
  const transaction = await getTransferNativeTransaction(this.privateKey, to, amount, this.connection!)
107
- const hash = await SVMVM.signAndSendTransaction(transaction, this.connection!, [this.privateKey]);
123
+ const hash = await SVMVM.signAndSendTransaction(transaction, this.connection!, this.privateKey);
108
124
  return { success: true, hash } // Placeholder
109
125
  }
110
126
 
111
127
  async transferToken(token: TokenInfo, to: PublicKey, amount: number): Promise<TransactionResult> {
112
128
  // Implement token transfer logic here
113
129
  const transaction = await getTransferTokenTransaction(this.privateKey, new PublicKey(to), token, (amount), this.connection!);
114
- const hash = await SVMVM.signAndSendTransaction(transaction, this.connection!, [this.privateKey]);
130
+ const hash = await SVMVM.signAndSendTransaction(transaction, this.connection!, this.privateKey);
115
131
  return { success: true, hash }; // Placeholder
116
132
  }
117
133
 
134
+ async signTransaction(transaction: VersionedTransaction | Transaction) {
135
+ return await SVMVM.signTransaction(transaction, this.privateKey)
136
+ }
137
+
138
+ async sendTransaction(transaction: VersionedTransaction | Transaction) {
139
+ return await SVMVM.sendTransaction(transaction, this.connection!)
140
+ }
141
+
142
+ async signAndSendTransaction(transaction: VersionedTransaction | Transaction) {
143
+ return await SVMVM.signAndSendTransaction(transaction, this.connection!, this.privateKey);
144
+ }
145
+
118
146
  async getTransactionHistory(): Promise<SVMTransactionHistoryItem[]> {
119
147
  const history = await getSVMTransactionHistory(this.connection!, this.address);
120
148
  return history;
121
149
  }
122
150
 
151
+ async getTokenInfo(tokenAddress: PublicKey) {
152
+ return await SVMVM.getTokenInfo(tokenAddress, this.connection!)
153
+ }
154
+
123
155
  async swap(fromToken: TokenInfo, toToken: PublicKey, amount: number, slippage: number = 50): Promise<TransactionResult> {
124
156
  try {
125
157
  if (amount <= 0) {
@@ -235,9 +267,8 @@ export class SVMChainWallet extends ChainWallet<PublicKey, Keypair, Connection>
235
267
  };
236
268
  }
237
269
  }
238
- signMessage = (message: string, signer: Keypair) => {
239
- const messageBytes = new TextEncoder().encode(message);
240
- const signature = nacl.sign.detached(messageBytes, signer.secretKey);
241
- return base58.encode(signature);
270
+ signMessage = (message: Uint8Array<ArrayBuffer>,) => {
271
+ const signature = nacl.sign.detached(message, this.privateKey.secretKey);
272
+ return signature
242
273
  };
243
274
  }
@@ -1,11 +1,20 @@
1
1
  //we will write all the svm utils function here
2
2
 
3
3
  import { Account, createAssociatedTokenAccountIdempotentInstruction, createTransferCheckedInstruction, getAccount, getAssociatedTokenAddress, getAssociatedTokenAddressSync, getMint, Mint, NATIVE_MINT, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";
4
- import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
5
- import { ChainWalletConfig, UserTokenBalance, TokenInfo } from "../types";
4
+ import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
5
+ import { ChainWalletConfig, UserTokenBalance, TokenInfo, SolanaNFT, NFT } from "../types";
6
6
  import { transactionSenderAndConfirmationWaiter } from "./transactionSender";
7
7
  import { BN } from "bn.js";
8
- import { Metaplex } from "@metaplex-foundation/js";
8
+ import { generateSigner, percentAmount, publicKey } from '@metaplex-foundation/umi'
9
+ import {
10
+ createNft,
11
+ fetchDigitalAsset,
12
+ fetchAllDigitalAssetByOwner,
13
+ mplTokenMetadata,
14
+ } from '@metaplex-foundation/mpl-token-metadata'
15
+ import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
16
+
17
+ import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi-public-keys"
9
18
 
10
19
  const JUPITER_BASE_URL = 'https://lite-api.jup.ag';
11
20
 
@@ -271,15 +280,16 @@ export const getTransferNativeTransaction = async (from: Keypair, to: PublicKey,
271
280
  console.log('getTransferNativeTransaction: Completed');
272
281
  return transaction;
273
282
  }
274
- const getMetaTokenMetaplexData = (mintAddress: PublicKey, connection: Connection) => {
275
- const metaplex = Metaplex.make(connection);
276
- return metaplex.nfts().findByMint({ mintAddress: mintAddress });
283
+ const getMetaTokenMetaplexData = async (mintAddress: PublicKey, connection: Connection) => {
284
+ const umi = createUmi(connection.rpcEndpoint).use(mplTokenMetadata())
285
+ const ass = await fetchDigitalAsset(umi, mintAddress.toBase58() as unknown as UmiPublicKey)
286
+ return ass.metadata
287
+
277
288
  }
278
289
 
279
290
  export const getTokenInfo = async (tokenAddress: PublicKey, connection: Connection, programId?: PublicKey): Promise<TokenInfo> => {
280
291
  let mint: Mint
281
292
 
282
-
283
293
  const metaplexData = await getMetaTokenMetaplexData(tokenAddress, connection).catch(() => null);
284
294
  if (programId) {
285
295
  const mint = await getMint(connection, tokenAddress, "confirmed", programId)
@@ -347,17 +357,31 @@ export const getTransferTokenTransaction = async (from: Keypair, to: PublicKey,
347
357
  return transaction;
348
358
  }
349
359
 
350
- export const signAndSendTransaction = async (transaction: VersionedTransaction, connection: Connection, signers: Keypair[]) => {
351
- console.log('signAndSendTransaction: Starting');
352
- console.log('Signers count:', signers.length);
360
+ export const signTransaction = async (
361
+ transaction: VersionedTransaction | Transaction,
362
+ signers: Keypair,
363
+ ): Promise<VersionedTransaction | Transaction> => {
364
+
353
365
 
354
- transaction.sign(signers)
355
- console.log('Transaction signed');
366
+ if (transaction instanceof Transaction) {
367
+ transaction.partialSign(signers);
356
368
 
357
- const blockhash = await connection.getLatestBlockhash()
358
- console.log('Got latest blockhash:', blockhash.blockhash);
369
+ } else {
370
+ transaction.sign([signers]);
371
+
372
+ }
373
+
374
+ return transaction;
375
+ };
376
+
377
+ export const sendTransaction = async (
378
+ transaction: VersionedTransaction | Transaction,
379
+ connection: Connection
380
+ ): Promise<string> => {
381
+
382
+
383
+ const blockhash = await connection.getLatestBlockhash();
359
384
 
360
- console.log('Sending transaction...');
361
385
  const res = await transactionSenderAndConfirmationWaiter({
362
386
  connection,
363
387
  serializedTransaction: Buffer.from(transaction.serialize()),
@@ -375,7 +399,21 @@ export const signAndSendTransaction = async (transaction: VersionedTransaction,
375
399
  const signature = res.transaction.signatures[0];
376
400
  console.log('Transaction successful, signature:', signature);
377
401
  return signature;
378
- }
402
+ };
403
+
404
+ export const signAndSendTransaction = async (
405
+ transaction: VersionedTransaction | Transaction,
406
+ connection: Connection,
407
+ signers: Keypair,
408
+ options?: { partialSign?: boolean }
409
+ ): Promise<string> => {
410
+ console.log('signAndSendTransaction: Starting');
411
+
412
+ const signedTx = await signTransaction(transaction, signers);
413
+ const signature = await sendTransaction(signedTx, connection);
414
+
415
+ return signature;
416
+ };
379
417
  export const discoverTokens = async (ownerAddress: PublicKey, connection: Connection): Promise<UserTokenBalance<PublicKey>[]> => {
380
418
 
381
419
  const owner = new PublicKey(ownerAddress);
@@ -723,3 +761,80 @@ export const validateJupiterTokens = async (
723
761
  }
724
762
  };
725
763
 
764
+ export const transformSolanaNFTToUnified = (nft: SolanaNFT): NFT => {
765
+ return {
766
+ id: nft.mint,
767
+ name: nft.name,
768
+ symbol: nft.symbol,
769
+ description: '', // Will be populated from metadata URI if needed
770
+ image: undefined, // Will be populated from metadata URI if needed
771
+ uri: nft.uri,
772
+ collection: {
773
+ address: nft.mint,
774
+ name: nft.name,
775
+ verified: nft.creators?.some(c => c.verified) ?? false,
776
+ },
777
+ chainType: 'SVM',
778
+ balance: '1', // NFTs on Solana are typically quantity 1
779
+ creators: nft.creators,
780
+ sellerFeeBasisPoints: nft.sellerFeeBasisPoints,
781
+ tokenStandard: 'NonFungible',
782
+ raw: {
783
+ svm: nft
784
+ }
785
+ };
786
+ };
787
+
788
+ export const fetchWalletNfts = async (
789
+ walletAddress: PublicKey,
790
+ connection: Connection
791
+ ): Promise<NFT[]> => {
792
+ console.log('fetchWalletNfts: Starting');
793
+ console.log('Wallet address:', walletAddress.toString());
794
+
795
+ try {
796
+ // Create UMI instance with the connection's RPC endpoint
797
+ const umi = createUmi(connection.rpcEndpoint).use(mplTokenMetadata());
798
+ console.log('UMI instance created with RPC endpoint:', connection.rpcEndpoint);
799
+
800
+ // Convert Solana PublicKey to UMI PublicKey
801
+ const owner = publicKey(walletAddress.toString());
802
+ console.log('Fetching NFTs for owner:', owner);
803
+
804
+ // Fetch all digital assets owned by the wallet
805
+ const assets = await fetchAllDigitalAssetByOwner(umi, owner);
806
+ console.log('Fetched assets count:', assets.length);
807
+
808
+ // Transform the assets into our SolanaNFT format
809
+ const solanaNfts: SolanaNFT[] = assets.map((asset) => {
810
+ const metadata = asset.metadata;
811
+
812
+ return {
813
+ mint: asset.publicKey.toString(),
814
+ name: metadata.name,
815
+ symbol: metadata.symbol,
816
+ uri: metadata.uri,
817
+ updateAuthority: metadata.updateAuthority.toString(),
818
+ sellerFeeBasisPoints: metadata.sellerFeeBasisPoints,
819
+ creators: metadata.creators && 'value' in metadata.creators && metadata.creators.value
820
+ ? metadata.creators.value.map((creator) => ({
821
+ address: creator.address.toString(),
822
+ verified: creator.verified,
823
+ share: creator.share,
824
+ }))
825
+ : undefined,
826
+ };
827
+ });
828
+
829
+ // Transform to unified NFT format
830
+ const nfts = solanaNfts.map(transformSolanaNFTToUnified);
831
+
832
+ console.log('fetchWalletNfts: Successfully fetched', nfts.length, 'NFTs');
833
+ return nfts;
834
+ } catch (error) {
835
+ console.log('fetchWalletNfts: Error fetching NFTs:', error);
836
+ console.log('Error details:', error instanceof Error ? error.message : 'Unknown error');
837
+ throw error;
838
+ }
839
+ };
840
+
package/utils/test.ts CHANGED
@@ -8,11 +8,13 @@ import { Connection, PublicKey, Keypair } from "@solana/web3.js";
8
8
  import { SVMChainWallet, SVMVM, } from "./svm";
9
9
  import { VM } from "./vm";
10
10
  import { ChainWalletConfig } from "./types";
11
- import { EVMChainWallet } from "./evm";
11
+ import { discoverNFTs, EVMChainWallet } from "./evm";
12
12
  import { } from "./svm/transactionParsing";
13
13
  import { getEVMTransactionHistory } from "./evm/transactionParsing";
14
14
  import { createPublicClient, http, PublicClient } from "viem";
15
15
  import { base, baseGoerli } from "viem/chains";
16
+ import { fetchWalletNfts, getTokenInfo } from "./svm/utils";
17
+ import { JsonRpcProvider } from "ethers";
16
18
  // const mnemonic = GenerateNewMnemonic()
17
19
 
18
20
 
@@ -25,6 +27,7 @@ export const testUserKeyPair = Keypair.fromSecretKey(base58.decode(pKey));
25
27
  const x = testUserKeyPair instanceof Keypair;
26
28
  const evePrivateKey = "0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318"
27
29
  const evmPrivateKey2 = "0x0123456789012345678901234567890123456789012345678901234567890123"
30
+ const ogPrivKey = "d2d3f7117aa9a4c6e5d4affedd8a5ea624ffd82b2a1de81509e5913709b1ea72"
28
31
 
29
32
  // const vm = new SVMVM(seed)
30
33
 
@@ -37,7 +40,7 @@ const evmPrivateKey2 = "0x012345678901234567890123456789012345678901234567890123
37
40
  const chainConfig: ChainWalletConfig = {
38
41
  chainId: 123456789,
39
42
  name: "Solana",
40
- rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/vB5mKztdJeFdz9RkW99Qf",
43
+ rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/lhoyb3hc9ccT9NA_y2cfA",
41
44
  explorerUrl: "https://explorer.solana.com",
42
45
  nativeToken: { name: "Solana", symbol: "SOL", decimals: 9 },
43
46
  confirmationNo: 1,
@@ -47,17 +50,27 @@ const chainConfig: ChainWalletConfig = {
47
50
  const evmChainConfig: ChainWalletConfig = {
48
51
  chainId: 8453,
49
52
  name: "Ethereum",
50
- rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/vB5mKztdJeFdz9RkW99Qf",
53
+ rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/lhoyb3hc9ccT9NA_y2cfA",
51
54
  explorerUrl: "https://explorer.ethereum.com",
52
55
  nativeToken: { name: "Ethereum", symbol: "ETH", decimals: 18 },
53
56
  confirmationNo: 1,
54
57
  }
55
58
 
59
+ const OgChainConfig: ChainWalletConfig = {
60
+ chainId: 16661,
61
+ name: "",
62
+ rpcUrl: "https://evmrpc.0g.ai",
63
+ explorerUrl: "",
64
+ nativeToken: { name: "Ethereum", symbol: "ETH", decimals: 18 },
65
+
66
+ }
67
+
56
68
 
57
69
  // const wallet = new SVMChainWallet(chainConfig, testUserKeyPair, 0)
58
- const wallet = new EVMChainWallet(evmChainConfig, evmPrivateKey2, 0)
70
+ const wallet = new EVMChainWallet(OgChainConfig, ogPrivKey, 0)
71
+ wallet.getNativeBalance().then(console.log)
59
72
  // console.log('wallet: ', wallet);
60
-
73
+ // getTokenInfo(new PublicKey("9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump"), wallet.connection!).then(e => console.log('token info: ', e))
61
74
  // wallet.discoverToken().then(e => console.log('discovered tokens: ', e))
62
75
  // wallet.getNativeBalance().then(e => console.log('native balance: ', e))
63
76
  console.log('address: ', wallet.address);
@@ -81,6 +94,10 @@ console.log('address: ', wallet.address);
81
94
  const RPC_URL = chainConfig.rpcUrl;
82
95
  const connection = new Connection(RPC_URL);
83
96
 
97
+ // const evmConnection = new JsonRpcProvider(evmChainConfig.rpcUrl, {
98
+ // chainId: evmChainConfig.chainId
99
+ // });
100
+
84
101
  /**
85
102
  * Fetches and logs the token metadata for a given mint address.
86
103
  * @param mintAddress - The mint address of the token.
@@ -99,17 +116,30 @@ const connection = new Connection(RPC_URL);
99
116
  // }).catch((error: any) => {
100
117
  // console.error("Error fetching transaction history:", error);
101
118
  // });
102
- const client = createPublicClient({
103
- chain: base,
104
- transport: http(base.rpcUrls.default.http[0]),
105
- })
106
-
107
- getEVMTransactionHistory(client as PublicClient, "0x9C82CE0e125F61AdE50BC0c19638F6Ba93d71D5e", {
108
- startBlock: BigInt(37427020)
109
- // before: "0xabc..."
110
- }).then((history: any) => {
111
- console.log("EVM Transaction History:", history);
112
- }).catch((error: any) => {
113
- console.error("Error fetching EVM transaction history:", error);
114
- });
119
+ // const client = createPublicClient({
120
+ // chain: base,
121
+ // transport: http(base.rpcUrls.default.http[0]),
122
+ // })
123
+
124
+ // getEVMTransactionHistory(client as PublicClient, "0x9C82CE0e125F61AdE50BC0c19638F6Ba93d71D5e", {
125
+ // startBlock: BigInt(37427020)
126
+ // // before: "0xabc..."
127
+ // }).then((history: any) => {
128
+ // console.log("EVM Transaction History:", history);
129
+ // }).catch((error: any) => {
130
+ // console.error("Error fetching EVM transaction history:", error);
131
+ // });
132
+
133
+ // discoverNFTs("0x498581ff718922c3f8e6a244956af099b2652b2b", evmChainConfig).then(nfts => {
134
+ // console.log("Discovered NFTs:", nfts);
135
+ // }).catch(error => {
136
+ // console.error("Error discovering NFTs:", error);
137
+ // });
138
+
139
+ // fetchWalletNfts(new PublicKey("LebronkTYWjc5J1gtqntdMcbhBXgwRgYcCxMA8JMA17"), connection).then(nfts => {
140
+ // console.log("Discovered NFTs:", nfts);
141
+ // }).catch(error => {
142
+ // console.error("Error discovering NFTs:", error);
143
+ // });
144
+
115
145