or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-initialization.mdblockchain-queries.mdevents-metadata.mdindex.mdnetwork-providers.mdrpc-operations.mdtransaction-submission.md

network-providers.mddocs/

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

```