# API Reference

## Package: `@tetherto/wdk-failover-provider`

### Class: `FailoverProvider<T>`

`FailoverProvider<T>` collects provider candidates of one shared shape and returns a proxied `T` that retries failed calls against the next provider.

#### Constructor

Use the constructor to set retry behavior before you add provider candidates:

{% code title="Create A FailoverProvider Factory" lineNumbers="true" %}

```javascript
new FailoverProvider({
  retries,        // optional, defaults to 3
  shouldRetryOn   // optional, defaults to (error) => error instanceof Error
})
```

{% endcode %}

* `retries` (`number`, optional): Number of additional attempts after the first failure. Total attempts are `1 + retries`.
* `shouldRetryOn` (`(error: Error) => boolean`, optional): Predicate that decides whether the proxy should switch to the next provider after a failure.

#### Methods

| Method                  | Description                                                                                                                   | Returns               |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `addProvider(provider)` | Register one provider candidate and return the same factory so you can chain more candidates.                                 | `FailoverProvider<T>` |
| `initialize()`          | Return a proxied provider of type `T` that reads from the active provider and retries failed calls against the next provider. | `T`                   |

#### `addProvider(provider)`

Register a provider candidate. Every candidate should satisfy the same `T` shape because `initialize()` returns one proxied `T`.

{% code title="Register A Provider Candidate" lineNumbers="true" %}

```javascript
const factory = new FailoverProvider({ retries: 1 })

factory.addProvider({
  name: 'primary',
  async getBlockNumber () {
    return 21345678
  }
})
```

{% endcode %}

#### `initialize()`

Create the failover-enabled proxy after you have added at least one provider. The runtime throws if the factory is still empty.

{% code title="Initialize The Failover Proxy" lineNumbers="true" %}

```javascript
const provider = new FailoverProvider({ retries: 1 })
  .addProvider(primary)
  .addProvider(secondary)
  .initialize()

const blockNumber = await provider.getBlockNumber()
```

{% endcode %}

#### `FailoverProviderConfig`

The package exports the `FailoverProviderConfig` type through its top-level type surface.

| Field            | Description                                                                                         |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| `retries?`       | Additional retry attempts after the first failure. Defaults to `3`.                                 |
| `shouldRetryOn?` | Retry predicate for thrown errors and rejected promises. Defaults to retrying any `Error` instance. |

## Runtime behavior

* `initialize()` returns a JavaScript `Proxy` over the first added provider.
* Non-function properties are forwarded from the currently active provider.
* If a property getter throws and `shouldRetryOn(error)` returns `true`, the runtime advances to the next provider before retrying the property access.
* If a synchronous method throws and `shouldRetryOn(error)` returns `true`, the runtime advances to the next provider and retries the method call.
* If an asynchronous method rejects and `shouldRetryOn(error)` returns `true`, the runtime advances to the next provider and retries the method call.
* Provider switching is round-robin. If the active provider already changed while another call was failing, the runtime keeps the newer active provider instead of advancing twice.

## Example

This example shows a transient failure on the first provider and a successful retry on the second provider:

{% code title="Retry Across Two Providers" lineNumbers="true" %}

```javascript
import FailoverProvider from '@tetherto/wdk-failover-provider'

const primary = {
  async getBlockNumber () {
    throw new Error('temporary upstream outage')
  }
}

const secondary = {
  async getBlockNumber () {
    return 21345678
  }
}

const provider = new FailoverProvider({
  retries: 1,
  shouldRetryOn: (error) => error.message.includes('temporary')
})
  .addProvider(primary)
  .addProvider(secondary)
  .initialize()

const blockNumber = await provider.getBlockNumber()
```

{% endcode %}

***

## Need Help?

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-discord">:discord:</i></td><td><strong>Discord Community</strong></td><td>Connect with developers, ask questions, share your projects</td><td><a href="https://discord.gg/arYXDhHB2w" class="button primary">Join Community</a></td><td><a href="https://discord.gg/arYXDhHB2w">https://discord.gg/arYXDhHB2w</a></td></tr><tr><td><i class="fa-github">:github:</i></td><td><strong>GitHub Issues</strong></td><td>Report bugs, request features, and get technical help</td><td><a href="https://github.com/tetherto/wdk-core" class="button secondary">Open an Issue</a></td><td><a href="https://github.com/tetherto/wdk-core">https://github.com/tetherto/wdk-core</a></td></tr><tr><td><i class="fa-envelope">:envelope:</i></td><td><strong>Email Contact</strong></td><td>For sensitive or private matters, contact our team directly</td><td><a href="mailto:wallet-info.tether.io" class="button secondary">Send an email</a></td><td><a href="mailto:wallet-info.tether.io">mailto:wallet-info.tether.io</a></td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wdk.tether.io/tools/failover-provider/api-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
