pwc-sdk-wallet 0.7.9 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -5
- package/dist/Vault.d.ts +8 -0
- package/dist/Vault.js +33 -2
- package/dist/chain/TronChainService.js +58 -0
- package/dist/keyrings/HDKeyring.js +1 -1
- package/dist/keyrings/SolanaKeyring.js +1 -1
- package/dist/keyrings/TronKeyring.js +59 -1
- package/dist/polyfills/react-native.d.ts +34 -0
- package/dist/polyfills/react-native.js +118 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1503,6 +1503,90 @@ npm install pwc-wallet-sdk react-native-webview
|
|
|
1503
1503
|
|
|
1504
1504
|
**Note:** This is a peer dependency. Mobile developers need to install it to use the DApp Browser features.
|
|
1505
1505
|
|
|
1506
|
+
### React Native Polyfills (Required for TRON Support)
|
|
1507
|
+
|
|
1508
|
+
The SDK uses `tronweb` for TRON blockchain support, which requires Node.js polyfills in React Native. You **must** set up polyfills before using the SDK in a React Native app.
|
|
1509
|
+
|
|
1510
|
+
#### Option 1: Automatic Polyfills (Recommended)
|
|
1511
|
+
|
|
1512
|
+
The SDK automatically applies polyfills when using TRON features, but you still need to install the required packages:
|
|
1513
|
+
|
|
1514
|
+
```bash
|
|
1515
|
+
npm install buffer process react-native-get-random-values
|
|
1516
|
+
```
|
|
1517
|
+
|
|
1518
|
+
Then, at the **very top** of your app's entry file (e.g., `index.js` or `App.js`), import the polyfills:
|
|
1519
|
+
|
|
1520
|
+
```typescript
|
|
1521
|
+
// At the VERY TOP of index.js or App.js - before any other imports
|
|
1522
|
+
import 'react-native-get-random-values';
|
|
1523
|
+
import { Buffer } from 'buffer';
|
|
1524
|
+
import process from 'process';
|
|
1525
|
+
|
|
1526
|
+
// Make them available globally
|
|
1527
|
+
global.Buffer = Buffer;
|
|
1528
|
+
global.process = process;
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
#### Option 2: Manual Setup
|
|
1532
|
+
|
|
1533
|
+
If you prefer more control, you can manually set up polyfills:
|
|
1534
|
+
|
|
1535
|
+
1. Install dependencies:
|
|
1536
|
+
```bash
|
|
1537
|
+
npm install buffer process react-native-get-random-values
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1540
|
+
2. Create a polyfill file (e.g., `polyfills.js`):
|
|
1541
|
+
```typescript
|
|
1542
|
+
import 'react-native-get-random-values';
|
|
1543
|
+
import { Buffer } from 'buffer';
|
|
1544
|
+
import process from 'process';
|
|
1545
|
+
|
|
1546
|
+
global.Buffer = Buffer;
|
|
1547
|
+
global.process = process;
|
|
1548
|
+
```
|
|
1549
|
+
|
|
1550
|
+
3. Import it at the top of your entry file:
|
|
1551
|
+
```typescript
|
|
1552
|
+
import './polyfills';
|
|
1553
|
+
// ... rest of your imports
|
|
1554
|
+
```
|
|
1555
|
+
|
|
1556
|
+
#### Troubleshooting
|
|
1557
|
+
|
|
1558
|
+
If you encounter errors like:
|
|
1559
|
+
- `RCTFatal` or `TronWebProto.Vote.serializeBinaryToWriter`
|
|
1560
|
+
- `Buffer is not defined`
|
|
1561
|
+
- `process is not defined`
|
|
1562
|
+
- `crypto.getRandomValues is not a function`
|
|
1563
|
+
|
|
1564
|
+
Make sure:
|
|
1565
|
+
1. ✅ `react-native-get-random-values` is imported **first** (before any crypto operations)
|
|
1566
|
+
2. ✅ `buffer` and `process` are installed and set as globals
|
|
1567
|
+
3. ✅ Polyfills are imported **before** importing the SDK
|
|
1568
|
+
4. ✅ You've restarted your Metro bundler after installing dependencies
|
|
1569
|
+
|
|
1570
|
+
#### Metro Config (Optional but Recommended)
|
|
1571
|
+
|
|
1572
|
+
For better compatibility, you can configure Metro to handle Node.js modules. Create or update `metro.config.js`:
|
|
1573
|
+
|
|
1574
|
+
```javascript
|
|
1575
|
+
const { getDefaultConfig } = require('metro-config');
|
|
1576
|
+
|
|
1577
|
+
module.exports = (async () => {
|
|
1578
|
+
const {
|
|
1579
|
+
resolver: { sourceExts, assetExts },
|
|
1580
|
+
} = await getDefaultConfig();
|
|
1581
|
+
|
|
1582
|
+
return {
|
|
1583
|
+
resolver: {
|
|
1584
|
+
sourceExts: [...sourceExts, 'cjs'],
|
|
1585
|
+
},
|
|
1586
|
+
};
|
|
1587
|
+
})();
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1506
1590
|
## Quick Start
|
|
1507
1591
|
|
|
1508
1592
|
### 1. Basic Wallet Creation
|
|
@@ -1795,7 +1879,7 @@ console.log('New account address:', newAccount.address);
|
|
|
1795
1879
|
#### Add New Solana Account
|
|
1796
1880
|
```typescript
|
|
1797
1881
|
// Add a new Solana account
|
|
1798
|
-
const newSolanaAccount = vault.
|
|
1882
|
+
const newSolanaAccount = await vault.addNewSolanaAccount();
|
|
1799
1883
|
console.log('New Solana account:', newSolanaAccount.address);
|
|
1800
1884
|
```
|
|
1801
1885
|
|
|
@@ -1827,6 +1911,14 @@ console.log('All accounts:', accounts.map(acc => acc.address));
|
|
|
1827
1911
|
// Get native token balance (ETH, BNB, MATIC, etc.)
|
|
1828
1912
|
const balance = await vault.getNativeBalance(address, '1'); // Ethereum
|
|
1829
1913
|
console.log('ETH Balance:', ethers.formatEther(balance));
|
|
1914
|
+
|
|
1915
|
+
// Get SOL balance on Solana
|
|
1916
|
+
const solBalance = await vault.getNativeBalance(address, 'solana');
|
|
1917
|
+
console.log('SOL Balance:', solBalance.toString(), 'lamports');
|
|
1918
|
+
|
|
1919
|
+
// Get TRX balance on TRON
|
|
1920
|
+
const trxBalance = await vault.getNativeBalance(address, 'tron');
|
|
1921
|
+
console.log('TRX Balance:', trxBalance.toString(), 'SUN');
|
|
1830
1922
|
```
|
|
1831
1923
|
|
|
1832
1924
|
#### Get Token Balance
|
|
@@ -1847,9 +1939,17 @@ console.log('Token:', tokenInfo.name, '(', tokenInfo.symbol, ')');
|
|
|
1847
1939
|
|
|
1848
1940
|
#### Send Native Token
|
|
1849
1941
|
```typescript
|
|
1850
|
-
// Send native tokens (ETH, BNB, etc.)
|
|
1851
|
-
const tx = await vault.sendNativeToken(from, to, amount, '1');
|
|
1942
|
+
// Send native tokens (ETH, BNB, etc.) on EVM chains
|
|
1943
|
+
const tx = await vault.sendNativeToken(from, to, amount, '1'); // Ethereum
|
|
1852
1944
|
console.log('Transaction hash:', tx.hash);
|
|
1945
|
+
|
|
1946
|
+
// Send SOL on Solana
|
|
1947
|
+
const solTx = await vault.sendNativeToken(from, to, amount, 'solana');
|
|
1948
|
+
console.log('Solana transaction hash:', solTx.hash);
|
|
1949
|
+
|
|
1950
|
+
// Send TRX on TRON
|
|
1951
|
+
const trxTx = await vault.sendNativeToken(from, to, amount, 'tron');
|
|
1952
|
+
console.log('TRON transaction hash:', trxTx.hash);
|
|
1853
1953
|
```
|
|
1854
1954
|
|
|
1855
1955
|
#### Send Token
|
|
@@ -2085,7 +2185,8 @@ console.log('Token transfers completed:', result.successfulCount);
|
|
|
2085
2185
|
```typescript
|
|
2086
2186
|
import { Vault, type VaultConfig } from 'pwc-wallet-sdk';
|
|
2087
2187
|
|
|
2088
|
-
|
|
2188
|
+
// Example: EVM chains config
|
|
2189
|
+
const evmConfig: VaultConfig = {
|
|
2089
2190
|
rpcUrls: {
|
|
2090
2191
|
'1': 'https://your-eth-rpc.com',
|
|
2091
2192
|
'56': 'https://your-bsc-rpc.com',
|
|
@@ -2110,9 +2211,37 @@ const config: VaultConfig = {
|
|
|
2110
2211
|
enableBatchProcessing: true,
|
|
2111
2212
|
}
|
|
2112
2213
|
};
|
|
2214
|
+
|
|
2215
|
+
// Example: Solana config
|
|
2216
|
+
const solanaConfig: VaultConfig = {
|
|
2217
|
+
rpcUrls: {
|
|
2218
|
+
'solana': 'https://your-solana-rpc.com',
|
|
2219
|
+
'solana-devnet': 'https://your-devnet-rpc.com'
|
|
2220
|
+
},
|
|
2221
|
+
explorerUrls: {
|
|
2222
|
+
'solana': 'https://solscan.io',
|
|
2223
|
+
'solana-devnet': 'https://solscan.io?cluster=devnet'
|
|
2224
|
+
},
|
|
2225
|
+
defaultChainId: 'solana'
|
|
2226
|
+
};
|
|
2227
|
+
|
|
2228
|
+
// Example: TRON config
|
|
2229
|
+
const tronConfig: VaultConfig = {
|
|
2230
|
+
rpcUrls: {
|
|
2231
|
+
'tron': 'https://your-tron-rpc.com',
|
|
2232
|
+
'tron-shasta': 'https://your-shasta-rpc.com'
|
|
2233
|
+
},
|
|
2234
|
+
explorerUrls: {
|
|
2235
|
+
'tron': 'https://tronscan.org',
|
|
2236
|
+
'tron-shasta': 'https://shasta.tronscan.org'
|
|
2237
|
+
},
|
|
2238
|
+
defaultChainId: 'tron'
|
|
2239
|
+
};
|
|
2113
2240
|
```
|
|
2114
2241
|
|
|
2115
2242
|
#### Usage Example (Recommended for Mobile Apps)
|
|
2243
|
+
|
|
2244
|
+
**For EVM Chains:**
|
|
2116
2245
|
```typescript
|
|
2117
2246
|
import { Vault, type VaultConfig } from 'pwc-wallet-sdk';
|
|
2118
2247
|
const appConfig: VaultConfig = {
|
|
@@ -2125,12 +2254,63 @@ const appConfig: VaultConfig = {
|
|
|
2125
2254
|
const { vault, encryptedVault } = await Vault.createNew(password, 'evm', appConfig);
|
|
2126
2255
|
|
|
2127
2256
|
// Pass config when loading existing vault
|
|
2128
|
-
const vault = await Vault.load(
|
|
2257
|
+
const vault = await Vault.load(password, encryptedVault, appConfig);
|
|
2129
2258
|
|
|
2130
2259
|
// All operations will use the config automatically
|
|
2131
2260
|
await vault.sendToken(from, to, amount, tokenAddress, '1');
|
|
2132
2261
|
```
|
|
2133
2262
|
|
|
2263
|
+
**For Solana:**
|
|
2264
|
+
```typescript
|
|
2265
|
+
import { Vault, type VaultConfig } from 'pwc-wallet-sdk';
|
|
2266
|
+
|
|
2267
|
+
// Configure Solana RPC URLs
|
|
2268
|
+
const solanaConfig: VaultConfig = {
|
|
2269
|
+
rpcUrls: {
|
|
2270
|
+
'solana': 'https://your-solana-rpc.com', // Mainnet
|
|
2271
|
+
'solana-devnet': 'https://your-devnet-rpc.com' // Devnet (optional)
|
|
2272
|
+
},
|
|
2273
|
+
explorerUrls: {
|
|
2274
|
+
'solana': 'https://solscan.io',
|
|
2275
|
+
'solana-devnet': 'https://solscan.io?cluster=devnet'
|
|
2276
|
+
},
|
|
2277
|
+
defaultChainId: 'solana' // Optional: set default chain
|
|
2278
|
+
};
|
|
2279
|
+
|
|
2280
|
+
// Create Solana vault with config
|
|
2281
|
+
const { vault, encryptedVault } = await Vault.createNew('password', 'solana', solanaConfig);
|
|
2282
|
+
|
|
2283
|
+
// Or from mnemonic
|
|
2284
|
+
const { vault, encryptedVault } = await Vault.createFromMnemonic(
|
|
2285
|
+
mnemonic,
|
|
2286
|
+
'password',
|
|
2287
|
+
'solana',
|
|
2288
|
+
solanaConfig
|
|
2289
|
+
);
|
|
2290
|
+
|
|
2291
|
+
// All Solana operations will use the configured RPC URLs
|
|
2292
|
+
const balance = await vault.getNativeBalance(address, 'solana');
|
|
2293
|
+
const tx = await vault.sendSPLToken(from, to, amount, tokenAddress);
|
|
2294
|
+
```
|
|
2295
|
+
|
|
2296
|
+
**For TRON:**
|
|
2297
|
+
```typescript
|
|
2298
|
+
import { Vault, type VaultConfig } from 'pwc-wallet-sdk';
|
|
2299
|
+
|
|
2300
|
+
const tronConfig: VaultConfig = {
|
|
2301
|
+
rpcUrls: {
|
|
2302
|
+
'tron': 'https://your-tron-rpc.com',
|
|
2303
|
+
'tron-shasta': 'https://your-shasta-rpc.com' // Testnet (optional)
|
|
2304
|
+
},
|
|
2305
|
+
explorerUrls: {
|
|
2306
|
+
'tron': 'https://tronscan.org',
|
|
2307
|
+
'tron-shasta': 'https://shasta.tronscan.org'
|
|
2308
|
+
}
|
|
2309
|
+
};
|
|
2310
|
+
|
|
2311
|
+
const { vault, encryptedVault } = await Vault.createNew('password', 'tron', tronConfig);
|
|
2312
|
+
```
|
|
2313
|
+
|
|
2134
2314
|
#### Alternative: Global Config (Advanced)
|
|
2135
2315
|
You can also set config globally for all vaults:
|
|
2136
2316
|
```typescript
|
package/dist/Vault.d.ts
CHANGED
|
@@ -136,6 +136,14 @@ export declare class Vault {
|
|
|
136
136
|
* @throws Error if the address is not found in any keyring
|
|
137
137
|
*/
|
|
138
138
|
getPrivateKeyFor(address: string): Promise<string>;
|
|
139
|
+
/**
|
|
140
|
+
* Gets the native token balance (ETH, SOL, TRX, etc.) for a specific address.
|
|
141
|
+
* @param address - The account address to check balance for
|
|
142
|
+
* @param chainId - The ID of the blockchain (e.g., '1' for Ethereum, 'solana' for Solana, 'tron' for TRON)
|
|
143
|
+
* @returns Promise resolving to the native token balance as a bigint
|
|
144
|
+
* @throws Error if the balance query fails or chain configuration not found
|
|
145
|
+
*/
|
|
146
|
+
getNativeBalance(address: string, chainId: ChainId): Promise<bigint>;
|
|
139
147
|
/**
|
|
140
148
|
* Gets the token balance for a specific account and token contract.
|
|
141
149
|
* @param accountAddress - The account address to check balance for
|
package/dist/Vault.js
CHANGED
|
@@ -134,12 +134,16 @@ class Vault {
|
|
|
134
134
|
else if (sKeyring.type === 'Solana') {
|
|
135
135
|
keyrings.push(await SolanaKeyring_1.SolanaKeyring.deserialize(sKeyring));
|
|
136
136
|
}
|
|
137
|
+
else if (sKeyring.type === 'Tron') {
|
|
138
|
+
keyrings.push(await TronKeyring_1.TronKeyring.deserialize(sKeyring));
|
|
139
|
+
}
|
|
137
140
|
else {
|
|
138
141
|
throw new Error(`Unknown keyring type: ${sKeyring.type}`);
|
|
139
142
|
}
|
|
140
143
|
}
|
|
141
144
|
catch (error) {
|
|
142
|
-
|
|
145
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
146
|
+
throw new Error(`Failed to deserialize ${sKeyring.type} keyring: ${errorMessage}`);
|
|
143
147
|
}
|
|
144
148
|
}
|
|
145
149
|
const vault = new Vault(keyrings, config);
|
|
@@ -147,6 +151,9 @@ class Vault {
|
|
|
147
151
|
if (keyrings.some(k => k instanceof SolanaKeyring_1.SolanaKeyring)) {
|
|
148
152
|
vault.chainId = 'solana';
|
|
149
153
|
}
|
|
154
|
+
else if (keyrings.some(k => k instanceof TronKeyring_1.TronKeyring)) {
|
|
155
|
+
vault.chainId = 'tron';
|
|
156
|
+
}
|
|
150
157
|
else {
|
|
151
158
|
vault.chainId = '1'; // Default to Ethereum mainnet
|
|
152
159
|
}
|
|
@@ -178,7 +185,8 @@ class Vault {
|
|
|
178
185
|
async addNewSolanaAccount() {
|
|
179
186
|
const solanaKeyring = this.keyrings.find(k => k instanceof SolanaKeyring_1.SolanaKeyring);
|
|
180
187
|
if (!solanaKeyring) {
|
|
181
|
-
|
|
188
|
+
const availableTypes = this.keyrings.map(k => k.type).join(', ') || 'none';
|
|
189
|
+
throw new Error(`No Solana keyring available to create new accounts. Available keyring types: ${availableTypes}. Make sure you created the vault with chainType: 'solana'.`);
|
|
182
190
|
}
|
|
183
191
|
const newAddress = await solanaKeyring.addNewAccount();
|
|
184
192
|
return {
|
|
@@ -380,6 +388,29 @@ class Vault {
|
|
|
380
388
|
throw new Error('Private key not found for the given address.');
|
|
381
389
|
}
|
|
382
390
|
// --- Blockchain Interaction Methods ---
|
|
391
|
+
/**
|
|
392
|
+
* Gets the native token balance (ETH, SOL, TRX, etc.) for a specific address.
|
|
393
|
+
* @param address - The account address to check balance for
|
|
394
|
+
* @param chainId - The ID of the blockchain (e.g., '1' for Ethereum, 'solana' for Solana, 'tron' for TRON)
|
|
395
|
+
* @returns Promise resolving to the native token balance as a bigint
|
|
396
|
+
* @throws Error if the balance query fails or chain configuration not found
|
|
397
|
+
*/
|
|
398
|
+
async getNativeBalance(address, chainId) {
|
|
399
|
+
const chainInfo = (0, chains_1.getChainConfig)(chainId);
|
|
400
|
+
const privateKey = await this.getPrivateKeyFor(address);
|
|
401
|
+
if (chainInfo.type === 'solana') {
|
|
402
|
+
const chainService = new SolanaChainService_1.SolanaChainService(privateKey, chainInfo);
|
|
403
|
+
return chainService.getNativeBalance();
|
|
404
|
+
}
|
|
405
|
+
else if (chainInfo.type === 'tron') {
|
|
406
|
+
const chainService = new TronChainService_1.TronChainService(privateKey, chainInfo);
|
|
407
|
+
return chainService.getNativeBalance();
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
const chainService = new ChainService_1.ChainService(privateKey, chainInfo);
|
|
411
|
+
return chainService.getNativeBalance();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
383
414
|
/**
|
|
384
415
|
* Gets the token balance for a specific account and token contract.
|
|
385
416
|
* @param accountAddress - The account address to check balance for
|
|
@@ -4,6 +4,64 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.TronChainService = void 0;
|
|
7
|
+
const isReactNative = (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') ||
|
|
8
|
+
(typeof window !== 'undefined' && window?.ReactNativeWebView !== undefined) ||
|
|
9
|
+
(typeof global !== 'undefined' && global.__DEV__ !== undefined && typeof navigator !== 'undefined');
|
|
10
|
+
if (isReactNative || (typeof window === 'undefined' && typeof global !== 'undefined')) {
|
|
11
|
+
// Polyfill Buffer
|
|
12
|
+
if (typeof global.Buffer === 'undefined') {
|
|
13
|
+
try {
|
|
14
|
+
global.Buffer = require('buffer').Buffer;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
console.warn('[PWC SDK] Failed to load buffer polyfill:', e);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// Polyfill process
|
|
21
|
+
if (typeof global.process === 'undefined') {
|
|
22
|
+
try {
|
|
23
|
+
global.process = require('process');
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
// Fallback minimal process object
|
|
27
|
+
global.process = {
|
|
28
|
+
env: {},
|
|
29
|
+
version: '',
|
|
30
|
+
versions: {},
|
|
31
|
+
platform: 'react-native',
|
|
32
|
+
nextTick: (fn) => setTimeout(() => fn(), 0),
|
|
33
|
+
browser: true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Ensure process.env exists
|
|
38
|
+
if (!global.process.env) {
|
|
39
|
+
global.process.env = {};
|
|
40
|
+
}
|
|
41
|
+
// Ensure crypto.getRandomValues is available
|
|
42
|
+
if (typeof global.crypto === 'undefined' || !global.crypto.getRandomValues) {
|
|
43
|
+
try {
|
|
44
|
+
require('react-native-get-random-values');
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
// Fallback if react-native-get-random-values is not installed
|
|
48
|
+
if (typeof global.crypto === 'undefined') {
|
|
49
|
+
global.crypto = {};
|
|
50
|
+
}
|
|
51
|
+
if (!global.crypto.getRandomValues) {
|
|
52
|
+
global.crypto.getRandomValues = function (arr) {
|
|
53
|
+
if (arr) {
|
|
54
|
+
const view = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
55
|
+
for (let i = 0; i < view.length; i++) {
|
|
56
|
+
view[i] = Math.floor(Math.random() * 256);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return arr;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
7
65
|
const tronweb_1 = __importDefault(require("tronweb"));
|
|
8
66
|
/**
|
|
9
67
|
* Service for interacting with TRON blockchain.
|
|
@@ -137,7 +137,7 @@ class SolanaKeyring {
|
|
|
137
137
|
if (data.type !== 'Solana' || !data.mnemonic) {
|
|
138
138
|
throw new Error('Invalid data for SolanaKeyring deserialization.');
|
|
139
139
|
}
|
|
140
|
-
//
|
|
140
|
+
// Only restore mnemonic, do not restore accounts
|
|
141
141
|
return new SolanaKeyring(data.mnemonic);
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
@@ -41,6 +41,64 @@ const bip32_1 = require("bip32");
|
|
|
41
41
|
const ecc = __importStar(require("@bitcoinerlab/secp256k1"));
|
|
42
42
|
const bip39 = __importStar(require("bip39"));
|
|
43
43
|
const chains_1 = require("../config/chains");
|
|
44
|
+
const isReactNative = (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') ||
|
|
45
|
+
(typeof window !== 'undefined' && window?.ReactNativeWebView !== undefined) ||
|
|
46
|
+
(typeof global !== 'undefined' && global.__DEV__ !== undefined && typeof navigator !== 'undefined');
|
|
47
|
+
if (isReactNative || (typeof window === 'undefined' && typeof global !== 'undefined')) {
|
|
48
|
+
// Polyfill Buffer
|
|
49
|
+
if (typeof global.Buffer === 'undefined') {
|
|
50
|
+
try {
|
|
51
|
+
global.Buffer = require('buffer').Buffer;
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
console.warn('[PWC SDK] Failed to load buffer polyfill:', e);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Polyfill process
|
|
58
|
+
if (typeof global.process === 'undefined') {
|
|
59
|
+
try {
|
|
60
|
+
global.process = require('process');
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
// Fallback minimal process object
|
|
64
|
+
global.process = {
|
|
65
|
+
env: {},
|
|
66
|
+
version: '',
|
|
67
|
+
versions: {},
|
|
68
|
+
platform: 'react-native',
|
|
69
|
+
nextTick: (fn) => setTimeout(() => fn(), 0),
|
|
70
|
+
browser: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Ensure process.env exists
|
|
75
|
+
if (!global.process.env) {
|
|
76
|
+
global.process.env = {};
|
|
77
|
+
}
|
|
78
|
+
// Ensure crypto.getRandomValues is available
|
|
79
|
+
if (typeof global.crypto === 'undefined' || !global.crypto.getRandomValues) {
|
|
80
|
+
try {
|
|
81
|
+
require('react-native-get-random-values');
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
// Fallback if react-native-get-random-values is not installed
|
|
85
|
+
if (typeof global.crypto === 'undefined') {
|
|
86
|
+
global.crypto = {};
|
|
87
|
+
}
|
|
88
|
+
if (!global.crypto.getRandomValues) {
|
|
89
|
+
global.crypto.getRandomValues = function (arr) {
|
|
90
|
+
if (arr) {
|
|
91
|
+
const view = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
92
|
+
for (let i = 0; i < view.length; i++) {
|
|
93
|
+
view[i] = Math.floor(Math.random() * 256);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return arr;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
44
102
|
const tronweb_1 = __importDefault(require("tronweb"));
|
|
45
103
|
/**
|
|
46
104
|
* TRON keyring for managing multiple TRON accounts
|
|
@@ -166,7 +224,7 @@ class TronKeyring {
|
|
|
166
224
|
if (data.type !== 'Tron' || !data.mnemonic) {
|
|
167
225
|
throw new Error('Invalid data for TronKeyring deserialization.');
|
|
168
226
|
}
|
|
169
|
-
//
|
|
227
|
+
// Only restore mnemonic, do not restore accounts
|
|
170
228
|
return new TronKeyring(data.mnemonic);
|
|
171
229
|
}
|
|
172
230
|
/**
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Polyfills
|
|
3
|
+
*
|
|
4
|
+
* This file provides necessary polyfills for Node.js APIs that are required
|
|
5
|
+
* by dependencies like tronweb (which uses Protocol Buffers).
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This file must be imported at the very beginning of your app entry point
|
|
8
|
+
* (e.g., index.js or App.js) BEFORE any other imports that use these polyfills.
|
|
9
|
+
*
|
|
10
|
+
* Usage in React Native app:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // At the very top of index.js or App.js
|
|
13
|
+
* import 'pwc-sdk-wallet/dist/polyfills/react-native';
|
|
14
|
+
*
|
|
15
|
+
* // Then import other modules
|
|
16
|
+
* import { Vault } from 'pwc-sdk-wallet';
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Alternatively, you can install the required polyfills in your app:
|
|
20
|
+
* ```bash
|
|
21
|
+
* npm install buffer process react-native-get-random-values
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* And import them at the top of your entry file:
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import 'react-native-get-random-values';
|
|
27
|
+
* import { Buffer } from 'buffer';
|
|
28
|
+
* import process from 'process';
|
|
29
|
+
*
|
|
30
|
+
* global.Buffer = Buffer;
|
|
31
|
+
* global.process = process;
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* React Native Polyfills
|
|
4
|
+
*
|
|
5
|
+
* This file provides necessary polyfills for Node.js APIs that are required
|
|
6
|
+
* by dependencies like tronweb (which uses Protocol Buffers).
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: This file must be imported at the very beginning of your app entry point
|
|
9
|
+
* (e.g., index.js or App.js) BEFORE any other imports that use these polyfills.
|
|
10
|
+
*
|
|
11
|
+
* Usage in React Native app:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // At the very top of index.js or App.js
|
|
14
|
+
* import 'pwc-sdk-wallet/dist/polyfills/react-native';
|
|
15
|
+
*
|
|
16
|
+
* // Then import other modules
|
|
17
|
+
* import { Vault } from 'pwc-sdk-wallet';
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Alternatively, you can install the required polyfills in your app:
|
|
21
|
+
* ```bash
|
|
22
|
+
* npm install buffer process react-native-get-random-values
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* And import them at the top of your entry file:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import 'react-native-get-random-values';
|
|
28
|
+
* import { Buffer } from 'buffer';
|
|
29
|
+
* import process from 'process';
|
|
30
|
+
*
|
|
31
|
+
* global.Buffer = Buffer;
|
|
32
|
+
* global.process = process;
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative' ||
|
|
37
|
+
(typeof window !== 'undefined' && window?.ReactNativeWebView !== undefined);
|
|
38
|
+
// Only apply polyfills in React Native environment
|
|
39
|
+
if (isReactNative || typeof window === 'undefined') {
|
|
40
|
+
// Polyfill Buffer
|
|
41
|
+
if (typeof global.Buffer === 'undefined') {
|
|
42
|
+
try {
|
|
43
|
+
global.Buffer = require('buffer').Buffer;
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.warn('Failed to load buffer polyfill:', e);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Polyfill process
|
|
50
|
+
if (typeof global.process === 'undefined') {
|
|
51
|
+
try {
|
|
52
|
+
global.process = require('process');
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
// Fallback minimal process object
|
|
56
|
+
global.process = {
|
|
57
|
+
env: {},
|
|
58
|
+
version: '',
|
|
59
|
+
versions: {},
|
|
60
|
+
platform: 'react-native',
|
|
61
|
+
nextTick: (fn) => setTimeout(() => fn(), 0),
|
|
62
|
+
browser: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Ensure process.env exists
|
|
67
|
+
if (!global.process.env) {
|
|
68
|
+
global.process.env = {};
|
|
69
|
+
}
|
|
70
|
+
// Polyfill crypto.getRandomValues (required by react-native-get-random-values)
|
|
71
|
+
// This should be imported by the app, but we ensure it's available
|
|
72
|
+
if (typeof global.crypto === 'undefined' || !global.crypto.getRandomValues) {
|
|
73
|
+
try {
|
|
74
|
+
// Try to use react-native-get-random-values if available
|
|
75
|
+
require('react-native-get-random-values');
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
// Fallback implementation
|
|
79
|
+
if (typeof global.crypto === 'undefined') {
|
|
80
|
+
global.crypto = {};
|
|
81
|
+
}
|
|
82
|
+
if (!global.crypto.getRandomValues) {
|
|
83
|
+
global.crypto.getRandomValues = function (arr) {
|
|
84
|
+
if (arr) {
|
|
85
|
+
const view = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
86
|
+
for (let i = 0; i < view.length; i++) {
|
|
87
|
+
view[i] = Math.floor(Math.random() * 256);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return arr;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Polyfill TextEncoder/TextDecoder if not available
|
|
96
|
+
if (typeof global.TextEncoder === 'undefined') {
|
|
97
|
+
try {
|
|
98
|
+
const { TextEncoder, TextDecoder } = require('util');
|
|
99
|
+
global.TextEncoder = TextEncoder;
|
|
100
|
+
global.TextDecoder = TextDecoder;
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
// Use polyfill if util is not available
|
|
104
|
+
try {
|
|
105
|
+
const { TextEncoder: TE, TextDecoder: TD } = require('text-encoding');
|
|
106
|
+
global.TextEncoder = TE;
|
|
107
|
+
global.TextDecoder = TD;
|
|
108
|
+
}
|
|
109
|
+
catch (e2) {
|
|
110
|
+
console.warn('TextEncoder/TextDecoder polyfills not available');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Ensure global is available
|
|
115
|
+
if (typeof global === 'undefined' && typeof window !== 'undefined') {
|
|
116
|
+
window.global = window;
|
|
117
|
+
}
|
|
118
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pwc-sdk-wallet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "A comprehensive wallet SDK for React Native (pwc), supporting multi-chain and multi-account features.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"bs58": "^6.0.0",
|
|
45
45
|
"buffer": "^6.0.3",
|
|
46
46
|
"crypto-js": "^4.2.0",
|
|
47
|
+
"process": "^0.11.10",
|
|
47
48
|
"ed25519-hd-key": "^1.3.0",
|
|
48
49
|
"react-native-camera": "^4.2.1",
|
|
49
50
|
"react-native-permissions": "^5.4.1",
|