0
# Network Providers
1
2
Connection providers for different transport protocols and connection types. The @polkadot/api supports multiple provider implementations for connecting to blockchain nodes through various protocols.
3
4
## Capabilities
5
6
### WebSocket Provider
7
8
WebSocket-based provider for real-time bidirectional communication with blockchain nodes.
9
10
```typescript { .api }
11
class WsProvider implements ProviderInterface {
12
/**
13
* Create WebSocket provider
14
* @param endpoint - WebSocket endpoint URL or array of URLs
15
* @param autoConnectMs - Auto-connect delay in milliseconds or false to disable
16
* @param headers - Additional WebSocket headers
17
* @param timeout - Connection timeout in milliseconds
18
* @param cacheCapacity - RPC response cache capacity
19
* @param cacheTtl - Cache TTL in milliseconds or null to disable
20
*/
21
constructor(
22
endpoint?: string | string[],
23
autoConnectMs?: number | false,
24
headers?: Record<string, string>,
25
timeout?: number,
26
cacheCapacity?: number,
27
cacheTtl?: number | null
28
);
29
30
/**
31
* Connect to WebSocket endpoint
32
* @returns Promise resolving when connected
33
*/
34
connect(): Promise<void>;
35
36
/**
37
* Disconnect from WebSocket endpoint
38
* @returns Promise resolving when disconnected
39
*/
40
disconnect(): Promise<void>;
41
42
/**
43
* Check if provider is connected
44
*/
45
get isConnected(): boolean;
46
47
/**
48
* Send RPC request
49
* @param method - RPC method name
50
* @param params - Method parameters
51
* @param subscription - Subscription callback
52
* @returns Promise resolving to result
53
*/
54
send<T = any>(
55
method: string,
56
params: unknown[],
57
subscription?: ProviderInterfaceCallback
58
): Promise<T>;
59
60
/**
61
* Subscribe to provider events
62
* @param type - Event type
63
* @param callback - Event callback
64
* @returns Unsubscribe function
65
*/
66
on(type: ProviderInterfaceEmitType, callback: ProviderInterfaceEmitted): () => void;
67
68
/**
69
* Clone provider with same configuration
70
* @returns New WsProvider instance
71
*/
72
clone(): WsProvider;
73
74
/** Current endpoint URL */
75
readonly endpoint: string;
76
77
/** Connection timeout setting */
78
readonly timeout: number;
79
}
80
```
81
82
### HTTP Provider
83
84
HTTP-based provider for stateless request-response communication with blockchain nodes.
85
86
```typescript { .api }
87
class HttpProvider implements ProviderInterface {
88
/**
89
* Create HTTP provider
90
* @param endpoint - HTTP endpoint URL
91
* @param headers - Additional HTTP headers
92
* @param timeout - Request timeout in milliseconds
93
* @param cacheCapacity - RPC response cache capacity
94
*/
95
constructor(
96
endpoint?: string,
97
headers?: Record<string, string>,
98
timeout?: number,
99
cacheCapacity?: number
100
);
101
102
/**
103
* Connect (no-op for HTTP)
104
* @returns Promise resolving immediately
105
*/
106
connect(): Promise<void>;
107
108
/**
109
* Disconnect (no-op for HTTP)
110
* @returns Promise resolving immediately
111
*/
112
disconnect(): Promise<void>;
113
114
/**
115
* HTTP is always "connected"
116
*/
117
get isConnected(): boolean;
118
119
/**
120
* Send HTTP RPC request
121
* @param method - RPC method name
122
* @param params - Method parameters
123
* @returns Promise resolving to result
124
*/
125
send<T = any>(method: string, params: unknown[]): Promise<T>;
126
127
/**
128
* Subscribe to provider events
129
* @param type - Event type
130
* @param callback - Event callback
131
* @returns Unsubscribe function
132
*/
133
on(type: ProviderInterfaceEmitType, callback: ProviderInterfaceEmitted): () => void;
134
135
/**
136
* Clone provider with same configuration
137
* @returns New HttpProvider instance
138
*/
139
clone(): HttpProvider;
140
141
/** Current endpoint URL */
142
readonly endpoint: string;
143
144
/** Request timeout setting */
145
readonly timeout: number;
146
}
147
```
148
149
### Substrate Connect Provider
150
151
Light client provider using Substrate Connect for browser-based blockchain access.
152
153
```typescript { .api }
154
class ScProvider implements ProviderInterface {
155
/**
156
* Create Substrate Connect provider
157
* @param Sc - Substrate Connect interface with WellKnownChain and createScClient
158
* @param spec - Chain specification string or well-known chain name
159
* @param sharedSandbox - Optional shared ScProvider instance for sandbox mode
160
*/
161
constructor(
162
Sc: SubstrateConnect,
163
spec: string | WellKnownChain,
164
sharedSandbox?: ScProvider
165
);
166
167
/**
168
* Connect to light client
169
* @returns Promise resolving when connected
170
*/
171
connect(): Promise<void>;
172
173
/**
174
* Disconnect from light client
175
* @returns Promise resolving when disconnected
176
*/
177
disconnect(): Promise<void>;
178
179
/**
180
* Check if provider is connected
181
*/
182
get isConnected(): boolean;
183
184
/**
185
* Send RPC request through light client
186
* @param method - RPC method name
187
* @param params - Method parameters
188
* @param subscription - Subscription callback
189
* @returns Promise resolving to result
190
*/
191
send<T = any>(
192
method: string,
193
params: unknown[],
194
subscription?: ProviderInterfaceCallback
195
): Promise<T>;
196
197
/**
198
* Subscribe to provider events
199
* @param type - Event type
200
* @param callback - Event callback
201
* @returns Unsubscribe function
202
*/
203
on(type: ProviderInterfaceEmitType, callback: ProviderInterfaceEmitted): () => void;
204
205
/**
206
* Clone provider with same configuration
207
* @returns New ScProvider instance
208
*/
209
clone(): ScProvider;
210
211
/** Chain specification */
212
readonly spec: string | ChainSpec;
213
}
214
215
interface SubstrateConnect {
216
/** Well-known chain constants */
217
WellKnownChain: typeof WellKnownChain;
218
/** Create Substrate Connect client */
219
createScClient: (config?: any) => ScClient;
220
}
221
222
type WellKnownChain = string;
223
224
interface ScClient {
225
/** Add a well-known chain */
226
addWellKnownChain: (spec: WellKnownChain, onResponse: (response: string) => void) => Promise<Chain>;
227
/** Add a custom chain */
228
addChain: (spec: string, onResponse: (response: string) => void) => Promise<Chain>;
229
}
230
231
interface Chain {
232
/** Send JSON-RPC request */
233
sendJsonRpc: (request: string) => void;
234
/** Add a chain to existing client */
235
addChain: (spec: string, onResponse: (response: string) => void) => Promise<Chain>;
236
/** Remove the chain */
237
remove: () => void;
238
}
239
240
interface ScProviderConfig {
241
/** Light client configuration */
242
config?: any;
243
/** Database name */
244
database?: string;
245
}
246
247
interface ChainSpec {
248
/** Chain specification JSON */
249
chainSpec: string;
250
/** Optional database configuration */
251
database?: string;
252
}
253
```
254
255
### Keyring Management
256
257
Cryptographic key management for transaction signing.
258
259
```typescript { .api }
260
class Keyring {
261
/**
262
* Create keyring instance
263
* @param options - Keyring configuration options
264
*/
265
constructor(options?: KeyringOptions);
266
267
/**
268
* Add keypair from URI
269
* @param suri - Secret URI (mnemonic, hex seed, or derivation path)
270
* @param meta - Key metadata
271
* @param type - Cryptographic algorithm type
272
* @returns KeyringPair instance
273
*/
274
addFromUri(
275
suri: string,
276
meta?: KeyringPair$Meta,
277
type?: KeypairType
278
): KeyringPair;
279
280
/**
281
* Add keypair from seed
282
* @param seed - Raw seed bytes
283
* @param meta - Key metadata
284
* @param type - Cryptographic algorithm type
285
* @returns KeyringPair instance
286
*/
287
addFromSeed(
288
seed: Uint8Array,
289
meta?: KeyringPair$Meta,
290
type?: KeypairType
291
): KeyringPair;
292
293
/**
294
* Add keypair from mnemonic
295
* @param mnemonic - BIP39 mnemonic phrase
296
* @param meta - Key metadata
297
* @param type - Cryptographic algorithm type
298
* @returns KeyringPair instance
299
*/
300
addFromMnemonic(
301
mnemonic: string,
302
meta?: KeyringPair$Meta,
303
type?: KeypairType
304
): KeyringPair;
305
306
/**
307
* Add keypair from JSON backup
308
* @param json - Keyring JSON backup
309
* @param passphrase - Decryption passphrase
310
* @returns KeyringPair instance
311
*/
312
addFromJson(json: KeyringPair$Json, passphrase?: string): KeyringPair;
313
314
/**
315
* Get all keypairs
316
* @returns Array of KeyringPair instances
317
*/
318
getPairs(): KeyringPair[];
319
320
/**
321
* Get keypair by address
322
* @param address - Account address
323
* @returns KeyringPair instance or undefined
324
*/
325
getPair(address: string): KeyringPair;
326
327
/**
328
* Remove keypair
329
* @param address - Account address to remove
330
*/
331
removePair(address: string): void;
332
333
/**
334
* Set address format
335
* @param ss58Format - SS58 address format number
336
*/
337
setSS58Format(ss58Format: number): void;
338
}
339
340
interface KeyringOptions {
341
/** Default cryptographic algorithm */
342
type?: 'ed25519' | 'sr25519' | 'ecdsa';
343
/** SS58 address format */
344
ss58Format?: number;
345
}
346
347
interface KeyringPair {
348
/** Account address */
349
readonly address: string;
350
351
/** Public key bytes */
352
readonly publicKey: Uint8Array;
353
354
/** Key metadata */
355
readonly meta: KeyringPair$Meta;
356
357
/** Cryptographic algorithm type */
358
readonly type: KeypairType;
359
360
/**
361
* Sign message
362
* @param message - Message to sign
363
* @param options - Signing options
364
* @returns Signature bytes
365
*/
366
sign(message: Uint8Array, options?: SignOptions): Uint8Array;
367
368
/**
369
* Verify signature
370
* @param message - Original message
371
* @param signature - Signature to verify
372
* @returns Verification result
373
*/
374
verify(message: Uint8Array, signature: Uint8Array): boolean;
375
376
/**
377
* Export to JSON
378
* @param passphrase - Encryption passphrase
379
* @returns JSON backup
380
*/
381
toJson(passphrase?: string): KeyringPair$Json;
382
383
/**
384
* Lock keypair (remove private key from memory)
385
*/
386
lock(): void;
387
388
/**
389
* Unlock keypair
390
* @param passphrase - Unlock passphrase
391
*/
392
unlock(passphrase?: string): void;
393
394
/**
395
* Check if keypair is locked
396
*/
397
get isLocked(): boolean;
398
}
399
```
400
401
## Usage Examples
402
403
### WebSocket Provider Setup
404
405
```typescript
406
import { ApiPromise, WsProvider } from "@polkadot/api";
407
408
// Basic WebSocket connection
409
const provider = new WsProvider('wss://rpc.polkadot.io');
410
const api = await ApiPromise.create({ provider });
411
412
// Multiple endpoints with failover
413
const provider = new WsProvider([
414
'wss://rpc.polkadot.io',
415
'wss://polkadot-rpc.dwellir.com',
416
'wss://1rpc.io/dot'
417
]);
418
const api = await ApiPromise.create({ provider });
419
420
// Custom headers and timeout
421
const provider = new WsProvider(
422
'wss://rpc.polkadot.io',
423
1000, // Auto-connect delay
424
{ 'User-Agent': 'MyApp/1.0' }, // Custom headers
425
30000, // 30 second timeout
426
1024 // Cache capacity
427
);
428
429
// Listen to provider events
430
provider.on('connected', () => console.log('Connected to node'));
431
provider.on('disconnected', () => console.log('Disconnected from node'));
432
provider.on('error', (error) => console.error('Provider error:', error));
433
434
// Manual connection management
435
await provider.connect();
436
console.log('Connected:', provider.isConnected);
437
await provider.disconnect();
438
```
439
440
### HTTP Provider Setup
441
442
```typescript
443
import { ApiPromise, HttpProvider } from "@polkadot/api";
444
445
// Basic HTTP connection
446
const provider = new HttpProvider('https://rpc.polkadot.io');
447
const api = await ApiPromise.create({ provider });
448
449
// Custom headers and timeout
450
const provider = new HttpProvider(
451
'https://rpc.polkadot.io',
452
{
453
'Authorization': 'Bearer token123',
454
'User-Agent': 'MyApp/1.0'
455
},
456
30000 // 30 second timeout
457
);
458
459
// HTTP provider limitations
460
console.log('Always connected:', provider.isConnected); // true
461
// Note: HTTP providers don't support subscriptions
462
```
463
464
### Substrate Connect Provider
465
466
```typescript
467
import { ApiPromise, ScProvider } from "@polkadot/api";
468
469
// Well-known chain connection
470
const provider = new ScProvider('polkadot');
471
const api = await ApiPromise.create({ provider });
472
473
// Custom chain spec
474
const chainSpec = {
475
chainSpec: JSON.stringify({
476
name: "My Custom Chain",
477
id: "my-chain",
478
// ... full chain specification
479
})
480
};
481
482
const provider = new ScProvider(chainSpec, {
483
database: 'my-chain-db'
484
});
485
486
// Light client connection
487
await provider.connect();
488
console.log('Light client connected');
489
490
// Provider events
491
provider.on('connected', () => console.log('Light client ready'));
492
provider.on('disconnected', () => console.log('Light client stopped'));
493
```
494
495
### Keyring Management
496
497
```typescript
498
import { Keyring } from "@polkadot/keyring";
499
500
// Create keyring with SR25519 keys
501
const keyring = new Keyring({ type: 'sr25519' });
502
503
// Add development accounts
504
const alice = keyring.addFromUri('//Alice');
505
const bob = keyring.addFromUri('//Bob');
506
const charlie = keyring.addFromUri('//Charlie');
507
508
console.log('Alice address:', alice.address);
509
console.log('Bob address:', bob.address);
510
511
// Add from mnemonic
512
const account = keyring.addFromMnemonic(
513
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
514
{ name: 'Test Account' }
515
);
516
517
// Add from seed
518
const seed = new Uint8Array(32).fill(1); // Don't use this in production!
519
const seedAccount = keyring.addFromSeed(seed, { name: 'Seed Account' });
520
521
// Get all accounts
522
const pairs = keyring.getPairs();
523
console.log(`Keyring has ${pairs.length} accounts`);
524
525
// Sign message
526
const message = new TextEncoder().encode('Hello Polkadot');
527
const signature = alice.sign(message);
528
console.log('Signature:', signature);
529
530
// Verify signature
531
const isValid = alice.verify(message, signature);
532
console.log('Signature valid:', isValid);
533
```
534
535
### Secure Key Management
536
537
```typescript
538
import { Keyring } from "@polkadot/keyring";
539
540
const keyring = new Keyring({ type: 'sr25519' });
541
542
// Generate new mnemonic (in production, use @polkadot/util-crypto)
543
import { mnemonicGenerate } from "@polkadot/util-crypto";
544
545
const mnemonic = mnemonicGenerate();
546
console.log('Generated mnemonic:', mnemonic);
547
548
// Add account with encryption
549
const account = keyring.addFromMnemonic(mnemonic, { name: 'Secure Account' });
550
551
// Export to encrypted JSON
552
const json = account.toJson('strong-passphrase');
553
console.log('Encrypted JSON:', json);
554
555
// Lock account (remove private key from memory)
556
account.lock();
557
console.log('Account locked:', account.isLocked);
558
559
// Unlock account
560
account.unlock('strong-passphrase');
561
console.log('Account unlocked:', !account.isLocked);
562
563
// Import from JSON
564
const keyring2 = new Keyring({ type: 'sr25519' });
565
const imported = keyring2.addFromJson(json, 'strong-passphrase');
566
console.log('Imported address:', imported.address);
567
```
568
569
### Provider Error Handling
570
571
```typescript
572
import { ApiPromise, WsProvider } from "@polkadot/api";
573
574
// Robust connection with error handling
575
async function connectWithRetry(endpoints: string[], maxRetries = 3) {
576
for (let i = 0; i < maxRetries; i++) {
577
for (const endpoint of endpoints) {
578
try {
579
console.log(`Attempting connection to ${endpoint}...`);
580
581
const provider = new WsProvider(endpoint, 1000, {}, 10000);
582
const api = await ApiPromise.create({
583
provider,
584
throwOnConnect: true
585
});
586
587
console.log(`Connected to ${endpoint}`);
588
return api;
589
} catch (error) {
590
console.warn(`Failed to connect to ${endpoint}:`, error.message);
591
}
592
}
593
594
if (i < maxRetries - 1) {
595
console.log(`Retry ${i + 1}/${maxRetries} in 5 seconds...`);
596
await new Promise(resolve => setTimeout(resolve, 5000));
597
}
598
}
599
600
throw new Error('Failed to connect to any endpoint');
601
}
602
603
// Usage
604
const endpoints = [
605
'wss://rpc.polkadot.io',
606
'wss://polkadot-rpc.dwellir.com',
607
'wss://1rpc.io/dot'
608
];
609
610
try {
611
const api = await connectWithRetry(endpoints);
612
console.log('Successfully connected');
613
614
// Set up reconnection on disconnect
615
api.provider.on('disconnected', async () => {
616
console.log('Connection lost, attempting to reconnect...');
617
try {
618
await api.connect();
619
console.log('Reconnected successfully');
620
} catch (error) {
621
console.error('Reconnection failed:', error);
622
}
623
});
624
} catch (error) {
625
console.error('All connection attempts failed:', error);
626
}
627
```
628
629
### Custom Provider Implementation
630
631
```typescript
632
import { ProviderInterface, ProviderInterfaceCallback } from "@polkadot/rpc-provider/types";
633
634
// Example custom provider implementation
635
class CustomProvider implements ProviderInterface {
636
private _isConnected = false;
637
private _eventemitter = new EventTarget();
638
639
constructor(private endpoint: string) {}
640
641
get isConnected(): boolean {
642
return this._isConnected;
643
}
644
645
async connect(): Promise<void> {
646
// Custom connection logic
647
this._isConnected = true;
648
this._eventemitter.dispatchEvent(new CustomEvent('connected'));
649
}
650
651
async disconnect(): Promise<void> {
652
// Custom disconnection logic
653
this._isConnected = false;
654
this._eventemitter.dispatchEvent(new CustomEvent('disconnected'));
655
}
656
657
async send(method: string, params: unknown[]): Promise<any> {
658
if (!this._isConnected) {
659
throw new Error('Provider not connected');
660
}
661
662
// Custom RPC request logic
663
const response = await fetch(this.endpoint, {
664
method: 'POST',
665
headers: { 'Content-Type': 'application/json' },
666
body: JSON.stringify({
667
jsonrpc: '2.0',
668
id: Date.now(),
669
method,
670
params
671
})
672
});
673
674
const result = await response.json();
675
676
if (result.error) {
677
throw new Error(result.error.message);
678
}
679
680
return result.result;
681
}
682
683
on(type: string, callback: (...args: any[]) => void): () => void {
684
this._eventemitter.addEventListener(type, callback);
685
return () => this._eventemitter.removeEventListener(type, callback);
686
}
687
688
clone(): CustomProvider {
689
return new CustomProvider(this.endpoint);
690
}
691
}
692
693
// Usage
694
const customProvider = new CustomProvider('https://my-custom-node.com');
695
const api = await ApiPromise.create({ provider: customProvider });
696
```