@tari-project/tarijs 0.10.1 → 0.12.0
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 +127 -67
- package/TODO.md +91 -3
- package/docusaurus/tari-docs/README.md +200 -17
- package/docusaurus/tari-docs/docs/api-reference.md +665 -0
- package/docusaurus/tari-docs/docs/contributing.md +619 -0
- package/docusaurus/tari-docs/docs/guides/getting-started-tutorial.md +965 -0
- package/docusaurus/tari-docs/docs/guides/production-deployment.md +977 -0
- package/docusaurus/tari-docs/docs/index.md +114 -11
- package/docusaurus/tari-docs/docs/installation.md +142 -1
- package/docusaurus/tari-docs/docs/signers/metamask.md +529 -0
- package/docusaurus/tari-docs/docs/troubleshooting.md +661 -0
- package/docusaurus/tari-docs/package.json +4 -4
- package/eslint.config.mjs +9 -0
- package/examples/vite-typescript-react/README.md +9 -0
- package/examples/vite-typescript-react/eslint.config.js +23 -0
- package/examples/vite-typescript-react/index.html +13 -0
- package/examples/vite-typescript-react/package.json +35 -0
- package/examples/vite-typescript-react/public/vite.svg +1 -0
- package/examples/vite-typescript-react/src/App.css +42 -0
- package/examples/vite-typescript-react/src/App.tsx +50 -0
- package/examples/vite-typescript-react/src/assets/react.svg +1 -0
- package/examples/vite-typescript-react/src/index.css +68 -0
- package/examples/vite-typescript-react/src/main.tsx +10 -0
- package/examples/vite-typescript-react/src/vite-env.d.ts +1 -0
- package/examples/vite-typescript-react/tsconfig.app.json +27 -0
- package/examples/vite-typescript-react/tsconfig.json +7 -0
- package/examples/vite-typescript-react/tsconfig.node.json +25 -0
- package/examples/vite-typescript-react/vite.config.ts +7 -0
- package/package.json +16 -3
- package/packages/builders/package.json +2 -2
- package/packages/builders/src/helpers/submitTransaction.ts +10 -35
- package/packages/builders/src/transaction/TransactionBuilder.ts +227 -29
- package/packages/indexer_provider/package.json +2 -2
- package/packages/indexer_provider/src/provider.ts +5 -5
- package/packages/indexer_provider/tsconfig.json +4 -2
- package/packages/metamask_signer/package.json +2 -2
- package/packages/metamask_signer/src/index.ts +3 -15
- package/packages/{tari_permissions → permissions}/package.json +2 -2
- package/packages/{tari_permissions → permissions}/src/helpers.ts +1 -1
- package/packages/permissions/src/index.ts +2 -0
- package/packages/{tari_permissions/src/tari_permissions.ts → permissions/src/permissions.ts} +56 -6
- package/packages/react-mui-connect-button/moon.yml +71 -0
- package/packages/react-mui-connect-button/package.json +40 -0
- package/packages/react-mui-connect-button/src/Logos.tsx +60 -0
- package/packages/react-mui-connect-button/src/TariConnectButton.tsx +51 -0
- package/packages/react-mui-connect-button/src/TariWalletSelectionDialog.tsx +116 -0
- package/packages/react-mui-connect-button/src/content/tari-logo-white.svg +18 -0
- package/packages/react-mui-connect-button/src/content/tari-logo.svg +18 -0
- package/packages/react-mui-connect-button/src/content/walletconnect-logo.svg +13 -0
- package/packages/react-mui-connect-button/src/defaultPermissions.ts +0 -0
- package/packages/react-mui-connect-button/src/index.ts +24 -0
- package/packages/react-mui-connect-button/tsconfig.json +31 -0
- package/packages/tari_provider/package.json +2 -2
- package/packages/tari_provider/src/TariProvider.ts +6 -1
- package/packages/tari_signer/package.json +2 -2
- package/packages/tari_universe/package.json +2 -2
- package/packages/tari_universe/tsconfig.json +4 -2
- package/packages/tarijs/package.json +2 -2
- package/packages/tarijs/src/index.ts +27 -49
- package/packages/tarijs/src/templates/Account.ts +7 -4
- package/packages/tarijs/test/integration-tests/.env +1 -1
- package/packages/tarijs/test/integration-tests/wallet_daemon/json_rpc_provider.spec.ts +112 -73
- package/packages/tarijs/tsconfig.json +6 -4
- package/packages/tarijs/vitest.config.ts +2 -1
- package/packages/tarijs_types/package.json +4 -3
- package/packages/tarijs_types/src/Account.ts +68 -0
- package/packages/tarijs_types/src/Amount.ts +5 -1
- package/packages/tarijs_types/src/TransactionResult.ts +1 -8
- package/packages/tarijs_types/src/consts.ts +3 -0
- package/packages/tarijs_types/src/helpers/index.ts +4 -0
- package/packages/tarijs_types/src/helpers/simpleResult.ts +345 -0
- package/packages/tarijs_types/src/helpers/txResult.ts +1 -2
- package/packages/tarijs_types/src/index.ts +8 -0
- package/packages/tarijs_types/src/signer.ts +1 -1
- package/packages/wallet_daemon/package.json +2 -2
- package/packages/wallet_daemon/src/provider.ts +8 -6
- package/packages/wallet_daemon/src/signer.ts +18 -8
- package/packages/wallet_daemon/tsconfig.json +1 -1
- package/packages/walletconnect/package.json +3 -2
- package/packages/walletconnect/src/index.ts +54 -28
- package/packages/walletconnect/tsconfig.json +3 -0
- package/pnpm-workspace.yaml +15 -7
- package/scripts/check_versions.sh +4 -0
- package/scripts/clean_everything.sh +38 -0
- package/tsconfig.json +6 -0
- package/typedoc.json +10 -0
- package/packages/tari_permissions/src/index.ts +0 -2
- /package/packages/{tari_permissions → permissions}/moon.yml +0 -0
- /package/packages/{tari_permissions → permissions}/tsconfig.json +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 4
|
|
3
|
+
title: MetaMask Integration
|
|
4
|
+
description: Connect to MetaMask with the Tari snap for seamless browser-based wallet integration
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MetaMask Signer Integration 🦊
|
|
8
|
+
|
|
9
|
+
> **Browser-native wallet experience** — Connect your web apps to MetaMask using the Tari snap for familiar, secure wallet interactions.
|
|
10
|
+
|
|
11
|
+
The MetaMask signer enables your dApps to integrate with MetaMask through the official **Tari snap**, providing users with a familiar wallet experience while accessing Tari's advanced privacy features.
|
|
12
|
+
|
|
13
|
+
## ✨ **Why Choose MetaMask?**
|
|
14
|
+
|
|
15
|
+
- **🔒 Familiar Security** — Users trust MetaMask's proven security model
|
|
16
|
+
- **🌐 Browser Native** — No additional software installation required
|
|
17
|
+
- **📱 Mobile Ready** — Works on MetaMask mobile app
|
|
18
|
+
- **🔗 Easy Integration** — Simple API for web developers
|
|
19
|
+
- **🛡️ Privacy Enabled** — Full access to Tari's confidential transactions
|
|
20
|
+
|
|
21
|
+
## 🚀 **Quick Start**
|
|
22
|
+
|
|
23
|
+
### **Prerequisites**
|
|
24
|
+
|
|
25
|
+
Before using the MetaMask signer, ensure:
|
|
26
|
+
|
|
27
|
+
- **MetaMask Flask** installed (developer version required for snaps)
|
|
28
|
+
- **Tari snap** installed in MetaMask
|
|
29
|
+
- **Modern browser** with MetaMask extension support
|
|
30
|
+
|
|
31
|
+
:::tip Install MetaMask Flask
|
|
32
|
+
Regular MetaMask doesn't support snaps yet. Download [MetaMask Flask](https://metamask.io/flask/) for snap functionality.
|
|
33
|
+
:::
|
|
34
|
+
|
|
35
|
+
### **Installation**
|
|
36
|
+
|
|
37
|
+
```bash npm2yarn
|
|
38
|
+
npm install @tari-project/tarijs @tari-project/metamask-signer
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### **Basic Connection**
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { MetaMaskSigner } from '@tari-project/metamask-signer';
|
|
45
|
+
|
|
46
|
+
// Check if MetaMask is available
|
|
47
|
+
if (typeof window.ethereum === 'undefined') {
|
|
48
|
+
throw new Error('MetaMask not installed. Please install MetaMask Flask.');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Create signer instance
|
|
52
|
+
const signer = new MetaMaskSigner();
|
|
53
|
+
|
|
54
|
+
// Connect to MetaMask (will prompt for snap installation)
|
|
55
|
+
await signer.connect();
|
|
56
|
+
|
|
57
|
+
// Verify connection
|
|
58
|
+
if (signer.isConnected()) {
|
|
59
|
+
console.log('✅ Connected to MetaMask with Tari snap!');
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 🔧 **Configuration Options**
|
|
64
|
+
|
|
65
|
+
### **Advanced Configuration**
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { MetaMaskSigner } from '@tari-project/metamask-signer';
|
|
69
|
+
|
|
70
|
+
const signer = new MetaMaskSigner({
|
|
71
|
+
// Snap configuration
|
|
72
|
+
snapId: 'npm:@tari-project/wallet-snap', // Default snap ID
|
|
73
|
+
snapVersion: '^0.1.0', // Snap version to install
|
|
74
|
+
|
|
75
|
+
// Connection options
|
|
76
|
+
autoInstallSnap: true, // Auto-install snap if not present
|
|
77
|
+
timeout: 30000, // Connection timeout (30 seconds)
|
|
78
|
+
|
|
79
|
+
// Network configuration
|
|
80
|
+
network: 'testnet', // 'mainnet' | 'testnet' | 'localnet'
|
|
81
|
+
|
|
82
|
+
// UI preferences
|
|
83
|
+
showInstallPrompt: true, // Show snap installation UI
|
|
84
|
+
theme: 'auto' // 'light' | 'dark' | 'auto'
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 🔌 **Connection Management**
|
|
89
|
+
|
|
90
|
+
### **Automatic Snap Installation**
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
async function connectWithSnapInstall() {
|
|
94
|
+
try {
|
|
95
|
+
const signer = new MetaMaskSigner({
|
|
96
|
+
autoInstallSnap: true,
|
|
97
|
+
showInstallPrompt: true
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// This will automatically install the snap if needed
|
|
101
|
+
await signer.connect();
|
|
102
|
+
|
|
103
|
+
console.log('Snap installed and connected!');
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error.code === 'SNAP_INSTALLATION_REJECTED') {
|
|
106
|
+
console.log('User rejected snap installation');
|
|
107
|
+
} else {
|
|
108
|
+
console.error('Connection failed:', error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### **Manual Snap Installation**
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
async function manualSnapInstall() {
|
|
118
|
+
// Request snap installation explicitly
|
|
119
|
+
const snapId = 'npm:@tari-project/wallet-snap';
|
|
120
|
+
|
|
121
|
+
await window.ethereum.request({
|
|
122
|
+
method: 'wallet_requestSnaps',
|
|
123
|
+
params: {
|
|
124
|
+
[snapId]: {}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Now connect with the signer
|
|
129
|
+
const signer = new MetaMaskSigner();
|
|
130
|
+
await signer.connect();
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### **Connection Status Checking**
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Check if MetaMask is available
|
|
138
|
+
function isMetaMaskAvailable(): boolean {
|
|
139
|
+
return typeof window.ethereum !== 'undefined';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check if Tari snap is installed
|
|
143
|
+
async function isSnapInstalled(): Promise<boolean> {
|
|
144
|
+
try {
|
|
145
|
+
const snaps = await window.ethereum.request({
|
|
146
|
+
method: 'wallet_getSnaps'
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return 'npm:@tari-project/wallet-snap' in snaps;
|
|
150
|
+
} catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Full connection check
|
|
156
|
+
async function checkConnection() {
|
|
157
|
+
if (!isMetaMaskAvailable()) {
|
|
158
|
+
throw new Error('MetaMask not available');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!(await isSnapInstalled())) {
|
|
162
|
+
throw new Error('Tari snap not installed');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const signer = new MetaMaskSigner();
|
|
166
|
+
return signer.isConnected();
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 💼 **Account Management**
|
|
171
|
+
|
|
172
|
+
### **Getting Accounts**
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Get all available accounts
|
|
176
|
+
const accounts = await signer.getAccounts();
|
|
177
|
+
console.log('Available accounts:', accounts);
|
|
178
|
+
|
|
179
|
+
// Get default account
|
|
180
|
+
const defaultAccount = await signer.getDefaultAccount();
|
|
181
|
+
console.log('Default account:', defaultAccount.address);
|
|
182
|
+
|
|
183
|
+
// Get account balance
|
|
184
|
+
const balance = await signer.getBalance(defaultAccount);
|
|
185
|
+
console.log('Balance:', balance, 'Tari');
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### **Account Information**
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Get detailed account info
|
|
192
|
+
const accountInfo = await signer.getAccountInfo(defaultAccount);
|
|
193
|
+
|
|
194
|
+
console.log('Account Details:', {
|
|
195
|
+
address: accountInfo.address,
|
|
196
|
+
publicKey: accountInfo.publicKey,
|
|
197
|
+
balance: accountInfo.balance,
|
|
198
|
+
network: accountInfo.network
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 💸 **Transaction Operations**
|
|
203
|
+
|
|
204
|
+
### **Simple Transfer**
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { TransactionBuilder } from '@tari-project/tarijs';
|
|
208
|
+
|
|
209
|
+
async function sendTransfer() {
|
|
210
|
+
const defaultAccount = await signer.getDefaultAccount();
|
|
211
|
+
|
|
212
|
+
// Build transaction
|
|
213
|
+
const transaction = new TransactionBuilder()
|
|
214
|
+
.fee(100)
|
|
215
|
+
.callMethod(defaultAccount.address, 'transfer', {
|
|
216
|
+
amount: 1000,
|
|
217
|
+
destination: 'account_recipient_address_here'
|
|
218
|
+
})
|
|
219
|
+
.build();
|
|
220
|
+
|
|
221
|
+
// Submit transaction (will prompt MetaMask for approval)
|
|
222
|
+
const result = await signer.submitTransaction({ transaction });
|
|
223
|
+
|
|
224
|
+
console.log('Transaction submitted:', result.transactionId);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### **Transaction with User Confirmation**
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
async function transferWithConfirmation() {
|
|
233
|
+
try {
|
|
234
|
+
// Show transaction preview to user
|
|
235
|
+
const transactionPreview = {
|
|
236
|
+
type: 'Transfer',
|
|
237
|
+
amount: '1000 Tari',
|
|
238
|
+
recipient: 'account_recipient...',
|
|
239
|
+
fee: '100 Tari'
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// User confirms in your UI
|
|
243
|
+
const userConfirmed = await showTransactionModal(transactionPreview);
|
|
244
|
+
if (!userConfirmed) return;
|
|
245
|
+
|
|
246
|
+
// Build and submit transaction
|
|
247
|
+
const transaction = new TransactionBuilder()
|
|
248
|
+
.fee(100)
|
|
249
|
+
.callMethod(account.address, 'transfer', {
|
|
250
|
+
amount: 1000,
|
|
251
|
+
destination: recipient
|
|
252
|
+
})
|
|
253
|
+
.build();
|
|
254
|
+
|
|
255
|
+
// MetaMask will show its own confirmation
|
|
256
|
+
const result = await signer.submitTransaction({ transaction });
|
|
257
|
+
|
|
258
|
+
// Show success message
|
|
259
|
+
showSuccessMessage(`Transaction sent: ${result.transactionId}`);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (error.code === 'USER_REJECTED') {
|
|
262
|
+
console.log('User rejected transaction');
|
|
263
|
+
} else {
|
|
264
|
+
console.error('Transaction failed:', error);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 🔒 **Permission Management**
|
|
271
|
+
|
|
272
|
+
### **Request Permissions**
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// Request specific permissions
|
|
276
|
+
const permissions = await signer.requestPermissions([
|
|
277
|
+
'accounts:read',
|
|
278
|
+
'transactions:submit',
|
|
279
|
+
'substates:read'
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
console.log('Granted permissions:', permissions);
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### **Check Permissions**
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
// Check current permissions
|
|
289
|
+
const currentPermissions = await signer.getPermissions();
|
|
290
|
+
|
|
291
|
+
if (currentPermissions.includes('transactions:submit')) {
|
|
292
|
+
console.log('Can submit transactions');
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## 🎨 **User Experience**
|
|
297
|
+
|
|
298
|
+
### **React Integration**
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
import React, { useState, useEffect } from 'react';
|
|
302
|
+
import { MetaMaskSigner } from '@tari-project/metamask-signer';
|
|
303
|
+
|
|
304
|
+
export function MetaMaskConnector() {
|
|
305
|
+
const [signer, setSigner] = useState<MetaMaskSigner | null>(null);
|
|
306
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
307
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
308
|
+
|
|
309
|
+
const connectWallet = async () => {
|
|
310
|
+
setIsConnecting(true);
|
|
311
|
+
|
|
312
|
+
try {
|
|
313
|
+
if (typeof window.ethereum === 'undefined') {
|
|
314
|
+
alert('Please install MetaMask Flask to continue');
|
|
315
|
+
window.open('https://metamask.io/flask/', '_blank');
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const metaMaskSigner = new MetaMaskSigner({
|
|
320
|
+
autoInstallSnap: true,
|
|
321
|
+
showInstallPrompt: true
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
await metaMaskSigner.connect();
|
|
325
|
+
|
|
326
|
+
setSigner(metaMaskSigner);
|
|
327
|
+
setIsConnected(true);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
console.error('Failed to connect:', error);
|
|
330
|
+
alert('Failed to connect to MetaMask. Please try again.');
|
|
331
|
+
} finally {
|
|
332
|
+
setIsConnecting(false);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const disconnect = async () => {
|
|
337
|
+
if (signer) {
|
|
338
|
+
await signer.disconnect();
|
|
339
|
+
setSigner(null);
|
|
340
|
+
setIsConnected(false);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
if (isConnected && signer) {
|
|
345
|
+
return (
|
|
346
|
+
<div className="wallet-connected">
|
|
347
|
+
<p>✅ Connected to MetaMask</p>
|
|
348
|
+
<button onClick={disconnect}>Disconnect</button>
|
|
349
|
+
</div>
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return (
|
|
354
|
+
<div className="wallet-connector">
|
|
355
|
+
<h3>Connect Your Wallet</h3>
|
|
356
|
+
<button
|
|
357
|
+
onClick={connectWallet}
|
|
358
|
+
disabled={isConnecting}
|
|
359
|
+
className="metamask-connect-btn"
|
|
360
|
+
>
|
|
361
|
+
{isConnecting ? '🔄 Connecting...' : '🦊 Connect MetaMask'}
|
|
362
|
+
</button>
|
|
363
|
+
|
|
364
|
+
{typeof window.ethereum === 'undefined' && (
|
|
365
|
+
<p className="install-prompt">
|
|
366
|
+
<a href="https://metamask.io/flask/" target="_blank" rel="noopener">
|
|
367
|
+
Install MetaMask Flask →
|
|
368
|
+
</a>
|
|
369
|
+
</p>
|
|
370
|
+
)}
|
|
371
|
+
</div>
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### **Error Handling**
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
async function robustMetaMaskConnection() {
|
|
380
|
+
try {
|
|
381
|
+
await signer.connect();
|
|
382
|
+
} catch (error) {
|
|
383
|
+
switch (error.code) {
|
|
384
|
+
case 'METAMASK_NOT_INSTALLED':
|
|
385
|
+
showError('Please install MetaMask Flask', {
|
|
386
|
+
action: 'Install',
|
|
387
|
+
url: 'https://metamask.io/flask/'
|
|
388
|
+
});
|
|
389
|
+
break;
|
|
390
|
+
|
|
391
|
+
case 'SNAP_INSTALLATION_REJECTED':
|
|
392
|
+
showError('Tari snap installation was rejected. Please try again.');
|
|
393
|
+
break;
|
|
394
|
+
|
|
395
|
+
case 'USER_REJECTED':
|
|
396
|
+
showError('Connection was rejected. Please accept to continue.');
|
|
397
|
+
break;
|
|
398
|
+
|
|
399
|
+
case 'SNAP_NOT_FOUND':
|
|
400
|
+
showError('Tari snap not found. Please install it first.');
|
|
401
|
+
break;
|
|
402
|
+
|
|
403
|
+
default:
|
|
404
|
+
showError(`Connection failed: ${error.message}`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## 🔧 **Troubleshooting**
|
|
411
|
+
|
|
412
|
+
### **Common Issues**
|
|
413
|
+
|
|
414
|
+
#### ❌ **"Snap not found" error**
|
|
415
|
+
```typescript
|
|
416
|
+
// Solution: Ensure snap is installed
|
|
417
|
+
await window.ethereum.request({
|
|
418
|
+
method: 'wallet_requestSnaps',
|
|
419
|
+
params: {
|
|
420
|
+
'npm:@tari-project/wallet-snap': {}
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
#### ❌ **"MetaMask not detected"**
|
|
426
|
+
```typescript
|
|
427
|
+
// Solution: Check installation and provide guidance
|
|
428
|
+
if (typeof window.ethereum === 'undefined') {
|
|
429
|
+
console.error('MetaMask not installed');
|
|
430
|
+
// Guide user to install MetaMask Flask
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### ❌ **Connection timeout**
|
|
435
|
+
```typescript
|
|
436
|
+
// Solution: Increase timeout and add retry logic
|
|
437
|
+
const signer = new MetaMaskSigner({
|
|
438
|
+
timeout: 60000, // 60 seconds
|
|
439
|
+
retryAttempts: 3
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### **Debug Mode**
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
// Enable debug logging
|
|
447
|
+
const signer = new MetaMaskSigner({
|
|
448
|
+
debug: true // Enables detailed logging
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Check snap status
|
|
452
|
+
const snapStatus = await signer.getSnapStatus();
|
|
453
|
+
console.log('Snap status:', snapStatus);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## 🚀 **Advanced Features**
|
|
457
|
+
|
|
458
|
+
### **Batch Transactions**
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
// Submit multiple transactions as a batch
|
|
462
|
+
const batch = new TransactionBuilder()
|
|
463
|
+
.fee(200) // Higher fee for batch
|
|
464
|
+
.callMethod(account, 'transfer', { amount: 500, destination: addr1 })
|
|
465
|
+
.callMethod(account, 'transfer', { amount: 300, destination: addr2 })
|
|
466
|
+
.build();
|
|
467
|
+
|
|
468
|
+
const result = await signer.submitTransaction({ transaction: batch });
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### **Confidential Transactions**
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
// Create privacy-preserving transaction
|
|
475
|
+
const confidentialTx = new TransactionBuilder()
|
|
476
|
+
.fee(150)
|
|
477
|
+
.confidentialTransfer({
|
|
478
|
+
amount: 1000,
|
|
479
|
+
destination: recipientAddress,
|
|
480
|
+
blindingFactor: generateBlindingFactor()
|
|
481
|
+
})
|
|
482
|
+
.build();
|
|
483
|
+
|
|
484
|
+
const result = await signer.submitTransaction({
|
|
485
|
+
transaction: confidentialTx,
|
|
486
|
+
isConfidential: true
|
|
487
|
+
});
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## 📚 **Best Practices**
|
|
491
|
+
|
|
492
|
+
### **Security**
|
|
493
|
+
- ✅ Always validate user input before transactions
|
|
494
|
+
- ✅ Use HTTPS in production environments
|
|
495
|
+
- ✅ Implement proper error boundaries
|
|
496
|
+
- ✅ Never store private keys in your application
|
|
497
|
+
- ✅ Validate snap authenticity before installation
|
|
498
|
+
|
|
499
|
+
### **User Experience**
|
|
500
|
+
- ✅ Show clear installation instructions
|
|
501
|
+
- ✅ Provide feedback during connection process
|
|
502
|
+
- ✅ Handle all error states gracefully
|
|
503
|
+
- ✅ Offer alternative wallet options
|
|
504
|
+
- ✅ Cache connection state appropriately
|
|
505
|
+
|
|
506
|
+
### **Performance**
|
|
507
|
+
- ✅ Only connect when needed
|
|
508
|
+
- ✅ Reuse signer instances
|
|
509
|
+
- ✅ Implement connection pooling
|
|
510
|
+
- ✅ Handle network switching
|
|
511
|
+
- ✅ Optimize transaction batching
|
|
512
|
+
|
|
513
|
+
## 🔗 **Related Documentation**
|
|
514
|
+
|
|
515
|
+
- **[Installation Guide](../installation)** — Set up your development environment
|
|
516
|
+
- **[Transaction Builder](../wallet/submit-transaction/transaction-builder/)** — Create complex transactions
|
|
517
|
+
- **[Provider vs Signer](../provider-vs-signer)** — Understand the architecture
|
|
518
|
+
- **[Troubleshooting](../troubleshooting)** — Common issues and solutions
|
|
519
|
+
|
|
520
|
+
## 💬 **Need Help?**
|
|
521
|
+
|
|
522
|
+
- **🐛 [Report issues](https://github.com/tari-project/tari.js/issues)** — Bug reports and feature requests
|
|
523
|
+
- **💬 [Join Discord](https://discord.gg/tari)** — Real-time community support
|
|
524
|
+
- **📖 [API Reference](../api-reference)** — Complete method documentation
|
|
525
|
+
- **🦊 [MetaMask Docs](https://docs.metamask.io/snaps/)** — Official MetaMask snap documentation
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
**Ready to integrate MetaMask?** Start with our [Getting Started Tutorial](../guides/getting-started-tutorial) and add MetaMask support to your Tari application! 🚀
|