EIPs
EIP-1193 — Ethereum Provider JavaScript API
The Provider envelope every wallet implements. A Provider is a four-field object:
type Provider = {
request(args: RequestArguments): Promise<unknown>;
on(event: EventName, listener): void;
removeListener(event: EventName, listener): void;
emit(event: EventName, payload): void;
}; That’s all. Method routing, allowlists, caching, confirmation policy — none of that is part of 1193. See Concepts → 1193 is a transport.
import { create_provider } from "@ethernauta/eip/1193";
const provider = create_provider({
request: async ({ method, params }) => dispatch(method, params),
}); Surface
Provider
| Export | Type | Purpose |
|---|---|---|
create_provider | (options) => Provider | Build a 1193 provider with the four-field shape. |
Provider, RequestArguments, CreateProviderOptions | types | Inferred shapes. |
requestArgumentsSchema | Valibot schema | Validate incoming request calls. |
Errors
EIP-1193 defines a standard error space (4001 user rejected, 4100 unauthorized, 4200 unsupported method, 4900/4901 disconnected, …):
| Export | Code | Purpose |
|---|---|---|
ERROR_CODE | enum-like | All standard codes by name. |
invalid_params | -32602 | Bad params. |
unauthorized | 4100 | Not authorized by user. |
user_rejected | 4001 | User clicked “reject.” |
unsupported_method | 4200 | Method not implemented. |
unrecognized_chain | 4902 | Chain not added to wallet. |
chain_disconnected | 4901 | Disconnected from chain. |
provider_error | -32603 | Internal provider error. |
disconnected | 4900 | No connection. |
ErrorCode | type | Discriminated union of the above. |
Events
import { create_emitter } from "@ethernauta/eip/1193";
const emitter = create_emitter();
emitter.on("accountsChanged", (accounts) => { ... });
emitter.on("chainChanged", (chain_id) => { ... });
emitter.emit("accountsChanged", new_accounts); | Event | Payload |
|---|---|
connect | { chain_id } |
disconnect | ProviderRpcError |
accountsChanged | Address[] |
chainChanged | Uint (decimal chain ID as bigint) |
message | EthSubscription \| ... |
| Export | Purpose |
|---|---|
create_emitter | Build an event emitter conforming to 1193 semantics. |
Emitter, EventMap, EventName, EthSubscription, ProviderMessage, ProviderConnectInfo | types |
Convenience watchers
import { watch_accounts, watch_chain } from "@ethernauta/eip/1193";
const unsubscribe = watch_accounts(provider, (accounts) => {
console.log("now exposed:", accounts);
});
watch_chain(provider, (chain_id) => {
console.log("active chain:", chain_id);
}); Return unsubscribe functions; cleanly handle accountsChanged / chainChanged together with initial-state fetching.
Consumer side — turning a 1193 provider into resolvers
The library’s typical dapp pattern doesn’t request directly; it adapts the provider into resolver shapes:
import { create_provider } from "@ethernauta/transport";
const provider = create_provider(window.ethereum);
const block = await eth_block_number()(provider.reader({ chain_id: 1 }));
const hash = await eth_send_transaction({ to, value })(
provider.signer({ chain_id: 1 }),
); create_provider in @ethernauta/eip/1193 builds a provider (the wallet side, producing the four-field envelope). create_provider in @ethernauta/transport consumes a provider (the dapp side, adapting it into resolver shapes). Same name, opposite sides of the same envelope — pick the import by what your code is doing.
See also
- EIP-6963 — discover providers when there may be more than one.
- Concepts → 1193 is a transport — why the envelope is intentionally four fields.
- Concepts → the wallet contract — what the Ethernauta wallet routes where.