# Neo3 Provider API

The NeoLine extension wallet can expose a Neo N3 provider that follows the NEP-21 `IDapiProvider` interface.

You can use this provider in your dapp to discover a compatible wallet, inspect provider metadata, call Neo3 methods, and listen for account and network changes.

{% hint style="info" %}
NOTE

Throughout this documentation, we refer to the selected Neo3 NEP-21 provider instance as `provider`.
{% endhint %}

## Provider Discovery

NEP-21 providers announce themselves through the `Neo.DapiProvider.ready` event on `window`.

```js
let provider;

window.addEventListener('Neo.DapiProvider.ready', (event) => {
  if (event.detail.provider.name === 'NeoLine') {
    provider = event.detail.provider;
  }
});
```

If you want to proactively request a provider, dispatch `Neo.DapiProvider.request` with the dAPI version you expect:

```js
window.dispatchEvent(new Event('Neo.DapiProvider.request'));
```

## Properties

An NEP-21 provider exposes the following properties:

| Property            | Type       | Description                                                                  |
| ------------------- | ---------- | ---------------------------------------------------------------------------- |
| `name`              | `string`   | Provider name.                                                               |
| `version`           | `string`   | Provider version.                                                            |
| `dapiVersion`       | `string`   | dAPI version. For NEP-21 this should currently be `1.0`.                     |
| `compatibility`     | `string[]` | Supported standards, for example `["NEP-11", "NEP-17", "NEP-21"]`.           |
| `connected`         | `boolean`  | Whether the wallet is currently connected to the dapp.                       |
| `network`           | `number`   | Current Neo N3 network magic number.                                         |
| `supportedNetworks` | `number[]` | Networks supported by the provider.                                          |
| `icon`              | `string`   | Provider icon URL, the scheme of the URL should be either "https" or "data". |
| `website`           | `string`   | Provider website.                                                            |
| `extra`             | `any`      | Additional provider-specific metadata.                                       |

#### Example

```js
console.log(provider.name);
console.log(provider.dapiVersion);
console.log(provider.network);
console.log(provider.compatibility);
```

## Methods

### Neo3 provider methods

The Neo3 provider exposes standardized NEP-21 provider methods such as:

* [authenticate](https://tutorial.neoline.io/reference/neo3-provider-api/authenticate)
* [getAccounts](https://tutorial.neoline.io/reference/neo3-provider-api/getaccounts)
* [pickAddress](https://tutorial.neoline.io/reference/neo3-provider-api/pickaddress)
* [getBalance](https://tutorial.neoline.io/reference/neo3-provider-api/getbalance)
* [send](https://tutorial.neoline.io/reference/neo3-provider-api/send)
* [call](https://tutorial.neoline.io/reference/neo3-provider-api/call)
* [invoke](https://tutorial.neoline.io/reference/neo3-provider-api/invoke)
* [makeTransaction](https://tutorial.neoline.io/reference/neo3-provider-api/maketransaction)
* [sign](https://tutorial.neoline.io/reference/neo3-provider-api/sign)
* [signMessage](https://tutorial.neoline.io/reference/neo3-provider-api/signmessage)
* [relay](https://tutorial.neoline.io/reference/neo3-provider-api/relay)
* [getBlock](https://tutorial.neoline.io/reference/neo3-provider-api/getblock)
* [getBlockCount](https://tutorial.neoline.io/reference/neo3-provider-api/getblockcount)
* [getTransaction](https://tutorial.neoline.io/reference/neo3-provider-api/gettransaction)
* [getApplicationLog](https://tutorial.neoline.io/reference/neo3-provider-api/getapplicationlog)
* [getStorage](https://tutorial.neoline.io/reference/neo3-provider-api/getstorage)
* [getTokenInfo](https://tutorial.neoline.io/reference/neo3-provider-api/gettokeninfo)

The following is an example of using `authenticate()`:

```js
provider
  .authenticate({
    action: "Authentication",
    grant_type: "Signature",
    allowed_algorithms: ["ECDSA-P256"],
    domain: "127.0.0.1",
    networks: [860833102],
    nonce: "1844674407370955161",
    timestamp: 1710000000,
  })
  .then((result) => {
    // Returns the NEP-20 authentication response payload.
  })
  .catch((error) => {
    // If the request fails, the Promise rejects with an error.
  });
```

## Events

The NeoLine provider emits events through the standard `on()` and `removeListener()` API. The following is an example of listening to the [`accountchanged`](#accountchanged) event.

You should remove listeners after you are done listening to an event, for example when a React component unmounts.

```js
function handleAccountsChanged(accounts) {
  // Handle new accounts, or lack thereof.
}

provider.on("accountchanged", handleAccountsChanged);

// Later

provider.removeListener("accountchanged", handleAccountsChanged);
```

### `accountchanged`

```js
provider.on("accountchanged", handler: (accounts: Account[]) => void);
```

The provider emits this event when the connected account set changes. The event payload is `accounts: Account[]`.

### `networkchanged`

```js
provider.on("networkchanged", handler: (network: number) => void);
```

The provider emits this event when the currently connected Neo network changes. The event payload is `network: number`.

### Remove event listeners <a href="#remove-event-listeners" id="remove-event-listeners"></a>

#### `removeListener`

Use `removeListener` to remove a specific listener from the provider.

```js
provider.on("accountchanged", updateWallet);
provider.on("networkchanged", updateNetwork);

provider.removeListener("accountchanged", updateWallet);
provider.removeListener("networkchanged", updateNetwork);
```

## Errors

All errors returned by the Neo3 provider follow this interface:

```ts
interface ProviderError extends Error {
  code: number;
  message: string;
  data?: any;
}
```

NEP-21 methods reject eagerly. You can use the error `code` property to determine why the request failed.

| Code    | Name                 | Description                                             |
| ------- | -------------------- | ------------------------------------------------------- |
| `10000` | `UNKNOWN`            | An unknown error has occurred.                          |
| `10001` | `UNSUPPORTED`        | The requested feature or operation is not supported.    |
| `10002` | `INVALID`            | The input data is in an invalid format.                 |
| `10003` | `NOTFOUND`           | The requested data does not exist.                      |
| `10004` | `FAILED`             | Contract execution failed.                              |
| `10005` | `TIMEOUT`            | The requested operation timed out.                      |
| `10006` | `CANCELED`           | The requested operation was canceled by the user.       |
| `10007` | `INSUFFICIENT_FUNDS` | The request failed because the balance is insufficient. |
| `10008` | `RPC_ERROR`          | The RPC server threw an exception.                      |

When `code` is `10004`, providers may include the failed `InvocationResult` in `data`.

```ts
interface FailedError extends ProviderError {
  code: 10004;
  message: "Contract execution failed";
  data: InvocationResult;
}
```

## Notes

* `Network` values are Neo N3 magic numbers, such as `860833102` for MainNet and `894710606` for TestNet.
* All callable Neo3 methods are documented in this section of the Neo3 provider API reference.
* `authenticate()` follows the NEP-20 authentication challenge and response format.
