@spacesops/wdk-react-native-provider 1.0.0-beta.3
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/LICENSE +176 -0
- package/README.md +841 -0
- package/lib/module/contexts/constants.js +20 -0
- package/lib/module/contexts/constants.js.map +1 -0
- package/lib/module/contexts/reducer.js +87 -0
- package/lib/module/contexts/reducer.js.map +1 -0
- package/lib/module/contexts/types.js +4 -0
- package/lib/module/contexts/types.js.map +1 -0
- package/lib/module/contexts/wallet-context.js +409 -0
- package/lib/module/contexts/wallet-context.js.map +1 -0
- package/lib/module/index.js +15 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/polyfills.js +34 -0
- package/lib/module/polyfills.js.map +1 -0
- package/lib/module/services/wdk-service/bare-api.js +69 -0
- package/lib/module/services/wdk-service/bare-api.js.map +1 -0
- package/lib/module/services/wdk-service/index.js +506 -0
- package/lib/module/services/wdk-service/index.js.map +1 -0
- package/lib/module/services/wdk-service/types.js +48 -0
- package/lib/module/services/wdk-service/types.js.map +1 -0
- package/lib/module/services/wdk-service/wdk-encryption-salt.js +29 -0
- package/lib/module/services/wdk-service/wdk-encryption-salt.js.map +1 -0
- package/lib/module/services/wdk-service/wdk-secret-manager-storage.js +64 -0
- package/lib/module/services/wdk-service/wdk-secret-manager-storage.js.map +1 -0
- package/lib/module/services/wdk-service/wdk-secret-manager-worklet.bundle.js +1 -0
- package/lib/module/services/wdk-service/wdk-worklet.mobile.bundle.js +1 -0
- package/lib/module/spec/hrpc/hrpc.json +66 -0
- package/lib/module/spec/hrpc/index.js +121 -0
- package/lib/module/spec/hrpc/index.js.map +1 -0
- package/lib/module/spec/hrpc/messages.js +291 -0
- package/lib/module/spec/hrpc/messages.js.map +1 -0
- package/lib/module/spec/schema/index.js +291 -0
- package/lib/module/spec/schema/index.js.map +1 -0
- package/lib/module/spec/schema/schema.json +186 -0
- package/lib/module/utils/get-balances-from-balance-map.js +18 -0
- package/lib/module/utils/get-balances-from-balance-map.js.map +1 -0
- package/lib/module/utils/get-transactions-from-transaction-map.js +10 -0
- package/lib/module/utils/get-transactions-from-transaction-map.js.map +1 -0
- package/lib/module/worklet/wdk-secret-manager-worklet.js +106 -0
- package/lib/module/worklet/wdk-secret-manager-worklet.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/contexts/constants.d.ts +3 -0
- package/lib/typescript/src/contexts/constants.d.ts.map +1 -0
- package/lib/typescript/src/contexts/reducer.d.ts +38 -0
- package/lib/typescript/src/contexts/reducer.d.ts.map +1 -0
- package/lib/typescript/src/contexts/types.d.ts +40 -0
- package/lib/typescript/src/contexts/types.d.ts.map +1 -0
- package/lib/typescript/src/contexts/wallet-context.d.ts +10 -0
- package/lib/typescript/src/contexts/wallet-context.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/polyfills.d.ts +7 -0
- package/lib/typescript/src/polyfills.d.ts.map +1 -0
- package/lib/typescript/src/services/wdk-service/bare-api.d.ts +32 -0
- package/lib/typescript/src/services/wdk-service/bare-api.d.ts.map +1 -0
- package/lib/typescript/src/services/wdk-service/index.d.ts +68 -0
- package/lib/typescript/src/services/wdk-service/index.d.ts.map +1 -0
- package/lib/typescript/src/services/wdk-service/types.d.ts +125 -0
- package/lib/typescript/src/services/wdk-service/types.d.ts.map +1 -0
- package/lib/typescript/src/services/wdk-service/wdk-encryption-salt.d.ts +6 -0
- package/lib/typescript/src/services/wdk-service/wdk-encryption-salt.d.ts.map +1 -0
- package/lib/typescript/src/services/wdk-service/wdk-secret-manager-storage.d.ts +13 -0
- package/lib/typescript/src/services/wdk-service/wdk-secret-manager-storage.d.ts.map +1 -0
- package/lib/typescript/src/utils/get-balances-from-balance-map.d.ts +4 -0
- package/lib/typescript/src/utils/get-balances-from-balance-map.d.ts.map +1 -0
- package/lib/typescript/src/utils/get-transactions-from-transaction-map.d.ts +4 -0
- package/lib/typescript/src/utils/get-transactions-from-transaction-map.d.ts.map +1 -0
- package/metro-polyfills.js +89 -0
- package/package.json +152 -0
- package/src/contexts/constants.ts +19 -0
- package/src/contexts/reducer.ts +103 -0
- package/src/contexts/types.ts +51 -0
- package/src/contexts/wallet-context.tsx +411 -0
- package/src/index.tsx +28 -0
- package/src/polyfills.ts +31 -0
- package/src/services/wdk-service/bare-api.ts +88 -0
- package/src/services/wdk-service/index.ts +765 -0
- package/src/services/wdk-service/types.ts +137 -0
- package/src/services/wdk-service/wdk-encryption-salt.ts +30 -0
- package/src/services/wdk-service/wdk-secret-manager-storage.ts +102 -0
- package/src/spec/hrpc/hrpc.json +66 -0
- package/src/spec/hrpc/index.js +228 -0
- package/src/spec/hrpc/messages.js +328 -0
- package/src/spec/schema/index.js +328 -0
- package/src/spec/schema/schema.json +186 -0
- package/src/utils/get-balances-from-balance-map.ts +22 -0
- package/src/utils/get-transactions-from-transaction-map.ts +18 -0
- package/src/worklet/wdk-secret-manager-worklet.js +118 -0
package/README.md
ADDED
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
# @tetherto/wdk-react-native-provider
|
|
2
|
+
|
|
3
|
+
A React Native library providing wallet context and WDK (Wallet Development Kit) service integration for building secure, multi-chain cryptocurrency wallets.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-chain Support**: Bitcoin, Ethereum, Polygon, Arbitrum, TON, Solana, and Tron
|
|
8
|
+
- **Multi-asset Management**: BTC, USDT, XAUT, and more
|
|
9
|
+
- **Secure Seed Management**: Encrypted seed phrase storage using native keychain
|
|
10
|
+
- **React Context API**: Easy-to-use wallet context provider and hooks
|
|
11
|
+
- **Account Management**: Create, import, and unlock wallets
|
|
12
|
+
- **Balance & Transactions**: Real-time balance updates and transaction history
|
|
13
|
+
- **Send & Quote**: Transaction sending and fee estimation
|
|
14
|
+
- **TypeScript Support**: Full type definitions included
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- **Android minSdkVersion**: 29 or higher
|
|
19
|
+
- **iOS Deployment Target**: 15.1 or higher
|
|
20
|
+
- **React Native**: 0.81.0+
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm install @tetherto/wdk-react-native-provider
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Android Configuration
|
|
29
|
+
|
|
30
|
+
The library requires **Android minSdkVersion 29** to properly run `react-native-bare-kit`.
|
|
31
|
+
|
|
32
|
+
**For Expo projects with prebuild:**
|
|
33
|
+
|
|
34
|
+
Add to your `app.json` or `app.config.js`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"expo": {
|
|
39
|
+
"plugins": [
|
|
40
|
+
[
|
|
41
|
+
"expo-build-properties",
|
|
42
|
+
{
|
|
43
|
+
"android": {
|
|
44
|
+
"minSdkVersion": 29
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**For bare React Native projects:**
|
|
54
|
+
|
|
55
|
+
Update `android/build.gradle`:
|
|
56
|
+
|
|
57
|
+
```gradle
|
|
58
|
+
buildscript {
|
|
59
|
+
ext {
|
|
60
|
+
minSdkVersion = 29
|
|
61
|
+
// ... other config
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Peer Dependencies
|
|
67
|
+
|
|
68
|
+
This library requires several peer dependencies. Install them using:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
npm install \
|
|
72
|
+
@craftzdog/react-native-buffer \
|
|
73
|
+
@react-native-async-storage/async-storage \
|
|
74
|
+
@spacesops/pear-wrk-wdk \
|
|
75
|
+
@tetherto/wdk-secret-manager \
|
|
76
|
+
b4a \
|
|
77
|
+
bip39 \
|
|
78
|
+
browserify-zlib \
|
|
79
|
+
decimal.js \
|
|
80
|
+
events \
|
|
81
|
+
http2-wrapper \
|
|
82
|
+
https-browserify \
|
|
83
|
+
nice-grpc-web \
|
|
84
|
+
path-browserify \
|
|
85
|
+
process \
|
|
86
|
+
querystring-es3 \
|
|
87
|
+
react-native-bare-kit \
|
|
88
|
+
react-native-crypto \
|
|
89
|
+
react-native-device-info \
|
|
90
|
+
react-native-get-random-values \
|
|
91
|
+
react-native-keychain \
|
|
92
|
+
react-native-tcp-socket \
|
|
93
|
+
react-native-url-polyfill \
|
|
94
|
+
sodium-javascript \
|
|
95
|
+
stream-browserify \
|
|
96
|
+
stream-http
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Metro Configuration
|
|
100
|
+
|
|
101
|
+
The library requires Node.js core module polyfills for React Native. Configure your Metro bundler using the provided helper function.
|
|
102
|
+
|
|
103
|
+
**For Expo projects:**
|
|
104
|
+
|
|
105
|
+
Update your `metro.config.js`:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
109
|
+
const { configureMetroForWDK } = require('@tetherto/wdk-react-native-provider/metro-polyfills');
|
|
110
|
+
|
|
111
|
+
const config = getDefaultConfig(__dirname);
|
|
112
|
+
const configWdk = configureMetroForWDK(config);
|
|
113
|
+
|
|
114
|
+
module.exports = configWdk;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Manual configuration (if needed):**
|
|
118
|
+
|
|
119
|
+
If you prefer to manually configure the polyfills:
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
123
|
+
const { getMetroPolyfills } = require('@tetherto/wdk-react-native-provider/metro-polyfills');
|
|
124
|
+
|
|
125
|
+
const config = getDefaultConfig(__dirname);
|
|
126
|
+
|
|
127
|
+
config.resolver.extraNodeModules = {
|
|
128
|
+
...config.resolver.extraNodeModules,
|
|
129
|
+
...getMetroPolyfills(),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
module.exports = config;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Note:** Runtime polyfills for Buffer, process, and crypto are automatically initialized when you import from `@tetherto/wdk-react-native-provider`. No additional setup is required.
|
|
136
|
+
|
|
137
|
+
## Quick Start
|
|
138
|
+
|
|
139
|
+
### 1. Setup the WalletProvider
|
|
140
|
+
|
|
141
|
+
Wrap your app with the `WalletProvider` and provide the required configuration.
|
|
142
|
+
|
|
143
|
+
**For Expo Router projects:**
|
|
144
|
+
|
|
145
|
+
Add the provider to your `app/_layout.tsx` file to make the `useWallet` hook accessible throughout your app:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
// app/_layout.tsx
|
|
149
|
+
import { WalletProvider } from '@tetherto/wdk-react-native-provider';
|
|
150
|
+
import { Stack } from 'expo-router';
|
|
151
|
+
|
|
152
|
+
// Define your chain configurations
|
|
153
|
+
const CHAINS_CONFIG = {
|
|
154
|
+
ethereum: {
|
|
155
|
+
chainId: 1,
|
|
156
|
+
blockchain: 'ethereum',
|
|
157
|
+
provider: 'https://mainnet.gateway.tenderly.co/YOUR_KEY',
|
|
158
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
159
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
160
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
161
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
162
|
+
transferMaxFee: 5000000,
|
|
163
|
+
swapMaxFee: 5000000,
|
|
164
|
+
bridgeMaxFee: 5000000,
|
|
165
|
+
paymasterToken: {
|
|
166
|
+
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
bitcoin: {
|
|
170
|
+
host: 'api.ordimint.com',
|
|
171
|
+
port: 50001,
|
|
172
|
+
},
|
|
173
|
+
// ... add other chains as needed
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export default function RootLayout() {
|
|
177
|
+
return (
|
|
178
|
+
<WalletProvider
|
|
179
|
+
config={{
|
|
180
|
+
indexer: {
|
|
181
|
+
apiKey: 'your-api-key-here',
|
|
182
|
+
url: 'https://your-indexer-url.com',
|
|
183
|
+
},
|
|
184
|
+
chains: CHAINS_CONFIG,
|
|
185
|
+
enableCaching: true, // Optional: enable caching for better performance
|
|
186
|
+
}}
|
|
187
|
+
>
|
|
188
|
+
<Stack />
|
|
189
|
+
</WalletProvider>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**For standard React Native projects:**
|
|
195
|
+
|
|
196
|
+
Wrap your root component:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
// App.tsx
|
|
200
|
+
import { WalletProvider } from '@tetherto/wdk-react-native-provider';
|
|
201
|
+
|
|
202
|
+
const CHAINS_CONFIG = {
|
|
203
|
+
ethereum: {
|
|
204
|
+
chainId: 1,
|
|
205
|
+
blockchain: 'ethereum',
|
|
206
|
+
provider: 'https://mainnet.gateway.tenderly.co/YOUR_KEY',
|
|
207
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
208
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
209
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
210
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
211
|
+
transferMaxFee: 5000000,
|
|
212
|
+
swapMaxFee: 5000000,
|
|
213
|
+
bridgeMaxFee: 5000000,
|
|
214
|
+
paymasterToken: {
|
|
215
|
+
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
bitcoin: {
|
|
219
|
+
host: 'api.ordimint.com',
|
|
220
|
+
port: 50001,
|
|
221
|
+
},
|
|
222
|
+
// ... other chains
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
function App() {
|
|
226
|
+
return (
|
|
227
|
+
<WalletProvider
|
|
228
|
+
config={{
|
|
229
|
+
indexer: {
|
|
230
|
+
apiKey: 'your-api-key-here',
|
|
231
|
+
url: 'https://your-indexer-url.com',
|
|
232
|
+
},
|
|
233
|
+
chains: CHAINS_CONFIG,
|
|
234
|
+
enableCaching: true, // Optional: enable caching for balances and transactions
|
|
235
|
+
}}
|
|
236
|
+
>
|
|
237
|
+
<YourApp />
|
|
238
|
+
</WalletProvider>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 2. Use the Wallet Context
|
|
244
|
+
|
|
245
|
+
Access wallet functionality using the `useWallet` hook:
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
import { useWallet } from '@tetherto/wdk-react-native-provider';
|
|
249
|
+
|
|
250
|
+
function WalletScreen() {
|
|
251
|
+
const {
|
|
252
|
+
wallet,
|
|
253
|
+
balances,
|
|
254
|
+
transactions,
|
|
255
|
+
isLoading,
|
|
256
|
+
isInitialized,
|
|
257
|
+
isUnlocked,
|
|
258
|
+
createWallet,
|
|
259
|
+
unlockWallet,
|
|
260
|
+
refreshWalletBalance,
|
|
261
|
+
refreshTransactions,
|
|
262
|
+
} = useWallet();
|
|
263
|
+
|
|
264
|
+
// Create a new wallet
|
|
265
|
+
const handleCreateWallet = async () => {
|
|
266
|
+
try {
|
|
267
|
+
const wallet = await createWallet({
|
|
268
|
+
name: 'Imported Wallet',
|
|
269
|
+
mnemonic: 'your twelve word seed phrase goes here',
|
|
270
|
+
});
|
|
271
|
+
console.log('Wallet created:', wallet);
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.error('Failed to create wallet:', error);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Unlock wallet
|
|
278
|
+
const handleUnlockWallet = async () => {
|
|
279
|
+
try {
|
|
280
|
+
await unlockWallet();
|
|
281
|
+
console.log('Wallet unlocked');
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error('Failed to unlock wallet:', error);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
if (!isInitialized) {
|
|
288
|
+
return <Text>Initializing...</Text>;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (!wallet) {
|
|
292
|
+
return (
|
|
293
|
+
<View>
|
|
294
|
+
<Button title="Create Wallet" onPress={handleCreateWallet} />
|
|
295
|
+
<Button title="Import Wallet" onPress={handleImportWallet} />
|
|
296
|
+
</View>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (!isUnlocked) {
|
|
301
|
+
return <Button title="Unlock Wallet" onPress={handleUnlockWallet} />;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return (
|
|
305
|
+
<View>
|
|
306
|
+
<Text>Wallet Name: {wallet.name}</Text>
|
|
307
|
+
<Button title="Refresh Balance" onPress={refreshWalletBalance} />
|
|
308
|
+
<Button title="Refresh Transactions" onPress={refreshTransactions} />
|
|
309
|
+
</View>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## API Reference
|
|
315
|
+
|
|
316
|
+
### WalletProvider
|
|
317
|
+
|
|
318
|
+
The main provider component that manages wallet state.
|
|
319
|
+
|
|
320
|
+
**Props:**
|
|
321
|
+
|
|
322
|
+
- `config.indexer` (object, required): Indexer service configuration
|
|
323
|
+
- `config.indexer.apiKey` (string, required): API key for the indexer service
|
|
324
|
+
- `config.indexer.url` (string, required): URL of the indexer service
|
|
325
|
+
- `config.indexer.version` (string, optional): API version (defaults to 'v1')
|
|
326
|
+
- `config.chains` (ChainsConfig, required): Chain configuration object containing network-specific settings
|
|
327
|
+
- `config.enableCaching` (boolean, optional): Enable caching for balances and transactions to improve performance
|
|
328
|
+
|
|
329
|
+
See [Chain Configuration](#chain-configuration) for detailed configuration options.
|
|
330
|
+
|
|
331
|
+
### useWallet()
|
|
332
|
+
|
|
333
|
+
Hook to access wallet context and functionality.
|
|
334
|
+
|
|
335
|
+
**Returns:**
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
{
|
|
339
|
+
// State
|
|
340
|
+
wallet?: Wallet | null;
|
|
341
|
+
addresses?: AddressMap;
|
|
342
|
+
balances: {
|
|
343
|
+
list: Amount[];
|
|
344
|
+
map: BalanceMap;
|
|
345
|
+
isLoading: boolean;
|
|
346
|
+
};
|
|
347
|
+
transactions: {
|
|
348
|
+
list: Transaction[];
|
|
349
|
+
map: TransactionMap;
|
|
350
|
+
isLoading: boolean;
|
|
351
|
+
};
|
|
352
|
+
isLoading: boolean;
|
|
353
|
+
error: string | null;
|
|
354
|
+
isInitialized: boolean;
|
|
355
|
+
isUnlocked: boolean;
|
|
356
|
+
|
|
357
|
+
// Actions
|
|
358
|
+
createWallet: (params: { name: string; mnemonic?: string }) => Promise<Wallet | null>;
|
|
359
|
+
clearWallet: () => Promise<void>;
|
|
360
|
+
clearError: () => void;
|
|
361
|
+
refreshWalletBalance: () => Promise<void>;
|
|
362
|
+
refreshTransactions: () => Promise<void>;
|
|
363
|
+
unlockWallet: () => Promise<boolean | undefined>;
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### WDKService
|
|
368
|
+
|
|
369
|
+
Low-level service for direct wallet operations. Available as a singleton.
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
import { WDKService } from '@tetherto/wdk-react-native-provider';
|
|
373
|
+
|
|
374
|
+
// Initialize WDK
|
|
375
|
+
await WDKService.initialize();
|
|
376
|
+
|
|
377
|
+
// Create seed
|
|
378
|
+
const seed = await WDKService.createSeed({ prf: 'passkey' });
|
|
379
|
+
|
|
380
|
+
// Import seed phrase
|
|
381
|
+
await WDKService.importSeedPhrase({
|
|
382
|
+
prf: 'passkey',
|
|
383
|
+
seedPhrase: 'your mnemonic here',
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Create wallet
|
|
387
|
+
const wallet = await WDKService.createWallet({
|
|
388
|
+
walletName: 'My Wallet',
|
|
389
|
+
prf: 'passkey',
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Get balances
|
|
393
|
+
const balances = await WDKService.resolveWalletBalances(
|
|
394
|
+
enabledAssets,
|
|
395
|
+
addressMap
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
// Send transaction
|
|
399
|
+
const result = await WDKService.sendByNetwork(
|
|
400
|
+
NetworkType.ETHEREUM,
|
|
401
|
+
0, // account index
|
|
402
|
+
100, // amount
|
|
403
|
+
'0x...', // recipient address
|
|
404
|
+
AssetTicker.USDT
|
|
405
|
+
);
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Chain Configuration
|
|
409
|
+
|
|
410
|
+
The library supports multiple blockchain networks, each with its own configuration structure.
|
|
411
|
+
|
|
412
|
+
### Chains Configuration Structure
|
|
413
|
+
|
|
414
|
+
The `chains` configuration object supports the following blockchain networks:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
const chains = {
|
|
418
|
+
ethereum?: EVMChainConfig;
|
|
419
|
+
arbitrum?: EVMChainConfig;
|
|
420
|
+
polygon?: EVMChainConfig;
|
|
421
|
+
ton?: TONChainConfig;
|
|
422
|
+
bitcoin?: BitcoinChainConfig;
|
|
423
|
+
tron?: TronChainConfig;
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### EVM Chain Configuration
|
|
428
|
+
|
|
429
|
+
For Ethereum, Polygon, and Arbitrum:
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
const ethereumConfig = {
|
|
433
|
+
chainId: 1,
|
|
434
|
+
blockchain: 'ethereum',
|
|
435
|
+
provider: 'https://mainnet.gateway.tenderly.co/YOUR_KEY',
|
|
436
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
437
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
438
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
439
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
440
|
+
transferMaxFee: 5000000,
|
|
441
|
+
swapMaxFee: 5000000,
|
|
442
|
+
bridgeMaxFee: 5000000,
|
|
443
|
+
paymasterToken: {
|
|
444
|
+
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
445
|
+
},
|
|
446
|
+
safeModulesVersion: '0.3.0', // Optional, for Polygon
|
|
447
|
+
};
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### TON Chain Configuration
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const tonConfig = {
|
|
454
|
+
tonApiClient: {
|
|
455
|
+
url: 'https://tonapi.io',
|
|
456
|
+
},
|
|
457
|
+
tonClient: {
|
|
458
|
+
url: 'https://toncenter.com/api/v2/jsonRPC',
|
|
459
|
+
},
|
|
460
|
+
paymasterToken: {
|
|
461
|
+
address: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
|
|
462
|
+
},
|
|
463
|
+
transferMaxFee: 1000000000,
|
|
464
|
+
};
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Bitcoin Chain Configuration
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
const bitcoinConfig = {
|
|
471
|
+
host: 'api.ordimint.com',
|
|
472
|
+
port: 50001,
|
|
473
|
+
};
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Tron Chain Configuration
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
const tronConfig = {
|
|
480
|
+
chainId: 3448148188,
|
|
481
|
+
provider: 'https://trongrid.io',
|
|
482
|
+
gasFreeProvider: 'https://gasfree.io',
|
|
483
|
+
apiKey: 'your-api-key',
|
|
484
|
+
apiSecret: 'your-api-secret',
|
|
485
|
+
serviceProvider: 'TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E',
|
|
486
|
+
verifyingContract: 'THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc',
|
|
487
|
+
transferMaxFee: 10000000,
|
|
488
|
+
swapMaxFee: 1000000,
|
|
489
|
+
bridgeMaxFee: 1000000,
|
|
490
|
+
paymasterToken: {
|
|
491
|
+
address: 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf',
|
|
492
|
+
},
|
|
493
|
+
};
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Complete Configuration Example
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { WalletProvider } from '@tetherto/wdk-react-native-provider';
|
|
500
|
+
|
|
501
|
+
const chains = {
|
|
502
|
+
ethereum: {
|
|
503
|
+
chainId: 1,
|
|
504
|
+
blockchain: 'ethereum',
|
|
505
|
+
provider: 'https://mainnet.gateway.tenderly.co/YOUR_KEY',
|
|
506
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
507
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
|
|
508
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
509
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
510
|
+
transferMaxFee: 5000000,
|
|
511
|
+
swapMaxFee: 5000000,
|
|
512
|
+
bridgeMaxFee: 5000000,
|
|
513
|
+
paymasterToken: {
|
|
514
|
+
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
polygon: {
|
|
518
|
+
chainId: 137,
|
|
519
|
+
blockchain: 'polygon',
|
|
520
|
+
provider: 'https://polygon.gateway.tenderly.co/YOUR_KEY',
|
|
521
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/polygon',
|
|
522
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/polygon',
|
|
523
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
524
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
525
|
+
transferMaxFee: 5000000,
|
|
526
|
+
swapMaxFee: 5000000,
|
|
527
|
+
bridgeMaxFee: 5000000,
|
|
528
|
+
paymasterToken: {
|
|
529
|
+
address: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f',
|
|
530
|
+
},
|
|
531
|
+
safeModulesVersion: '0.3.0',
|
|
532
|
+
},
|
|
533
|
+
arbitrum: {
|
|
534
|
+
chainId: 42161,
|
|
535
|
+
blockchain: 'arbitrum',
|
|
536
|
+
provider: 'https://arbitrum.gateway.tenderly.co/YOUR_KEY',
|
|
537
|
+
bundlerUrl: 'https://api.candide.dev/public/v3/arbitrum',
|
|
538
|
+
paymasterUrl: 'https://api.candide.dev/public/v3/arbitrum',
|
|
539
|
+
paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
|
|
540
|
+
entrypointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
541
|
+
transferMaxFee: 5000000,
|
|
542
|
+
swapMaxFee: 5000000,
|
|
543
|
+
bridgeMaxFee: 5000000,
|
|
544
|
+
paymasterToken: {
|
|
545
|
+
address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
ton: {
|
|
549
|
+
tonApiClient: {
|
|
550
|
+
url: 'https://tonapi.io',
|
|
551
|
+
},
|
|
552
|
+
tonClient: {
|
|
553
|
+
url: 'https://toncenter.com/api/v2/jsonRPC',
|
|
554
|
+
},
|
|
555
|
+
paymasterToken: {
|
|
556
|
+
address: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
|
|
557
|
+
},
|
|
558
|
+
transferMaxFee: 1000000000,
|
|
559
|
+
},
|
|
560
|
+
bitcoin: {
|
|
561
|
+
host: 'api.ordimint.com',
|
|
562
|
+
port: 50001,
|
|
563
|
+
},
|
|
564
|
+
tron: {
|
|
565
|
+
chainId: 3448148188,
|
|
566
|
+
provider: 'https://trongrid.io',
|
|
567
|
+
gasFreeProvider: 'https://gasfree.io',
|
|
568
|
+
apiKey: 'your-api-key',
|
|
569
|
+
apiSecret: 'your-api-secret',
|
|
570
|
+
serviceProvider: 'TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E',
|
|
571
|
+
verifyingContract: 'THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc',
|
|
572
|
+
transferMaxFee: 10000000,
|
|
573
|
+
swapMaxFee: 1000000,
|
|
574
|
+
bridgeMaxFee: 1000000,
|
|
575
|
+
paymasterToken: {
|
|
576
|
+
address: 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf',
|
|
577
|
+
},
|
|
578
|
+
},
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
function App() {
|
|
582
|
+
return (
|
|
583
|
+
<WalletProvider
|
|
584
|
+
config={{
|
|
585
|
+
indexer: {
|
|
586
|
+
apiKey: 'your-indexer-api-key',
|
|
587
|
+
url: 'https://your-indexer-url.com',
|
|
588
|
+
},
|
|
589
|
+
chains,
|
|
590
|
+
enableCaching: true, // Optional: enable caching for better performance
|
|
591
|
+
}}
|
|
592
|
+
>
|
|
593
|
+
<YourApp />
|
|
594
|
+
</WalletProvider>
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Advanced Usage
|
|
600
|
+
|
|
601
|
+
### Accessing Balances and Transactions
|
|
602
|
+
|
|
603
|
+
```tsx
|
|
604
|
+
const { wallet, addresses, balances, transactions } = useWallet();
|
|
605
|
+
|
|
606
|
+
if (wallet) {
|
|
607
|
+
// Addresses
|
|
608
|
+
if (addresses) {
|
|
609
|
+
Object.entries(addresses).forEach(([ticker, addressList]) => {
|
|
610
|
+
console.log(`${ticker}: ${addressList[0]?.value}`);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Balances - available as both list and map
|
|
615
|
+
balances.list.forEach(balance => {
|
|
616
|
+
console.log(`${balance.denomination}: ${balance.value}`);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// Or access by ticker from the map
|
|
620
|
+
const usdtBalance = balances.map.USDT?.[0];
|
|
621
|
+
console.log('USDT Balance:', usdtBalance?.value);
|
|
622
|
+
|
|
623
|
+
// Check loading state
|
|
624
|
+
if (balances.isLoading) {
|
|
625
|
+
console.log('Loading balances...');
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Transactions - available as both list and map
|
|
629
|
+
transactions.list.forEach(tx => {
|
|
630
|
+
console.log('Transaction:', tx);
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// Or access by ticker from the map
|
|
634
|
+
const usdtTransactions = transactions.map.USDT;
|
|
635
|
+
console.log('USDT Transactions:', usdtTransactions);
|
|
636
|
+
|
|
637
|
+
// Check loading state
|
|
638
|
+
if (transactions.isLoading) {
|
|
639
|
+
console.log('Loading transactions...');
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### Network Types
|
|
645
|
+
|
|
646
|
+
```typescript
|
|
647
|
+
import { NetworkType } from '@tetherto/wdk-react-native-provider';
|
|
648
|
+
|
|
649
|
+
// Available networks:
|
|
650
|
+
NetworkType.SEGWIT // Bitcoin
|
|
651
|
+
NetworkType.ETHEREUM // Ethereum
|
|
652
|
+
NetworkType.POLYGON // Polygon
|
|
653
|
+
NetworkType.ARBITRUM // Arbitrum
|
|
654
|
+
NetworkType.TON // TON
|
|
655
|
+
NetworkType.SOLANA // Solana
|
|
656
|
+
NetworkType.TRON // Tron
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### Asset Tickers
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
import { AssetTicker } from '@tetherto/wdk-react-native-provider';
|
|
663
|
+
|
|
664
|
+
// Available assets:
|
|
665
|
+
AssetTicker.BTC // Bitcoin
|
|
666
|
+
AssetTicker.USDT // Tether USD
|
|
667
|
+
AssetTicker.XAUT // Tether Gold
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
## TypeScript Support
|
|
671
|
+
|
|
672
|
+
This library is written in TypeScript and includes complete type definitions. Import types as needed:
|
|
673
|
+
|
|
674
|
+
```typescript
|
|
675
|
+
import type {
|
|
676
|
+
// Provider configuration
|
|
677
|
+
WalletProviderConfig,
|
|
678
|
+
|
|
679
|
+
// Wallet types
|
|
680
|
+
Amount,
|
|
681
|
+
Transaction,
|
|
682
|
+
Wallet,
|
|
683
|
+
|
|
684
|
+
// Enums (also available as values)
|
|
685
|
+
AssetTicker,
|
|
686
|
+
NetworkType,
|
|
687
|
+
} from '@tetherto/wdk-react-native-provider';
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
**Note:** Chain configuration types (`ChainsConfig`, `EVMChainConfig`, `TONChainConfig`, etc.) are defined in the underlying `@spacesops/pear-wrk-wdk` package. TypeScript will infer these types when you use them in the `WalletProviderConfig`, so explicit imports are typically not needed.
|
|
691
|
+
|
|
692
|
+
## Security Considerations
|
|
693
|
+
|
|
694
|
+
- **Seed Phrase Storage**: Seed phrases are encrypted and stored securely using device-specific encryption
|
|
695
|
+
- **Passkey/PRF**: Uses device unique ID by default. In production, integrate with biometric authentication
|
|
696
|
+
- **Never Log Seeds**: Never log or display seed phrases in production code
|
|
697
|
+
- **Secure Communication**: All API calls use HTTPS and require API keys
|
|
698
|
+
|
|
699
|
+
## Development
|
|
700
|
+
|
|
701
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development workflow and guidelines.
|
|
702
|
+
|
|
703
|
+
### Build
|
|
704
|
+
|
|
705
|
+
```sh
|
|
706
|
+
npm run prepare
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Type Check
|
|
710
|
+
|
|
711
|
+
```sh
|
|
712
|
+
npm run typecheck
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### Lint
|
|
716
|
+
|
|
717
|
+
```sh
|
|
718
|
+
npm run lint
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### Test
|
|
722
|
+
|
|
723
|
+
```sh
|
|
724
|
+
npm test
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
## Troubleshooting
|
|
728
|
+
|
|
729
|
+
### Setup Checklist
|
|
730
|
+
|
|
731
|
+
If you're experiencing issues, verify you've completed all setup steps:
|
|
732
|
+
|
|
733
|
+
**For Expo projects:**
|
|
734
|
+
|
|
735
|
+
1. ✅ Install the package: `npm install @tetherto/wdk-react-native-provider`
|
|
736
|
+
2. ✅ Install all peer dependencies (see [Peer Dependencies](#peer-dependencies))
|
|
737
|
+
3. ✅ Configure Android minSdkVersion to 29 in `app.json`:
|
|
738
|
+
```json
|
|
739
|
+
{
|
|
740
|
+
"expo": {
|
|
741
|
+
"plugins": [
|
|
742
|
+
["expo-build-properties", { "android": { "minSdkVersion": 29 } }]
|
|
743
|
+
]
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
```
|
|
747
|
+
4. ✅ Configure Metro polyfills in `metro.config.js`:
|
|
748
|
+
```js
|
|
749
|
+
const { configureMetroForWDK } = require('@tetherto/wdk-react-native-provider/metro-polyfills');
|
|
750
|
+
const config = getDefaultConfig(__dirname);
|
|
751
|
+
const configWdk = configureMetroForWDK(config);
|
|
752
|
+
module.exports = configWdk;
|
|
753
|
+
```
|
|
754
|
+
5. ✅ Add `WalletProvider` to `app/_layout.tsx` with proper config
|
|
755
|
+
6. ✅ Use `useWallet()` hook in your components
|
|
756
|
+
7. ✅ Check `isInitialized` before creating wallets
|
|
757
|
+
|
|
758
|
+
**For bare React Native projects:**
|
|
759
|
+
|
|
760
|
+
1. ✅ Install the package and peer dependencies
|
|
761
|
+
2. ✅ Set minSdkVersion to 29 in `android/build.gradle`
|
|
762
|
+
3. ✅ Configure Metro polyfills in `metro.config.js`
|
|
763
|
+
4. ✅ Wrap your root component with `WalletProvider`
|
|
764
|
+
5. ✅ Rebuild native code: `npx react-native run-android` or `npx react-native run-ios`
|
|
765
|
+
|
|
766
|
+
### "WDK Manager not initialized"
|
|
767
|
+
|
|
768
|
+
The WDK service is initialized automatically when the `WalletProvider` mounts. If you see this error, ensure:
|
|
769
|
+
|
|
770
|
+
1. Your component is wrapped with `WalletProvider`
|
|
771
|
+
2. The provider's config is properly set
|
|
772
|
+
3. You're checking `isInitialized` before performing wallet operations:
|
|
773
|
+
|
|
774
|
+
```tsx
|
|
775
|
+
const { isInitialized, createWallet } = useWallet();
|
|
776
|
+
|
|
777
|
+
if (isInitialized) {
|
|
778
|
+
await createWallet({ name: 'My Wallet' });
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### "No wallet found"
|
|
783
|
+
|
|
784
|
+
Ensure a wallet has been created or imported before attempting transactions:
|
|
785
|
+
|
|
786
|
+
```tsx
|
|
787
|
+
const { wallet, createWallet } = useWallet();
|
|
788
|
+
if (!wallet) {
|
|
789
|
+
await createWallet({ name: 'My Wallet' });
|
|
790
|
+
}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### Metro bundler errors or "Unable to resolve module"
|
|
794
|
+
|
|
795
|
+
If you see errors like `Unable to resolve "stream"` or other Node.js core modules:
|
|
796
|
+
|
|
797
|
+
1. Ensure you've configured Metro polyfills correctly (see [Metro Configuration](#metro-configuration))
|
|
798
|
+
2. Clear Metro cache: `npx expo start --clear` or `npx react-native start --reset-cache`
|
|
799
|
+
3. Delete `node_modules` and reinstall: `rm -rf node_modules && npm install`
|
|
800
|
+
4. For Expo: Run prebuild if using custom native modules: `npx expo prebuild --clean`
|
|
801
|
+
|
|
802
|
+
### Android build fails with "Execution failed for task ':app:checkDebugAarMetadata'"
|
|
803
|
+
|
|
804
|
+
This usually means minSdkVersion is too low. Ensure you've set minSdkVersion to 29:
|
|
805
|
+
|
|
806
|
+
**For Expo:**
|
|
807
|
+
```json
|
|
808
|
+
{
|
|
809
|
+
"expo": {
|
|
810
|
+
"plugins": [
|
|
811
|
+
["expo-build-properties", { "android": { "minSdkVersion": 29 } }]
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Then rebuild: `npx expo run:android` or `npx expo prebuild --clean && npx expo run:android`
|
|
818
|
+
|
|
819
|
+
### TypeScript errors about missing types
|
|
820
|
+
|
|
821
|
+
Some peer dependencies may not have type definitions. You can ignore these by adding to your `tsconfig.json`:
|
|
822
|
+
|
|
823
|
+
```json
|
|
824
|
+
{
|
|
825
|
+
"compilerOptions": {
|
|
826
|
+
"skipLibCheck": true
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
## Contributing
|
|
832
|
+
|
|
833
|
+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
834
|
+
|
|
835
|
+
## License
|
|
836
|
+
|
|
837
|
+
Apache-2.0
|
|
838
|
+
|
|
839
|
+
---
|
|
840
|
+
|
|
841
|
+
Made with ❤️ by [Tether](https://tether.to)
|