pwc-sdk-wallet 0.7.7 → 0.7.8

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/README.md CHANGED
@@ -37,14 +37,20 @@ A comprehensive, secure, and user-friendly wallet SDK for React Native applicati
37
37
  - [Get Native Balance](#get-native-balance)
38
38
  - [Get Token Balance](#get-token-balance)
39
39
  - [Get Token Info](#get-token-info)
40
+ - [Get SPL Token Balance (Solana)](#get-spl-token-balance)
41
+ - [Get SPL Token Info (Solana)](#get-spl-token-info)
42
+ - [Estimate SPL Token Transfer Fee](#estimate-spl-token-transfer-fee)
43
+ - [Popular Solana SPL Tokens](#popular-solana-spl-tokens)
40
44
  - [Transaction Functions](#transaction-functions)
41
45
  - [Send Native Token](#send-native-token)
42
46
  - [Send Token](#send-token)
47
+ - [Send SPL Token (Solana)](#send-spl-token-solana)
43
48
  - [Export Mnemonic](#export-mnemonic)
44
49
 
45
50
  ### 🔄 Multi-Transfer Operations
46
51
  - [Batch Send Native Tokens](#batch-send-native-tokens)
47
52
  - [Batch Send ERC-20 Tokens](#batch-send-erc-20-tokens)
53
+ - [Multi-Transfer (Batch Send) - Simple Usage](#multi-transfer-batch-send---simple-usage)
48
54
 
49
55
  ### 📱 QR Code Functionality
50
56
  - [Generate Address QR](#generate-address-qr)
@@ -76,6 +82,9 @@ A comprehensive, secure, and user-friendly wallet SDK for React Native applicati
76
82
  - [React Native NFT Component Example](#react-native-nft-component-example)
77
83
  - [Get Owned NFTs](#get-owned-nfts)
78
84
  - [Transfer NFT](#transfer-nft)
85
+ - [Transfer Solana NFT](#transfer-solana-nft)
86
+ - [Get Solana NFT Balance](#get-solana-nft-balance)
87
+ - [Get Solana NFT Details](#get-solana-nft-details)
79
88
  - [Estimate NFT Transfer Gas](#estimate-nft-transfer-gas)
80
89
 
81
90
  ### ⛽ Advanced Features
@@ -122,7 +131,26 @@ A comprehensive, secure, and user-friendly wallet SDK for React Native applicati
122
131
  ### 🛠️ Development
123
132
  - [Contributing](#contributing)
124
133
 
134
+ ### 🔥 New API: Simple chainId-based usage
135
+ - [Simple chainId-based usage](#new-api-simple-chainid-based-usage)
136
+
137
+ ### 📱 QR Code Functionality
138
+ - [Generate Address QR](#generate-address-qr)
139
+ - [Generate Mnemonic QR](#generate-mnemonic-qr)
140
+ - [Generate Transaction QR](#generate-transaction-qr)
141
+ - [Import Wallet from QR](#import-wallet-from-qr)
142
+ - [Process Transaction from QR](#process-transaction-from-qr)
143
+ - [Validate QR Code](#validate-qr-code)
144
+ - [Generate EIP-681 Compatible Address QR](#generate-eip-681-compatible-address-qr-for-metamask-binance-trust-wallet)
145
+
125
146
  ### 🛠️ Advanced Transaction Utilities
147
+ - [Build Generic Transaction](#build-generic-transaction)
148
+ - [Sign Transaction (Vault)](#sign-transaction-recommended---using-vault)
149
+ - [Sign Transaction (Private Key)](#sign-transaction-deprecated---using-private-key)
150
+ - [Send Raw Transaction](#send-raw-transaction)
151
+ - [Approve Token (Vault)](#approve-token-recommended---using-vault)
152
+ - [Approve Token (Private Key)](#approve-token-deprecated---using-private-key)
153
+ - [Track Transaction Status](#track-transaction-status)
126
154
 
127
155
  ### Build Generic Transaction
128
156
  Builds an unsigned transaction for any contract method.
@@ -975,7 +1003,7 @@ The PWC Wallet SDK with direct provider injection provides **universal dApp comp
975
1003
 
976
1004
  #### ✅ **One Setup, Universal Access:**
977
1005
  ```typescript
978
- // Mobile dev chỉ cần setup 1 lần
1006
+ // Mobile developers only need to setup once
979
1007
  <DAppBrowser
980
1008
  vault={vault}
981
1009
  initialUrl="https://pancakeswap.finance/"
@@ -1194,7 +1222,7 @@ Transfers an NFT (ERC-721) from one address to another.
1194
1222
  - `tokenId` - Token ID to transfer (string)
1195
1223
 
1196
1224
  ```typescript
1197
- // Gửi NFT ERC-721 từ này sang khác
1225
+ // Send ERC-721 NFT from this wallet to another wallet
1198
1226
  const tx = await vault.transferNFT(
1199
1227
  '0xSenderAddress',
1200
1228
  '0xRecipientAddress',
@@ -1204,7 +1232,88 @@ const tx = await vault.transferNFT(
1204
1232
  console.log('NFT transfer tx hash:', tx.hash);
1205
1233
  ```
1206
1234
 
1207
- > **Note:** Hiện tại chỉ hỗ trợ EVM chains (Ethereum, BSC, v.v.). Solana NFT transfer chưa được hỗ trợ.
1235
+ > **Note:** Currently supports EVM chains (Ethereum, BSC, etc.) and Solana NFTs. Solana NFT transfers are now fully supported!
1236
+
1237
+ #### Transfer Solana NFT
1238
+ Transfers a Solana NFT from one address to another using the dedicated Solana NFT method.
1239
+
1240
+ **Parameters:**
1241
+ - `fromAddress` - Sender's address
1242
+ - `toAddress` - Recipient's address
1243
+ - `mintAddress` - The NFT mint address
1244
+ - `commitment` - Optional commitment level (default: 'confirmed')
1245
+
1246
+ ```typescript
1247
+ // Transfer a Solana NFT
1248
+ const tx = await vault.transferSolanaNFT(
1249
+ '0xYourAddress...',
1250
+ '0xRecipient...',
1251
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // NFT mint address
1252
+ );
1253
+ console.log('Solana NFT transfer hash:', tx.hash);
1254
+
1255
+ // With custom commitment level
1256
+ const txFast = await vault.transferSolanaNFT(
1257
+ '0xYourAddress...',
1258
+ '0xRecipient...',
1259
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
1260
+ 'processed' // Fastest confirmation
1261
+ );
1262
+ ```
1263
+
1264
+ #### Get Solana NFT Balance
1265
+ Gets Solana NFT balance for a specific address.
1266
+
1267
+ **Parameters:**
1268
+ - `address` - Wallet address to check balance for
1269
+ - `mintAddress` - The NFT mint address
1270
+ - `commitment` - Optional commitment level (default: 'confirmed')
1271
+
1272
+ ```typescript
1273
+ // Check if you own a specific Solana NFT
1274
+ const balance = await vault.getSolanaNFTBalance(
1275
+ '0xYourAddress...',
1276
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
1277
+ );
1278
+
1279
+ if (balance.count > 0) {
1280
+ console.log('You own this NFT!');
1281
+ } else {
1282
+ console.log('You do not own this NFT');
1283
+ }
1284
+ ```
1285
+
1286
+ #### Get Solana NFT Details
1287
+ Gets detailed Solana NFT information with metadata.
1288
+
1289
+ **Parameters:**
1290
+ - `mintAddress` - The NFT mint address
1291
+ - `options` - Query options for additional data
1292
+ - `commitment` - Optional commitment level (default: 'confirmed')
1293
+
1294
+ ```typescript
1295
+ // Get basic Solana NFT information
1296
+ const nftDetail = await vault.getSolanaNFTDetail(
1297
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
1298
+ );
1299
+ console.log('NFT Name:', nftDetail.name);
1300
+ console.log('Owner:', nftDetail.owner);
1301
+ console.log('Token Type:', nftDetail.tokenType); // 'SPL-NFT'
1302
+
1303
+ // Get extended information with metadata
1304
+ const nftDetailExtended = await vault.getSolanaNFTDetail(
1305
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
1306
+ {
1307
+ includeMetadata: true,
1308
+ includeHistory: true,
1309
+ includeCollection: true
1310
+ }
1311
+ );
1312
+ console.log('Description:', nftDetailExtended.description);
1313
+ console.log('Image URL:', nftDetailExtended.image);
1314
+ console.log('Attributes:', nftDetailExtended.attributes);
1315
+ console.log('Transaction History:', nftDetailExtended.transactionHistory);
1316
+ ```
1208
1317
 
1209
1318
  ---
1210
1319
 
@@ -1727,9 +1836,85 @@ console.log('Transaction hash:', tx.hash);
1727
1836
 
1728
1837
  #### Send Token
1729
1838
  ```typescript
1730
- // Send ERC-20 tokens
1839
+ // Send ERC-20 tokens on EVM chains
1731
1840
  const tx = await vault.sendToken(from, to, amount, tokenAddress, '1');
1732
1841
  console.log('Transaction hash:', tx.hash);
1842
+
1843
+ // Send SPL tokens on Solana
1844
+ const solanaTx = await vault.sendSPLToken(
1845
+ from,
1846
+ to,
1847
+ amount,
1848
+ tokenAddress // SPL token mint address
1849
+ );
1850
+ console.log('Solana transaction hash:', solanaTx.hash);
1851
+ ```
1852
+
1853
+ #### Send SPL Token (Solana)
1854
+ ```typescript
1855
+ // Send USDC on Solana
1856
+ const usdcTx = await vault.sendSPLToken(
1857
+ '0xYourAddress...',
1858
+ '0xRecipient...',
1859
+ '100', // 100 USDC
1860
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC mint address
1861
+ );
1862
+
1863
+ // Send USDT on Solana
1864
+ const usdtTx = await vault.sendSPLToken(
1865
+ '0xYourAddress...',
1866
+ '0xRecipient...',
1867
+ '50', // 50 USDT
1868
+ 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB' // USDT mint address
1869
+ );
1870
+
1871
+ // Get SPL token balance
1872
+ const usdcBalance = await vault.getSPLTokenBalance(
1873
+ '0xYourAddress...',
1874
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
1875
+ );
1876
+ console.log('USDC Balance:', usdcBalance.toString());
1877
+
1878
+ // Get SPL token information
1879
+ const tokenInfo = await vault.getSPLTokenInfo(
1880
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
1881
+ );
1882
+ console.log('Token:', tokenInfo.name, '(', tokenInfo.symbol, ')');
1883
+ console.log('Decimals:', tokenInfo.decimals);
1884
+
1885
+ // Estimate SPL token transfer fee
1886
+ const transferFee = await vault.estimateSPLTokenTransferFee(
1887
+ '0xYourAddress...',
1888
+ '0xRecipient...',
1889
+ 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
1890
+ );
1891
+ console.log('Estimated fee:', transferFee.toString(), 'lamports');
1892
+ ```
1893
+
1894
+ #### Popular Solana SPL Tokens
1895
+
1896
+ **Mainnet Token Addresses:**
1897
+ ```typescript
1898
+ // USDC (USD Coin)
1899
+ const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
1900
+
1901
+ // USDT (Tether)
1902
+ const USDT_MINT = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB';
1903
+
1904
+ // BONK (Bonk)
1905
+ const BONK_MINT = 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263';
1906
+
1907
+ // JUP (Jupiter)
1908
+ const JUP_MINT = 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN';
1909
+ ```
1910
+
1911
+ **Devnet Token Addresses (for testing):**
1912
+ ```typescript
1913
+ // USDC Devnet
1914
+ const USDC_DEVNET = '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU';
1915
+
1916
+ // USDT Devnet
1917
+ const USDT_DEVNET = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB';
1733
1918
  ```
1734
1919
 
1735
1920
  #### Export Mnemonic
@@ -1745,7 +1930,7 @@ console.log('Mnemonic:', mnemonic);
1745
1930
  ```typescript
1746
1931
  import { MultiTransferService } from 'pwc-wallet-sdk';
1747
1932
 
1748
- const multiTransferService = new MultiTransferService(vault, chainService, '1'); // '1' chainId cho Ethereum mainnet
1933
+ const multiTransferService = new MultiTransferService(vault, chainService, '1'); // '1' is chainId for Ethereum mainnet
1749
1934
  const recipients = [
1750
1935
  { address: '0x1111...', amount: '0.01' },
1751
1936
  { address: '0x2222...', amount: '0.02' },
@@ -2148,7 +2333,7 @@ const balance = await getTokenBalance('0xToken...', '0x123...', '1');
2148
2333
  ### Example: MultiTransfer
2149
2334
  ```ts
2150
2335
  import { MultiTransferService } from 'pwc-wallet-sdk';
2151
- const service = new MultiTransferService(vault, chainService, '1'); // truyền chainId rõ ràng
2336
+ const service = new MultiTransferService(vault, chainService, '1'); // pass chainId explicitly
2152
2337
  await service.transferNativeTokens('0x123...', [{ address: '0xabc...', amount: '0.1' }], '1');
2153
2338
  ```
2154
2339
 
package/dist/Vault.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type EncryptedData } from './crypto/EncryptionService';
2
2
  import { type ChainId } from './config/chains';
3
3
  import { Recipient, MultiTransferResult } from './types/multiTransfer';
4
- import { NFTDetailExtended, NFTOptions } from './types/nft';
4
+ import { NFTDetailExtended, NFTBalance, NFTOptions } from './types/nft';
5
5
  export interface Account {
6
6
  address: string;
7
7
  type: 'HD' | 'Simple' | 'Solana';
@@ -150,6 +150,96 @@ export declare class Vault {
150
150
  * @throws Error if insufficient balance, invalid addresses, or transaction fails
151
151
  */
152
152
  sendToken(fromAddress: string, to: string, amount: string, tokenAddress: string, chainId: ChainId): Promise<TransactionResponse>;
153
+ /**
154
+ * Sends SPL tokens on Solana blockchain with enhanced validation and error handling.
155
+ * This method is specifically designed for Solana SPL token transfers.
156
+ * @param fromAddress - The sender's account address
157
+ * @param to - The recipient's address
158
+ * @param amount - The amount of tokens to send as a string
159
+ * @param tokenAddress - The SPL token mint address
160
+ * @param commitment - Optional commitment level for the transaction (default: 'confirmed')
161
+ * @returns Promise resolving to the transaction response with hash and details
162
+ * @throws Error if insufficient balance, invalid addresses, or transaction fails
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * // Send USDC on Solana
167
+ * const tx = await vault.sendSPLToken(
168
+ * '0xYourAddress...',
169
+ * '0xRecipient...',
170
+ * '100', // 100 USDC
171
+ * 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC mint address
172
+ * );
173
+ * ```
174
+ */
175
+ sendSPLToken(fromAddress: string, to: string, amount: string, tokenAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<TransactionResponse>;
176
+ /**
177
+ * Gets SPL token balance for a specific address on Solana.
178
+ * @param address - The account address to check balance for
179
+ * @param tokenAddress - The SPL token mint address
180
+ * @param commitment - Optional commitment level (default: 'confirmed')
181
+ * @returns Promise resolving to the token balance as a bigint
182
+ * @throws Error if the balance query fails
183
+ */
184
+ getSPLTokenBalance(address: string, tokenAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<bigint>;
185
+ /**
186
+ * Gets SPL token information on Solana.
187
+ * @param tokenAddress - The SPL token mint address
188
+ * @param commitment - Optional commitment level (default: 'confirmed')
189
+ * @returns Promise resolving to token metadata
190
+ * @throws Error if the token info query fails
191
+ */
192
+ getSPLTokenInfo(tokenAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<Token>;
193
+ /**
194
+ * Estimates the transaction fee for SPL token transfers on Solana.
195
+ * @param fromAddress - The sender's account address
196
+ * @param to - The recipient's address
197
+ * @param tokenAddress - The SPL token mint address
198
+ * @param commitment - Optional commitment level (default: 'confirmed')
199
+ * @returns Promise resolving to the estimated fee as a bigint in lamports
200
+ * @throws Error if the fee estimation fails
201
+ */
202
+ estimateSPLTokenTransferFee(fromAddress: string, to: string, tokenAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<bigint>;
203
+ /**
204
+ * Transfers a Solana NFT from one address to another.
205
+ * This method is specifically designed for Solana NFT transfers.
206
+ * @param fromAddress - The sender's account address
207
+ * @param toAddress - The recipient's address
208
+ * @param mintAddress - The NFT mint address
209
+ * @param commitment - Optional commitment level for the transaction (default: 'confirmed')
210
+ * @returns Promise resolving to the transaction response with hash and details
211
+ * @throws Error if insufficient balance, invalid addresses, or transaction fails
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // Transfer a Solana NFT
216
+ * const tx = await vault.transferSolanaNFT(
217
+ * '0xYourAddress...',
218
+ * '0xRecipient...',
219
+ * 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // NFT mint address
220
+ * );
221
+ * console.log('NFT transfer hash:', tx.hash);
222
+ * ```
223
+ */
224
+ transferSolanaNFT(fromAddress: string, toAddress: string, mintAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<TransactionResponse>;
225
+ /**
226
+ * Gets Solana NFT balance for a specific address.
227
+ * @param address - Wallet address to check balance for
228
+ * @param mintAddress - The NFT mint address
229
+ * @param commitment - Optional commitment level (default: 'confirmed')
230
+ * @returns Promise resolving to the NFT balance
231
+ * @throws Error if the balance query fails
232
+ */
233
+ getSolanaNFTBalance(address: string, mintAddress: string, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<NFTBalance>;
234
+ /**
235
+ * Gets detailed Solana NFT information with metadata.
236
+ * @param mintAddress - The NFT mint address
237
+ * @param options - Query options for additional data
238
+ * @param commitment - Optional commitment level (default: 'confirmed')
239
+ * @returns Promise resolving to extended NFT detail
240
+ * @throws Error if the NFT query fails
241
+ */
242
+ getSolanaNFTDetail(mintAddress: string, options?: NFTOptions, commitment?: 'processed' | 'confirmed' | 'finalized'): Promise<NFTDetailExtended>;
153
243
  /**
154
244
  * Generates a vanity HD wallet with a specific address prefix.
155
245
  * Uses default configuration from VANITY_WALLET_CONFIG for optimal settings.
package/dist/Vault.js CHANGED
@@ -372,7 +372,12 @@ class Vault {
372
372
  const privateKey = await this.getPrivateKeyFor(fromAddress);
373
373
  if (chainInfo.type === 'solana') {
374
374
  const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo);
375
- const result = await chainService.sendToken(tokenAddress, to, amount);
375
+ // Use enhanced SPL token transfer with proper parameters
376
+ const result = await chainService.sendToken({
377
+ tokenAddress,
378
+ to,
379
+ amount
380
+ });
376
381
  return {
377
382
  hash: result.hash,
378
383
  from: result.from,
@@ -391,6 +396,191 @@ class Vault {
391
396
  };
392
397
  }
393
398
  }
399
+ /**
400
+ * Sends SPL tokens on Solana blockchain with enhanced validation and error handling.
401
+ * This method is specifically designed for Solana SPL token transfers.
402
+ * @param fromAddress - The sender's account address
403
+ * @param to - The recipient's address
404
+ * @param amount - The amount of tokens to send as a string
405
+ * @param tokenAddress - The SPL token mint address
406
+ * @param commitment - Optional commitment level for the transaction (default: 'confirmed')
407
+ * @returns Promise resolving to the transaction response with hash and details
408
+ * @throws Error if insufficient balance, invalid addresses, or transaction fails
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * // Send USDC on Solana
413
+ * const tx = await vault.sendSPLToken(
414
+ * '0xYourAddress...',
415
+ * '0xRecipient...',
416
+ * '100', // 100 USDC
417
+ * 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC mint address
418
+ * );
419
+ * ```
420
+ */
421
+ async sendSPLToken(fromAddress, to, amount, tokenAddress, commitment) {
422
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
423
+ if (chainInfo.type !== 'solana') {
424
+ throw new Error('Solana chain configuration not found');
425
+ }
426
+ const privateKey = await this.getPrivateKeyFor(fromAddress);
427
+ const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo, commitment);
428
+ const result = await chainService.sendToken({
429
+ tokenAddress,
430
+ to,
431
+ amount,
432
+ commitment
433
+ });
434
+ return {
435
+ hash: result.hash,
436
+ from: result.from,
437
+ to: result.to,
438
+ blockNumber: result.blockNumber
439
+ };
440
+ }
441
+ /**
442
+ * Gets SPL token balance for a specific address on Solana.
443
+ * @param address - The account address to check balance for
444
+ * @param tokenAddress - The SPL token mint address
445
+ * @param commitment - Optional commitment level (default: 'confirmed')
446
+ * @returns Promise resolving to the token balance as a bigint
447
+ * @throws Error if the balance query fails
448
+ */
449
+ async getSPLTokenBalance(address, tokenAddress, commitment) {
450
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
451
+ if (chainInfo.type !== 'solana') {
452
+ throw new Error('Solana chain configuration not found');
453
+ }
454
+ const privateKey = await this.getPrivateKeyFor(address);
455
+ const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo, commitment);
456
+ return await chainService.getTokenBalance(tokenAddress);
457
+ }
458
+ /**
459
+ * Gets SPL token information on Solana.
460
+ * @param tokenAddress - The SPL token mint address
461
+ * @param commitment - Optional commitment level (default: 'confirmed')
462
+ * @returns Promise resolving to token metadata
463
+ * @throws Error if the token info query fails
464
+ */
465
+ async getSPLTokenInfo(tokenAddress, commitment) {
466
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
467
+ if (chainInfo.type !== 'solana') {
468
+ throw new Error('Solana chain configuration not found');
469
+ }
470
+ // Use a dummy private key for read-only operations
471
+ const dummyPrivateKey = '0000000000000000000000000000000000000000000000000000000000000000';
472
+ const chainService = new SolanaChainService_1.SolanaChainService(dummyPrivateKey, chainInfo, commitment);
473
+ const solanaToken = await chainService.getTokenInfo(tokenAddress);
474
+ return {
475
+ address: solanaToken.address,
476
+ name: solanaToken.name,
477
+ symbol: solanaToken.symbol,
478
+ decimals: solanaToken.decimals,
479
+ totalSupply: solanaToken.totalSupply
480
+ };
481
+ }
482
+ /**
483
+ * Estimates the transaction fee for SPL token transfers on Solana.
484
+ * @param fromAddress - The sender's account address
485
+ * @param to - The recipient's address
486
+ * @param tokenAddress - The SPL token mint address
487
+ * @param commitment - Optional commitment level (default: 'confirmed')
488
+ * @returns Promise resolving to the estimated fee as a bigint in lamports
489
+ * @throws Error if the fee estimation fails
490
+ */
491
+ async estimateSPLTokenTransferFee(fromAddress, to, tokenAddress, commitment) {
492
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
493
+ if (chainInfo.type !== 'solana') {
494
+ throw new Error('Solana chain configuration not found');
495
+ }
496
+ const privateKey = await this.getPrivateKeyFor(fromAddress);
497
+ const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo, commitment);
498
+ return await chainService.estimateSPLTokenTransferFee(tokenAddress, to);
499
+ }
500
+ /**
501
+ * Transfers a Solana NFT from one address to another.
502
+ * This method is specifically designed for Solana NFT transfers.
503
+ * @param fromAddress - The sender's account address
504
+ * @param toAddress - The recipient's address
505
+ * @param mintAddress - The NFT mint address
506
+ * @param commitment - Optional commitment level for the transaction (default: 'confirmed')
507
+ * @returns Promise resolving to the transaction response with hash and details
508
+ * @throws Error if insufficient balance, invalid addresses, or transaction fails
509
+ *
510
+ * @example
511
+ * ```typescript
512
+ * // Transfer a Solana NFT
513
+ * const tx = await vault.transferSolanaNFT(
514
+ * '0xYourAddress...',
515
+ * '0xRecipient...',
516
+ * 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // NFT mint address
517
+ * );
518
+ * console.log('NFT transfer hash:', tx.hash);
519
+ * ```
520
+ */
521
+ async transferSolanaNFT(fromAddress, toAddress, mintAddress, commitment) {
522
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
523
+ if (chainInfo.type !== 'solana') {
524
+ throw new Error('Solana chain configuration not found');
525
+ }
526
+ const privateKey = await this.getPrivateKeyFor(fromAddress);
527
+ const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo, commitment);
528
+ try {
529
+ // Get the NFT balance to verify ownership
530
+ const nftService = new NFTService_1.NFTService('solana', this, fromAddress);
531
+ const balance = await nftService.getSolanaNFTBalance(fromAddress, mintAddress);
532
+ if (balance.count === 0) {
533
+ throw new Error('NFT is not owned by the specified address');
534
+ }
535
+ // Transfer the NFT using SPL token transfer
536
+ const result = await chainService.sendToken({
537
+ tokenAddress: mintAddress,
538
+ to: toAddress,
539
+ amount: '1' // NFTs always have amount 1
540
+ });
541
+ return {
542
+ hash: result.hash,
543
+ from: result.from,
544
+ to: result.to,
545
+ blockNumber: result.blockNumber
546
+ };
547
+ }
548
+ catch (error) {
549
+ throw new Error(`Solana NFT transfer failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
550
+ }
551
+ }
552
+ /**
553
+ * Gets Solana NFT balance for a specific address.
554
+ * @param address - Wallet address to check balance for
555
+ * @param mintAddress - The NFT mint address
556
+ * @param commitment - Optional commitment level (default: 'confirmed')
557
+ * @returns Promise resolving to the NFT balance
558
+ * @throws Error if the balance query fails
559
+ */
560
+ async getSolanaNFTBalance(address, mintAddress, commitment) {
561
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
562
+ if (chainInfo.type !== 'solana') {
563
+ throw new Error('Solana chain configuration not found');
564
+ }
565
+ const nftService = new NFTService_1.NFTService('solana', this, address);
566
+ return await nftService.getSolanaNFTBalance(address, mintAddress);
567
+ }
568
+ /**
569
+ * Gets detailed Solana NFT information with metadata.
570
+ * @param mintAddress - The NFT mint address
571
+ * @param options - Query options for additional data
572
+ * @param commitment - Optional commitment level (default: 'confirmed')
573
+ * @returns Promise resolving to extended NFT detail
574
+ * @throws Error if the NFT query fails
575
+ */
576
+ async getSolanaNFTDetail(mintAddress, options = {}, commitment) {
577
+ const chainInfo = (0, chains_1.getChainConfig)('solana');
578
+ if (chainInfo.type !== 'solana') {
579
+ throw new Error('Solana chain configuration not found');
580
+ }
581
+ const nftService = new NFTService_1.NFTService('solana', this, 'dummy'); // Address not needed for read-only operations
582
+ return await nftService.getSolanaNFTDetail(mintAddress, options);
583
+ }
394
584
  /**
395
585
  * Generates a vanity HD wallet with a specific address prefix.
396
586
  * Uses default configuration from VANITY_WALLET_CONFIG for optimal settings.
@@ -937,8 +1127,31 @@ class Vault {
937
1127
  const privateKey = await this.getPrivateKeyFor(fromAddress);
938
1128
  if (chainInfo.type === 'solana') {
939
1129
  const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo);
940
- // Solana NFT transfer implementation would go here
941
- throw new Error('Solana NFT transfer not yet implemented');
1130
+ // Solana NFT transfer implementation
1131
+ const mintAddress = contractAddress; // For Solana, contractAddress is the mint address
1132
+ try {
1133
+ // Get the NFT balance to verify ownership
1134
+ const nftService = new NFTService_1.NFTService(this.chainId, this, fromAddress);
1135
+ const balance = await nftService.getSolanaNFTBalance(fromAddress, mintAddress);
1136
+ if (balance.count === 0) {
1137
+ throw new Error('NFT is not owned by the specified address');
1138
+ }
1139
+ // Transfer the NFT using SPL token transfer
1140
+ const result = await chainService.sendToken({
1141
+ tokenAddress: mintAddress,
1142
+ to: toAddress,
1143
+ amount: '1' // NFTs always have amount 1
1144
+ });
1145
+ return {
1146
+ hash: result.hash,
1147
+ from: result.from,
1148
+ to: result.to,
1149
+ blockNumber: result.blockNumber
1150
+ };
1151
+ }
1152
+ catch (error) {
1153
+ throw new Error(`Solana NFT transfer failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
1154
+ }
942
1155
  }
943
1156
  else {
944
1157
  const chainService = new ChainService_1.ChainService(privateKey, chainInfo);