Package Exports
- p-sdk-wallet
- p-sdk-wallet/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (p-sdk-wallet) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
PWC Wallet SDK
A comprehensive, secure, and user-friendly wallet SDK for React Native applications. This SDK provides a complete solution for managing cryptocurrency wallets with support for multiple blockchains, HD wallet generation, vanity addresses, NFT support, and advanced features like multi-transfer operations.
๐ Table of Contents
๐ Quick Start
๐ฑ React Native Usage
โ๏ธ Configuration
๐ฐ Core Wallet Functions
๐ Multi-Transfer Operations
๐ฑ QR Code Functionality
- Generate Address QR
- Generate Mnemonic QR
- Generate Transaction QR
- Import Wallet from QR
- Process Transaction from QR
- Validate QR Code
- Generate EIP-681 Compatible Address QR (for Metamask, Binance, Trust Wallet)
๐ผ๏ธ NFT Functionality
- Get NFT Details
- Get NFT Balance
- Get Collection Information
- NFT Metadata & Attributes
- NFT Transaction History
- NFT Types and Interfaces
- React Native NFT Component Example
- Get Owned NFTs
- Transfer NFT
โฝ Advanced Features
๐ ๏ธ Advanced Transaction Utilities
- Build Generic Transaction
- Sign Transaction
- Send Raw Transaction
- Approve Token (Public Utility)
- Track Transaction Status
๐ Read-Only Utilities (Token & NFT)
- Get Token Balance
- Get Token Info
- Get Native Balance
- Check Allowance
- Get NFT Details
- Get NFT Balance
- Get Owned NFTs
๐ Security & Error Handling
๐ ๏ธ Development
๐ ๏ธ Advanced Transaction Utilities
Build Generic Transaction
Builds an unsigned transaction for any contract method.
Parameters:
contractAddress- The contract address to interact withabi- The contract ABI arraymethod- The method name to callargs- Arguments to pass to the method (optional)value- Native token value to send (optional)chainId- The chain ID (e.g., '1' for Ethereum, '56' for BSC)
import { buildTransaction } from 'pwc-wallet-sdk/services/TokenUtils';
const unsignedTx = await buildTransaction({
contractAddress: '0xA0b86a33E6441b8c4C8C8C8C8C8C8C8C8C8C8C8', // USDT contract
abi: [
"function transfer(address to, uint256 amount) returns (bool)",
"function balanceOf(address account) view returns (uint256)"
],
method: 'transfer',
args: ['0xRecipientAddress...', '1000000000'], // to address, amount (in smallest unit)
chainId: '1' // Ethereum mainnet
});Sign Transaction (RECOMMENDED - Using Vault)
Signs an unsigned transaction using Vault for better security.
Parameters:
unsignedTx- The unsigned transaction object from buildTransactionvault- The vault instance containing the accountfromAddress- The sender's addresschainId- The chain ID
import { signTransactionWithVault } from 'pwc-wallet-sdk/services/TokenUtils';
const signedTx = await signTransactionWithVault(unsignedTx, vault, '0xYourAddress', '1');Sign Transaction (DEPRECATED - Using Private Key)
โ ๏ธ DEPRECATED: Use signTransactionWithVault instead for better security.
Parameters:
unsignedTx- The unsigned transaction object from buildTransactionprivateKey- The private key to sign with (without 0x prefix)chainId- The chain ID
import { signTransaction } from 'pwc-wallet-sdk/services/TokenUtils';
const privateKey = 'your-private-key-without-0x-prefix';
const signedTx = await signTransaction(unsignedTx, privateKey, '1');Send Raw Transaction
Broadcasts a signed transaction to the network.
Parameters:
signedTx- The signed transaction as hex stringchainId- The chain ID
import { sendTransaction } from 'pwc-wallet-sdk/services/TokenUtils';
const txResponse = await sendTransaction(signedTx, '1');
console.log('Transaction hash:', txResponse.hash);
console.log('Block number:', txResponse.blockNumber);Approve Token (RECOMMENDED - Using Vault)
Approves a spender to spend tokens using Vault for better security.
Parameters:
vault- The vault instance containing the owner's accountfromAddress- The owner's addresstokenAddress- The ERC-20 token contract addressspender- The spender's address (e.g., DEX contract address)amount- The amount to approve (string or bigint)chainId- The chain ID
import { approveTokenWithVault } from 'pwc-wallet-sdk/services/TokenUtils';
const receipt = await approveTokenWithVault(
vault,
'0xOwner...',
'0xToken...',
'0xSpender...',
'1000',
'1'
);Approve Token (DEPRECATED - Using Private Key)
โ ๏ธ DEPRECATED: Use approveTokenWithVault instead for better security.
Parameters:
privateKey- The owner's private key (without 0x prefix)tokenAddress- The ERC-20 token contract addressspender- The spender's address (e.g., DEX contract address)amount- The amount to approve (string or bigint)chainId- The chain ID
import { approveToken } from 'pwc-wallet-sdk/services/TokenUtils';
const receipt = await approveToken('privateKey...', '0xToken...', '0xSpender...', '1000', '1');Track Transaction Status
Tracks the status of a transaction with polling and callback notifications.
Parameters:
txHash- The transaction hash to trackchainId- The chain IDcallback- Function called with status updates ('pending', 'confirmed', 'failed')pollInterval- Polling interval in milliseconds (optional, default: 3000)
import { trackTxStatus } from 'pwc-wallet-sdk/services/TokenUtils';
trackTxStatus('0xTransactionHash...', '1', (status, receipt) => {
switch (status) {
case 'pending':
console.log('Transaction is pending...');
break;
case 'confirmed':
console.log('Transaction confirmed!', receipt?.transactionHash);
break;
case 'failed':
console.log('Transaction failed!', receipt?.transactionHash);
break;
}
}, 5000); // Poll every 5 seconds๐ Read-Only Utilities (Token & NFT)
Get Token Balance
Gets the token balance for a specific account.
Parameters:
tokenAddress- The ERC-20 token contract addressaccount- The account address to check balance forchainId- The chain ID
import { getTokenBalance } from 'pwc-wallet-sdk/services/TokenUtils';
const balance = await getTokenBalance(
'0xA0b86a33E6441b8c4C8C8C8C8C8C8C8C8C8C8C8', // USDT contract
'0xYourWalletAddress...',
'1' // Ethereum mainnet
);
console.log('USDT Balance:', ethers.formatUnits(balance, 6)); // USDT has 6 decimalsGet Token Info
Gets comprehensive information about an ERC-20 token.
Parameters:
tokenAddress- The ERC-20 token contract addresschainId- The chain ID
import { getTokenInfo } from 'pwc-wallet-sdk/services/TokenUtils';
const info = await getTokenInfo(
'0xA0b86a33E6441b8c4C8C8C8C8C8C8C8C8C8C8C8', // USDT contract
'1' // Ethereum mainnet
);
console.log('Token:', info.name, '(', info.symbol, ')');
console.log('Decimals:', info.decimals);
console.log('Total Supply:', ethers.formatUnits(info.totalSupply, info.decimals));Get Native Balance
Gets the native token balance (ETH, BNB, MATIC, etc.) for an account.
Parameters:
account- The account address to check balance forchainId- The chain ID
import { getNativeBalance } from 'pwc-wallet-sdk/services/TokenUtils';
const balance = await getNativeBalance('0xYourWalletAddress...', '1');
console.log('ETH Balance:', ethers.formatEther(balance));
// For BSC
const bnbBalance = await getNativeBalance('0xYourWalletAddress...', '56');
console.log('BNB Balance:', ethers.formatEther(bnbBalance));Check Allowance
Checks the allowance granted by an owner to a spender for a specific token.
Parameters:
tokenAddress- The ERC-20 token contract addressowner- The token owner's addressspender- The spender's address (e.g., DEX contract address)chainId- The chain ID
import { checkAllowance } from 'pwc-wallet-sdk/services/TokenUtils';
const allowance = await checkAllowance(
'0xA0b86a33E6441b8c4C8C8C8C8C8C8C8C8C8C8C8', // USDT contract
'0xYourWalletAddress...', // Owner
'0xDexContractAddress...', // Spender (DEX)
'1' // Ethereum mainnet
);
console.log('Allowance:', ethers.formatUnits(allowance, 6)); // USDT has 6 decimalsGet NFT Details
Gets comprehensive NFT detail by reading directly from blockchain.
Parameters:
contractAddress- NFT contract addresstokenId- Token ID (string)options- Optional parameters for additional dataincludeMetadata- Whether to fetch metadata (default: false)includeHistory- Whether to fetch transaction history (default: false)includeCollection- Whether to fetch collection info (default: false)
import { NFTService } from 'pwc-wallet-sdk';
const nftService = new NFTService('1'); // chainId = '1' for Ethereum (read-only)
const nftDetail = await nftService.getNFTDetail(
'0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', // BAYC contract
'1234', // Token ID
{
includeMetadata: true,
includeHistory: true,
includeCollection: true
}
);
console.log('NFT Name:', nftDetail.name);
console.log('Owner:', nftDetail.owner);
console.log('Image URL:', nftDetail.image);
console.log('Attributes:', nftDetail.attributes);Get NFT Balance
Gets NFT balance for an address from a specific contract.
Parameters:
address- Wallet address to check balance forcontractAddress- NFT contract address
const nftBalance = await nftService.getNFTBalance(
'0xYourWalletAddress...',
'0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D' // BAYC contract
);
console.log('NFT Count:', nftBalance.count);
console.log('Token IDs:', nftBalance.tokenIds);Get Collection Information
Gets collection information directly from the NFT contract.
Parameters:
contractAddress- NFT contract address
const collection = await nftService.getCollectionInfo('0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D');
console.log('Collection Name:', collection.name);
console.log('Total Supply:', collection.totalSupply);
console.log('Token Type:', collection.tokenType);NFT Metadata & Attributes
NFT metadata is automatically resolved from tokenURI (IPFS or HTTP).
import { NFTDetail, NFTDetailExtended, NFTCollection, NFTOptions } from 'pwc-wallet-sdk';
// Basic NFT information (on-chain data)
interface NFTDetail {
contractAddress: string;
tokenId: string;
name: string;
owner: string;
tokenType: 'ERC-721' | 'ERC-1155' | 'SPL-NFT';
chainId: string;
tokenUri?: string;
createdAt?: number;
lastTransferAt?: number;
}
// Extended NFT information with metadata
interface NFTDetailExtended extends NFTDetail {
description?: string;
image?: string;
attributes?: Array<{ trait_type: string; value: string; display_type?: string }>;
metadata?: NFTMetadata;
collection?: NFTCollection;
transactionHistory?: NFTTransaction[];
metadataSource?: 'ipfs' | 'http';
lastUpdated: number;
}
// Collection information
interface NFTCollection {
contractAddress: string;
name: string;
symbol: string;
tokenType: string;
chainId: string;
totalSupply?: number;
}NFT Transaction History
Gets transaction history from blockchain events.
Parameters:
contractAddress- NFT contract addresstokenId- Token ID (string)
const history = await nftService.getTransactionHistory(
'0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', // NFT contract
'1234' // Token ID
);
console.log('Transaction History:', history);
// Returns array of: { hash, from, to, blockNumber, timestamp, type }NFT Types and Interfaces
Complete TypeScript interfaces for NFT functionality.
import {
NFTDetail,
NFTDetailExtended,
NFTCollection,
NFTOptions,
NFTMetadata,
NFTTransaction,
NFTBalance
} from 'pwc-wallet-sdk';
// Basic NFT information (on-chain data)
interface NFTDetail {
contractAddress: string;
tokenId: string;
name: string;
owner: string;
tokenType: 'ERC-721' | 'ERC-1155' | 'SPL-NFT';
chainId: string;
tokenUri?: string;
createdAt?: number;
lastTransferAt?: number;
}
// Extended NFT information with metadata
interface NFTDetailExtended extends NFTDetail {
description?: string;
image?: string;
attributes?: Array<{ trait_type: string; value: string; display_type?: string }>;
metadata?: NFTMetadata;
collection?: NFTCollection;
transactionHistory?: NFTTransaction[];
metadataSource?: 'ipfs' | 'http';
lastUpdated: number;
}
// NFT metadata from tokenURI
interface NFTMetadata {
name: string;
description?: string;
image?: string;
attributes?: Array<{ trait_type: string; value: string; display_type?: string }>;
external_url?: string;
animation_url?: string;
}
// Collection information
interface NFTCollection {
contractAddress: string;
name: string;
symbol: string;
tokenType: string;
chainId: string;
totalSupply?: number;
}
// NFT transaction history
interface NFTTransaction {
hash: string;
from: string;
to: string;
blockNumber: number;
timestamp: number;
type: 'mint' | 'transfer';
}
// NFT balance information
interface NFTBalance {
contractAddress: string;
tokenIds: string[];
count: number;
tokenType: string;
chainId: string;
}
// NFT options for queries
interface NFTOptions {
includeMetadata?: boolean;
includeHistory?: boolean;
includeCollection?: boolean;
}React Native NFT Component Example
import React, { useState, useEffect } from 'react';
import { View, Text, Image, ScrollView } from 'react-native';
import { NFTService, NFTDetailExtended } from 'pwc-wallet-sdk';
const NFTDetailView = ({ contractAddress, tokenId, chainId }) => {
const [nft, setNft] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
loadNFTDetail();
}, [contractAddress, tokenId]);
const loadNFTDetail = async () => {
try {
setLoading(true);
setError(null);
const nftService = new NFTService(chainId); // Read-only operations
const nftDetail = await nftService.getNFTDetail(
contractAddress,
tokenId,
{ includeMetadata: true, includeHistory: true }
);
setNft(nftDetail);
} catch (err) {
setError(err.message);
console.error('Failed to load NFT:', err);
} finally {
setLoading(false);
}
};
if (loading) {
return <Text>Loading NFT...</Text>;
}
if (error) {
return <Text>Error: {error}</Text>;
}
if (!nft) {
return <Text>NFT not found</Text>;
}
return (
<ScrollView style={{ padding: 20 }}>
{nft.image && (
<Image
source={{ uri: nft.image }}
style={{ width: 300, height: 300, alignSelf: 'center' }}
resizeMode="cover"
/>
)}
<Text style={{ fontSize: 24, fontWeight: 'bold', marginTop: 10 }}>
{nft.name}
</Text>
{nft.description && (
<Text style={{ marginTop: 5 }}>{nft.description}</Text>
)}
<Text style={{ marginTop: 10 }}>
Contract: {nft.contractAddress}
</Text>
<Text>Token ID: {nft.tokenId}</Text>
<Text>Owner: {nft.owner}</Text>
<Text>Type: {nft.tokenType}</Text>
{nft.attributes && nft.attributes.length > 0 && (
<View style={{ marginTop: 15 }}>
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>Attributes:</Text>
{nft.attributes.map((attr, index) => (
<Text key={index}>
{attr.trait_type}: {attr.value}
</Text>
))}
</View>
)}
</ScrollView>
);
};Get Owned NFTs
Gets all NFTs owned by an address from multiple contracts.
Parameters:
account- Wallet address to checkcontractAddresses- Array of NFT contract addressesoptions- Optional parameters (same as getNFTDetail)
const nfts = await nftService.getOwnedNFTs(
'0xYourWalletAddress...',
['0xContract1...', '0xContract2...'],
{ includeMetadata: true }
);
console.log('Total NFTs:', nfts.length);
nfts.forEach(nft => {
console.log(`${nft.name} (${nft.contractAddress})`);
});Transfer NFT
Transfers an NFT (ERC-721) from one address to another.
Parameters:
fromAddress- Sender's addresstoAddress- Recipient's addresscontractAddress- NFT contract address (ERC-721)tokenId- Token ID to transfer (string)
// Gแปญi NFT ERC-721 tแปซ vรญ nร y sang vรญ khรกc
const tx = await vault.transferNFT(
'0xSenderAddress',
'0xRecipientAddress',
'0xNFTContractAddress',
'1234' // Token ID
);
console.log('NFT transfer tx hash:', tx.hash);Note: Hiแปn tแบกi chแป hแป trแปฃ EVM chains (Ethereum, BSC, v.v.). Solana NFT transfer chฦฐa ฤฦฐแปฃc hแป trแปฃ.
NFT Transfer (ERC-721 & ERC-1155)
Initialize NFTService for Transfer Operations
For transfer operations, you need to initialize NFTService with vault and sender address:
import { NFTService, Vault } from 'pwc-wallet-sdk';
// Initialize for read-only operations
const nftService = new NFTService('1'); // chainId = '1' for Ethereum
// Initialize for write operations (transfer)
const nftService = new NFTService('1', vault, fromAddress);Transfer NFT (RECOMMENDED - Using Vault)
The transferNFTWithVault function supports transferring both ERC-721 and ERC-1155 NFTs.
Parameters:
vault- The Vault instance containing the sender's accountfromAddress- The sender's wallet addresstoAddress- The recipient's wallet addresscontractAddress- The NFT contract addresstokenId- The token ID to transferamount(optional, default "1") - The amount to transfer (required for ERC-1155, default 1 for ERC-721)
Usage:
// Initialize NFTService for transfer operations
const nftService = new NFTService('1', vault, fromAddress);
// ERC-721: only basic parameters are required
await nftService.transferNFTWithVault(
fromAddress,
toAddress,
contractAddress,
tokenId
);
// ERC-1155: specify the amount (number of NFTs to transfer)
await nftService.transferNFTWithVault(
fromAddress,
toAddress,
contractAddress,
tokenId,
"5" // transfer 5 ERC-1155 NFTs
);- The function will automatically detect the contract type (ERC-721 or ERC-1155) and call the correct transfer method.
- If the contract is ERC-721,
amountwill default to 1. - If the contract is ERC-1155,
amountis the number of NFTs to transfer.
Deprecated: transferNFT
The transferNFT function (without vault) also supports both standards, but is not recommended for production.
Features
- ๐ Secure HD Wallet Management: BIP-44 compliant hierarchical deterministic wallets
- ๐ฏ Vanity Address Generation: Generate wallets with custom address prefixes
- ๐ Multi-Chain Support: Ethereum, BSC, Polygon, Arbitrum, Optimism, Base, and Solana
- ๐ Multi-Transfer Operations: Batch send tokens to multiple recipients
- ๐ง Custom Chain Support: Add custom chains and override built-in configurations
- ๐ฑ React Native Optimized: Designed specifically for mobile applications
- ๐ Encryption: AES-256 encryption for secure vault storage
- ๐จ TypeScript: Full TypeScript support with comprehensive type definitions
- ๐ผ๏ธ NFT Support: Core NFT functionality for individual tokens and collections
Installation
npm install pwc-wallet-sdkQuick Start
1. Basic Wallet Creation
import { Vault } from 'pwc-wallet-sdk';
// Create a new wallet
const { vault, encryptedVault } = await Vault.createNew('your-secure-password');
// Get wallet accounts
const accounts = vault.getAccounts();
console.log('Wallet addresses:', accounts.map(acc => acc.address));2. Vanity Wallet Generation
// Generate wallet with custom address prefix
const { vault, encryptedVault, attempts, foundAddress } =
await Vault.generateVanityHDWallet('your-password', (attempts, currentAddress) => {
console.log(`Attempt ${attempts}: ${currentAddress}`);
});
console.log(`Found address with prefix after ${attempts} attempts: ${foundAddress}`);3. Custom Chain Configuration
import { setupChainConfigs, registerCustomChain, overrideChain } from 'pwc-wallet-sdk';
// Setup custom chains and overrides (call once when app starts)
setupChainConfigs({
// Override built-in chains
overrides: {
'1': { rpcUrl: 'https://my-eth-rpc.com' }, // Use custom Ethereum RPC
'56': { rpcUrl: 'https://my-bsc-rpc.com' }, // Use custom BSC RPC
},
// Add custom chains
customChains: {
'custom-1': {
name: 'My Custom Chain',
rpcUrl: 'https://my-custom-rpc.com',
explorerUrl: 'https://my-explorer.com',
nativeCurrency: { name: 'Token', symbol: 'TKN', decimals: 18 },
type: 'evm'
},
'custom-solana': {
name: 'My Solana Chain',
rpcUrl: 'https://my-solana-rpc.com',
explorerUrl: 'https://my-solana-explorer.com',
nativeCurrency: { name: 'SOL', symbol: 'SOL', decimals: 9 },
type: 'solana'
}
}
});
// Load vault
const vault = await Vault.load(password, encryptedVault);
// Use custom chains normally
await vault.sendToken(from, to, amount, tokenAddress, 'custom-1');
await vault.getNativeBalance(address, 'custom-solana');React Native Usage
Simple Wallet Component
import React, { useState, useEffect } from 'react';
import { Vault, setupChainConfigs } from 'pwc-wallet-sdk';
const WalletComponent = () => {
const [vault, setVault] = useState(null);
const [balance, setBalance] = useState('0');
useEffect(() => {
// Setup custom chains when component mounts
setupChainConfigs({
overrides: {
'1': { rpcUrl: 'https://my-eth-rpc.com' }
},
customChains: {
'custom-1': {
name: 'My Chain',
rpcUrl: 'https://my-rpc.com',
type: 'evm'
}
}
});
loadWallet();
}, []);
const loadWallet = async () => {
try {
const loadedVault = await Vault.load(password, encryptedVault);
setVault(loadedVault);
// Get balance using custom chain
const balance = await loadedVault.getNativeBalance(address, 'custom-1');
setBalance(ethers.formatEther(balance));
} catch (error) {
console.error('Failed to load wallet:', error);
}
};
const sendTransaction = async () => {
if (!vault) return;
try {
// Send using custom chain
const tx = await vault.sendToken(from, to, amount, tokenAddress, 'custom-1');
console.log('Transaction sent:', tx.hash);
} catch (error) {
console.error('Transaction failed:', error);
}
};
return (
<View>
<Text>Balance: {balance}</Text>
<Button title="Send Transaction" onPress={sendTransaction} />
</View>
);
};Custom Hook for Wallet Management
import { useState, useEffect } from 'react';
import { Vault, setupChainConfigs } from 'pwc-wallet-sdk';
export const useWallet = (password: string, encryptedVault: EncryptedData) => {
const [vault, setVault] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
initializeWallet();
}, []);
const initializeWallet = async () => {
try {
setLoading(true);
// Setup chains
setupChainConfigs({
overrides: {
'1': { rpcUrl: 'https://my-eth-rpc.com' }
}
});
const loadedVault = await Vault.load(password, encryptedVault);
setVault(loadedVault);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
const sendToken = async (from: string, to: string, amount: string, tokenAddress: string, chainId: string) => {
if (!vault) throw new Error('Wallet not loaded');
return vault.sendToken(from, to, amount, tokenAddress, chainId);
};
const getBalance = async (address: string, chainId: string) => {
if (!vault) throw new Error('Wallet not loaded');
return vault.getNativeBalance(address, chainId);
};
return {
vault,
loading,
error,
sendToken,
getBalance
};
};Configuration
Vanity Wallet Settings
import { VANITY_WALLET_CONFIG } from 'pwc-wallet-sdk';
// Default settings
console.log(VANITY_WALLET_CONFIG.DEFAULT_PREFIX); // 'aaa'
console.log(VANITY_WALLET_CONFIG.DEFAULT_MAX_ATTEMPTS); // 1000000
console.log(VANITY_WALLET_CONFIG.DEFAULT_CASE_SENSITIVE); // falseSupported Chains
import { SUPPORTED_CHAINS } from 'pwc-wallet-sdk';
// View all supported chains
Object.entries(SUPPORTED_CHAINS).forEach(([chainId, config]) => {
console.log(`${chainId}: ${config.name} (${config.type})`);
});Core Wallet Functions
Account Management
Add New HD Account
// Add a new HD account to the vault
const newAccount = vault.addHDAccount();
console.log('New account address:', newAccount.address);Add New Solana Account
// Add a new Solana account
const newSolanaAccount = vault.addSolanaAccount();
console.log('New Solana account:', newSolanaAccount.address);Import Account
// Import an existing account with private key
const importedAccount = vault.importAccount('private-key-without-0x-prefix');
console.log('Imported account:', importedAccount.address);Get Accounts
// Get all accounts in the vault
const accounts = vault.getAccounts();
console.log('All accounts:', accounts.map(acc => acc.address));Balance & Token Functions
Get Native Balance
// Get native token balance (ETH, BNB, MATIC, etc.)
const balance = await vault.getNativeBalance(address, '1'); // Ethereum
console.log('ETH Balance:', ethers.formatEther(balance));Get Token Balance
// Get ERC-20 token balance
const tokenBalance = await vault.getTokenBalance(address, tokenAddress, '1');
console.log('Token Balance:', ethers.formatUnits(tokenBalance, 18));Get Token Info
// Get token information
const tokenInfo = await vault.getTokenInfo(tokenAddress, '1');
console.log('Token:', tokenInfo.name, '(', tokenInfo.symbol, ')');Transaction Functions
Send Native Token
// Send native tokens (ETH, BNB, etc.)
const tx = await vault.sendNativeToken(from, to, amount, '1');
console.log('Transaction hash:', tx.hash);Send Token
// Send ERC-20 tokens
const tx = await vault.sendToken(from, to, amount, tokenAddress, '1');
console.log('Transaction hash:', tx.hash);Export Mnemonic
// Export the mnemonic phrase (requires password)
const mnemonic = await vault.exportMnemonic(password);
console.log('Mnemonic:', mnemonic);Multi-Transfer Operations
Batch Send Native Tokens
import { MultiTransferService } from 'pwc-wallet-sdk';
const multiTransferService = new MultiTransferService(vault, chainService, '1'); // '1' lร chainId cho Ethereum mainnet
const recipients = [
{ address: '0x1111...', amount: '0.01' },
{ address: '0x2222...', amount: '0.02' },
{ address: '0x3333...', amount: '0.005' }
];
const result = await multiTransferService.transferNativeTokens(
fromAddress,
recipients,
'1', // chainId
{ batchSize: 5, onProgress: (progress) => console.log('Progress:', progress) }
);
console.log('Successful:', result.successfulCount);
console.log('Failed:', result.failedCount);
console.log('Total gas used:', result.totalGasUsed.toString());Batch Send ERC-20 Tokens
const result = await multiTransferService.transferTokens(
fromAddress,
tokenAddress, // USDT, USDC, etc.
recipients,
'1', // chainId
{ batchSize: 10 }
);
console.log('Token transfers completed:', result.successfulCount);Configuration
Built-in Chains
The SDK supports multiple blockchain networks out of the box:
import { SUPPORTED_CHAINS } from 'pwc-wallet-sdk';
// View all supported chains
Object.entries(SUPPORTED_CHAINS).forEach(([chainId, config]) => {
console.log(`${chainId}: ${config.name} (${config.type})`);
});Custom Chain Management
Override Built-in Chains
import { overrideChain } from 'pwc-wallet-sdk';
// Override Ethereum RPC URL
overrideChain('1', {
rpcUrl: 'https://my-eth-rpc.com'
});Add Custom Chains
import { registerCustomChain } from 'pwc-wallet-sdk';
registerCustomChain('custom-1', {
name: 'My Custom Chain',
rpcUrl: 'https://my-custom-rpc.com',
explorerUrl: 'https://my-explorer.com',
nativeCurrency: { name: 'Token', symbol: 'TKN', decimals: 18 },
type: 'evm'
});Setup All Chains at Once
import { setupChainConfigs } from 'pwc-wallet-sdk';
setupChainConfigs({
overrides: {
'1': { rpcUrl: 'https://my-eth-rpc.com' },
'56': { rpcUrl: 'https://my-bsc-rpc.com' }
},
customChains: {
'custom-1': {
name: 'My Chain',
rpcUrl: 'https://my-rpc.com',
explorerUrl: 'https://my-explorer.com',
nativeCurrency: { name: 'Token', symbol: 'TKN', decimals: 18 },
type: 'evm'
}
}
});Chain Configuration Priority
- Custom chains (highest priority)
- Overrides (modify built-in chains)
- Built-in chains (default configuration)
Utility Functions
import {
getChainConfig,
getAllAvailableChains,
clearCustomChains,
clearOverrides
} from 'pwc-wallet-sdk';
// Get chain configuration
const config = getChainConfig('1');
// Get all available chains
const allChains = getAllAvailableChains();
// Clear custom configurations
clearCustomChains();
clearOverrides();Vanity Wallet Settings
import { VANITY_WALLET_CONFIG } from 'pwc-wallet-sdk';
// Default settings
console.log(VANITY_WALLET_CONFIG.DEFAULT_PREFIX); // 'aaa'
console.log(VANITY_WALLET_CONFIG.DEFAULT_MAX_ATTEMPTS); // 1000000
console.log(VANITY_WALLET_CONFIG.DEFAULT_CASE_SENSITIVE); // falseSupported Chains
import { SUPPORTED_CHAINS } from 'pwc-wallet-sdk';
// View all supported chains
Object.entries(SUPPORTED_CHAINS).forEach(([chainId, config]) => {
console.log(`${chainId}: ${config.name} (${config.type})`);
});Advanced Features
Gas Estimation
Estimate Native Transfer Gas
const gasEstimate = await vault.estimateNativeTransferGas(
fromAddress,
toAddress,
amount,
'1'
);
console.log('Estimated gas:', gasEstimate.toString());
console.log('Estimated cost (in ETH):', ethers.formatEther(gasEstimate * gasPrice));Estimate Token Transfer Gas
const gasEstimate = await vault.estimateTokenTransferGas(
fromAddress,
tokenAddress,
toAddress,
amount,
'1'
);
console.log('Estimated gas for token transfer:', gasEstimate.toString());Estimate Multi-Transfer Gas
const recipients = [
{ address: '0x1111...', amount: '0.01' },
{ address: '0x2222...', amount: '0.02' },
{ address: '0x3333...', amount: '0.005' }
];
// Estimate for native token multi-transfer
const nativeGasEstimate = await multiTransferService.estimateGasCost(
recipients,
'1', // chainId
true // Native tokens
);
// Estimate for token multi-transfer
const tokenGasEstimate = await multiTransferService.estimateGasCost(
recipients,
'1', // chainId
false, // ERC-20 tokens
tokenAddress // USDC
);
console.log('Native multi-transfer gas:', nativeGasEstimate.toString());
console.log('Token multi-transfer gas:', tokenGasEstimate.toString());Security Considerations
- Password Strength: Use strong passwords for vault encryption
- Private Key Storage: Private keys are never stored in plain text
- Memory Safety: Sensitive data is cleared from memory when possible
- Encryption: All vault data is encrypted using AES-256
- Validation: Input validation prevents common attack vectors
Error Handling
try {
const vault = await Vault.load(password, encryptedVault);
await vault.sendToken(from, to, amount, tokenAddress, '1');
} catch (error) {
if (error.message.includes('incorrect password')) {
// Handle password error
} else if (error.message.includes('insufficient balance')) {
// Handle balance error
} else {
// Handle other errors
}
}Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details.
๐ฅ New API: Simple chainId-based usage
All read-only and write operations now only require chainId, address, token, ...
No need to manage or pass provider from your app. The SDK manages providers internally.
Example: Get native balance
import { getNativeBalance } from 'pwc-wallet-sdk';
const balance = await getNativeBalance('0x123...', '1'); // Ethereum mainnetExample: Get ERC-20 token balance
import { getTokenBalance } from 'pwc-wallet-sdk';
const balance = await getTokenBalance('0xToken...', '0x123...', '1');Example: MultiTransfer
import { MultiTransferService } from 'pwc-wallet-sdk';
const service = new MultiTransferService(vault, chainService, '1'); // truyแปn chainId rรต rร ng
await service.transferNativeTokens('0x123...', [{ address: '0xabc...', amount: '0.1' }], '1');Example: NFTService
import { NFTService } from 'pwc-wallet-sdk';
// Read-only operations
const nftService = new NFTService('1'); // chainId = '1' for Ethereum
const nftDetail = await nftService.getNFTDetail('0xContract...', '123');
// Write operations (transfer)
const nftService = new NFTService('1', vault, fromAddress);
await nftService.transferNFTWithVault(fromAddress, toAddress, contractAddress, tokenId);Advanced: Override RPC URLs
You can override RPC URLs for any chain via config if needed.
๐ฑ QR Code Functionality
Generate Address QR
Generates QR code data for a wallet address.
Parameters:
address- The wallet address to encodelabel- Optional label for the address
import { QRCodeService } from 'pwc-wallet-sdk';
// Generate QR for any address
const qrData = QRCodeService.generateAddressQR('0x1234...', 'My Wallet');
// Generate QR from Vault account
const qrData = QRCodeService.generateAddressQRFromVault(vault, 0, 'My Wallet');Generate Mnemonic QR
Generates encrypted QR code data for mnemonic backup.
Parameters:
mnemonic- The mnemonic phrase to encryptpassword- Password for encryptionchainType- Type of blockchain (evm, solana, etc.) - defaults to 'evm'accountCount- Number of accounts to import - defaults to 1
import { QRCodeService } from 'pwc-wallet-sdk';
// Generate QR for mnemonic
const qrData = await QRCodeService.generateMnemonicQR(
'abandon abandon abandon...',
'my-password',
'evm',
3
);
// Generate QR from Vault
const qrData = await QRCodeService.generateMnemonicQRFromVault(
vault,
'my-password',
3
);Generate Transaction QR
Generates QR code data for transaction signing.
Parameters:
transactionData- Transaction details object with required fields:txType- 'native', 'token', or 'nft'chainId- Chain ID (e.g., '1' for Ethereum mainnet)to- Recipient addressamount- Amount to sendtokenAddress- Optional: Token contract address (for token transfers)tokenId- Optional: Token ID (for NFT transfers)gasLimit- Optional: Gas limitgasPrice- Optional: Gas price
import { QRCodeService } from 'pwc-wallet-sdk';
// Native token transfer
const nativeTxData = {
txType: 'native',
chainId: '1',
to: '0x1234...',
amount: '0.1',
gasLimit: '21000'
};
// ERC-20 token transfer
const tokenTxData = {
txType: 'token',
chainId: '1',
to: '0x1234...',
amount: '100',
tokenAddress: '0xA0b86a33E6441b8c4C8C8C8C8C8C8C8C8C8C8C8C8',
gasLimit: '65000'
};
const qrData = QRCodeService.generateTransactionQR(nativeTxData);Parse and Extract QR Data
Parse QR code data and extract specific information.
import { QRCodeService } from 'pwc-wallet-sdk';
// Parse any QR code
const qrData = QRCodeService.parseQRData(qrString);
// Extract specific data types
const address = QRCodeService.extractAddress(qrString);
const walletData = QRCodeService.extractWalletImportData(qrString);
const txData = QRCodeService.extractTransactionData(qrString);
// Validate address types
const addressType = QRCodeService.getAddressType('0x1234...'); // 'ethereum'
const isValidEth = QRCodeService.isValidEthereumAddress('0x1234...');
const isValidSol = QRCodeService.isValidSolanaAddress('ABC123...');Import Wallet from QR
Imports wallet from QR code data (requires Vault).
Parameters:
qrString- QR code string to parsepassword- Password to decrypt the mnemonic
// Import wallet from scanned QR code
const accounts = await vault.importFromQR(qrString, 'my-password');
console.log('Imported accounts:', accounts);Process Transaction from QR
Processes transaction from QR code data (requires Vault).
Parameters:
qrString- QR code string to parsefromAddress- Sender's address
// Process transaction from scanned QR code
const result = await vault.processTransactionFromQR(qrString, '0x1234...');
console.log('Transaction hash:', result.hash);Validate QR Code
Validates QR code data without processing it.
Parameters:
qrString- QR code string to validate
Returns:
isValid- Boolean indicating if QR is validtype- Type of QR code ('address', 'wallet-import', 'transaction', or 'unknown')data- Parsed data if valid, null if invalid
import { QRCodeService } from 'pwc-wallet-sdk';
// Validate QR code before processing
const validation = QRCodeService.validateQRCode(qrString);
console.log('QR type:', validation.type);
console.log('Is valid:', validation.isValid);
if (validation.isValid) {
console.log('QR data:', validation.data);
}Multi-Transfer (Batch Send) - Simple Usage
import { MultiTransferService } from 'pwc-wallet-sdk';
// Create the service easily (no need to handle privateKey or chainService)
const multiTransferService = await MultiTransferService.fromVault(vault, fromAddress, '1');
// Batch send native tokens
const recipients = [
{ address: '0x1111...', amount: '0.01' },
{ address: '0x2222...', amount: '0.02' }
];
const result = await multiTransferService.transferNativeTokens(
fromAddress,
recipients,
'1',
{ batchSize: 2, onProgress: (completed, total, txHash) => console.log(completed, total, txHash) }
);
console.log('Batch result:', result);
// Batch send ERC-20 tokens
const tokenResult = await multiTransferService.transferTokens(
fromAddress,
'0xTokenContractAddress...',
recipients,
'1',
{ batchSize: 2 }
);
console.log('Token batch result:', tokenResult);Generate EIP-681 Compatible Address QR (for Metamask, Binance, Trust Wallet)
Generates a QR code string in EIP-681 format, which is compatible with most popular wallets.
Parameters:
address- The wallet address to encode
import { QRCodeService } from 'pwc-wallet-sdk';
// Generate EIP-681 QR string (recommended for wallet compatibility)
const qrString = QRCodeService.generateEIP681AddressQR('0x1234abcd...');
// Pass this string to your QR code generator (e.g., react-native-qrcode-svg, qrcode.react, etc.)Tip: Use this format if you want users to scan your QR code with Metamask, Binance, Trust Wallet, or other EVM wallets. If you use the default generateAddressQR, it will only work with your own app.