UNPKG

@starknet-react/core

Version:

Starknet React is a collection of React hooks for Starknet.

1,414 lines (1,384 loc) 93.5 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/connectors/base.ts import EventEmitter from "eventemitter3"; var Connector = class extends EventEmitter { }; // src/connectors/discovery.ts import { useCallback, useEffect, useMemo, useState } from "react"; // src/connectors/injected.ts import { Permission } from "@starknet-io/types-js"; import { num, WalletAccount } from "starknet"; // src/errors.ts var ConnectorAlreadyConnectedError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "ConnectorAlreadyConnectedError"); __publicField(this, "message", "Connector already connected"); } }; var ConnectorNotConnectedError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "ConnectorNotConnectedError"); __publicField(this, "message", "Connector not connected"); } }; var ConnectorNotFoundError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "ConnectorNotFoundError"); __publicField(this, "message", "Connector not found"); } }; var UserRejectedRequestError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "UserRejectedRequestError"); __publicField(this, "message", "User rejected request"); } }; var WalletRequestError = class extends Error { constructor(error, _cause) { super( error instanceof Error ? error.message : typeof error === "string" ? error : "Unknown Request Error" ); this.name = "WalletRequestError"; this.stack = error instanceof Error ? error.stack : void 0; } }; var UserNotConnectedError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "UserNotConnectedError"); __publicField(this, "message", "User not connected"); } }; var UnsupportedAccountInterfaceError = class extends Error { constructor() { super(...arguments); __publicField(this, "name", "UnsupportedAccountInterfaceError"); __publicField(this, "message", "Unsupported account interface. starknet-react v1 only supports the starknet.js v5 account interface"); } }; // src/connectors/injected.ts var WALLET_NOT_FOUND_ICON_LIGHT = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0iYmxhY2siPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTkuODc5IDcuNTE5YzEuMTcxLTEuMDI1IDMuMDcxLTEuMDI1IDQuMjQyIDAgMS4xNzIgMS4wMjUgMS4xNzIgMi42ODcgMCAzLjcxMi0uMjAzLjE3OS0uNDMuMzI2LS42Ny40NDItLjc0NS4zNjEtMS40NS45OTktMS40NSAxLjgyN3YuNzVNMjEgMTJhOSA5IDAgMTEtMTggMCA5IDkgMCAwMTE4IDB6bS05IDUuMjVoLjAwOHYuMDA4SDEydi0uMDA4eiIgLz4KPC9zdmc+"; var WALLET_NOT_FOUND_ICON_DARK = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0id2hpdGUiPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTkuODc5IDcuNTE5YzEuMTcxLTEuMDI1IDMuMDcxLTEuMDI1IDQuMjQyIDAgMS4xNzIgMS4wMjUgMS4xNzIgMi42ODcgMCAzLjcxMi0uMjAzLjE3OS0uNDMuMzI2LS42Ny40NDItLjc0NS4zNjEtMS40NS45OTktMS40NSAxLjgyN3YuNzVNMjEgMTJhOSA5IDAgMTEtMTggMCA5IDkgMCAwMTE4IDB6bS05IDUuMjVoLjAwOHYuMDA4SDEydi0uMDA4eiIgLz4KPC9zdmc+Cg=="; var walletIcons = { argentX: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA2NS4xOTUwOCA1Ny43MzU2MiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjUuMTk1MDggNTcuNzM1NjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkY4NzVCO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQwLjk4NTkyLDBIMjQuMjA4ODhjLTAuNTYsMC0xLjAxMDAxLDAuNDUxMDItMS4wMjE5NywxLjAxMjAyCgljLTAuMzM4OTksMTUuNzU1LTguNTgyMDMsMzAuNzA4OTgtMjIuNzcwMDIsNDEuMzAwOTljLTAuNDUwMDEsMC4zMzcwMS0wLjU1Mjk4LDAuOTY3OTktMC4yMjQsMS40MjNsOS44MTU5OCwxMy41NzMKCWMwLjMzNDA1LDAuNDYyMDEsMC45ODUwNSwwLjU2NTk4LDEuNDQyOTksMC4yMjY5OWM4Ljg3MTAzLTYuNTc5MDEsMTYuMDA3MDItMTQuNTE3LDIxLjE0NjA2LTIzLjMxNQoJYzUuMTM4LDguNzk4LDEyLjI3Mzk5LDE2LjczNTk5LDIxLjE0NiwyMy4zMTVjMC40NTY5NywwLjMzODk5LDEuMTA3OTcsMC4yMzUwMiwxLjQ0MTk2LTAuMjI2OTlsOS44MTYwNC0xMy41NzMKCWMwLjMyODk4LTAuNDU1MDIsMC4yMjY5OS0xLjA4Ni0wLjIyNC0xLjQyM0M1MC41ODk4NiwzMS43MjEwMSw0Mi4zNDY4OCwxNi43NjcwMyw0Mi4wMDc4OSwxLjAxMjAyCglDNDEuOTk1ODcsMC40NTEwMiw0MS41NDY4OSwwLDQwLjk4NTkyLDAiLz4KPC9zdmc+Cg==", braavos: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgdmlld0JveD0iMCAwIDUwMCA1MDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0zMjMuNDQgNDEuMzg4NkMzMjQuMTk4IDQyLjY3MjggMzIzLjE5NSA0NC4yNjAzIDMyMS43MDQgNDQuMjYwM0MyOTEuNTEgNDQuMjYwMyAyNjYuOTY1IDY4LjE2NTYgMjY2LjM4OSA5Ny44NzFDMjU2LjA1IDk1Ljk0MDcgMjQ1LjMzNyA5NS43OTU2IDIzNC43NTQgOTcuNTc4N0MyMzQuMDIzIDY4LjAwOSAyMDkuNTQgNDQuMjYwMyAxNzkuNDQ1IDQ0LjI2MDNDMTc3Ljk1MyA0NC4yNjAzIDE3Ni45NDkgNDIuNjcxNiAxNzcuNzA3IDQxLjM4NjVDMTkyLjMyMyAxNi42MzMgMjE5LjQ4MyAwIDI1MC41NzMgMEMyODEuNjY0IDAgMzA4LjgyNCAxNi42MzM5IDMyMy40NCA0MS4zODg2WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzIzMjRfNjE4NjkpIi8+CjxwYXRoIGQ9Ik00MTguNzU2IDIyNi44OTRDNDI2LjM3IDIyOS4yIDQzMy41ODEgMjIyLjUxNyA0MzEuMDM2IDIxNC45NzlDNDA0LjUwNyAxMzYuNDAxIDMxNi41MzUgMTA0LjM1OCAyNTAuMTU5IDEwNC4zNThDMTgzLjY3NCAxMDQuMzU4IDkzLjczOTEgMTM3LjQxOCA2OS4zMDUxIDIxNS4zMzFDNjYuOTU3NCAyMjIuODE4IDc0LjE0NjUgMjI5LjI3NSA4MS42NDc5IDIyNi45NzdMMjQ0LjI1IDE3Ny4xNTFDMjQ3LjU2OSAxNzYuMTM0IDI1MS4xMTYgMTc2LjEyOCAyNTQuNDM5IDE3Ny4xMzVMNDE4Ljc1NiAyMjYuODk0WiIgZmlsbD0idXJsKCNwYWludDFfbGluZWFyXzIzMjRfNjE4NjkpIi8+CjxwYXRoIGQ9Ik02OS43MTY1IDIzOS40MjZMMjQ0LjM3IDE4Ni40NTZDMjQ3LjY2OSAxODUuNDU2IDI1MS4xOTEgMTg1LjQ1MyAyNTQuNDkyIDE4Ni40NDhMNDMwLjIzMiAyMzkuNDUyQzQ0NC43NiAyNDMuODMzIDQ1NC43MDEgMjU3LjIxNiA0NTQuNzAxIDI3Mi4zOVY0MzAuNDgxQzQ1NC4wMjggNDY5LjA3IDQxOS4zNjIgNTAwIDM4MC43ODYgNTAwSDMxNi43MTJDMzEwLjM3OSA1MDAgMzA1LjI1IDQ5NC44NzcgMzA1LjI1IDQ4OC41NDNWNDMzLjExNUMzMDUuMjUgNDExLjI4OSAzMTguMTY3IDM5MS41MzUgMzM4LjE1NSAzODIuNzkyQzM2NC45NDkgMzcxLjA3MSAzOTYuNjQ2IDM1NS4yMTggNDAyLjYwOCAzMjMuNDA2QzQwNC41MzIgMzEzLjEzOCAzOTcuODM3IDMwMy4yMzQgMzg3LjU5NSAzMDEuMTk4QzM2MS42OTkgMjk2LjA1MSAzMzIuOTg5IDI5OC4wMzkgMzA4LjcxMSAzMDguODk4QzI4MS4xNSAzMjEuMjI1IDI3My45NCAzNDEuNzMxIDI3MS4yNzEgMzY5LjI3TDI2OC4wMzYgMzk4LjkzOEMyNjcuMDQ3IDQwOC4wMDUgMjU4LjU0NiA0MTQuOTUyIDI0OS40MjkgNDE0Ljk1MkMyMzkuOTk4IDQxNC45NTIgMjMyLjkyNiA0MDcuNzY5IDIzMS45MDMgMzk4LjM4OEwyMjguNzI4IDM2OS4yN0MyMjYuNDQyIDM0NS42ODEgMjIyLjI5OCAzMjIuNzY3IDE5Ny45MTIgMzExLjg2QzE3MC4wOTUgMjk5LjQxOSAxNDIuMTQxIDI5NS4yODcgMTEyLjQwNCAzMDEuMTk4QzEwMi4xNjIgMzAzLjIzNCA5NS40NjcgMzEzLjEzOCA5Ny4zOTEzIDMyMy40MDZDMTAzLjQwNSAzNTUuNDk1IDEzNC44NTQgMzcwLjk4NSAxNjEuODQ0IDM4Mi43OTJDMTgxLjgzMyAzOTEuNTM1IDE5NC43NSA0MTEuMjg5IDE5NC43NSA0MzMuMTE1VjQ4OC41MzNDMTk0Ljc1IDQ5NC44NjcgMTg5LjYyMiA1MDAgMTgzLjI4OSA1MDBIMTE5LjIxNEM4MC42Mzc0IDUwMCA0NS45NzE2IDQ2OS4wNyA0NS4yOTc5IDQzMC40ODFWMjcyLjM0OUM0NS4yOTc5IDI1Ny4xOTQgNTUuMjE0MiAyNDMuODI0IDY5LjcxNjUgMjM5LjQyNloiIGZpbGw9InVybCgjcGFpbnQyX2xpbmVhcl8yMzI0XzYxODY5KSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4=" }; var InjectedConnector = class extends Connector { constructor({ options }) { super(); __publicField(this, "_wallet"); __publicField(this, "_options"); this._options = options; } get id() { return this._options.id; } get name() { this.ensureWallet(); return this._options.name ?? this._wallet?.name ?? this._options.id; } get icon() { this.ensureWallet(); const deafultIcon = { dark: walletIcons[this.id] || WALLET_NOT_FOUND_ICON_DARK, light: walletIcons[this.id] || WALLET_NOT_FOUND_ICON_LIGHT }; return this._options.icon || this._wallet?.icon || deafultIcon; } available() { this.ensureWallet(); return this._wallet !== void 0; } async chainId() { this.ensureWallet(); const locked = await this.isLocked(); if (!this._wallet || locked) { throw new ConnectorNotConnectedError(); } return await this.requestChainId(); } async ready() { this.ensureWallet(); if (!this._wallet) return false; const permissions = await this.request({ type: "wallet_getPermissions" }); return permissions ? permissions.includes(Permission.ACCOUNTS) : false; } async account(provider, paymasterProvider) { this.ensureWallet(); const locked = await this.isLocked(); if (locked || !this._wallet) { throw new ConnectorNotConnectedError(); } return await WalletAccount.connect( provider, this._wallet, void 0, paymasterProvider, true ); } async connect(_args = {}) { this.ensureWallet(); if (!this._wallet) { throw new ConnectorNotFoundError(); } this._wallet.on("accountsChanged", async (accounts2) => { await this.onAccountsChanged(accounts2); }); this._wallet.on("networkChanged", (chainId2, accounts2) => { this.onNetworkChanged(chainId2, accounts2); }); const accounts = await this.request({ type: "wallet_requestAccounts" }); if (!accounts) { throw new UserRejectedRequestError(); } if (_args.chainIdHint) { const chainId2 = await this.requestChainId(); if (chainId2 !== _args.chainIdHint) { await this.switchChain(_args.chainIdHint); } } const [account] = accounts; const chainId = await this.requestChainId(); this.emit("connect", { account, chainId }); return { account, chainId }; } async disconnect() { this.ensureWallet(); if (!this._wallet) { throw new ConnectorNotFoundError(); } this.emit("disconnect"); } async request(call) { this.ensureWallet(); if (!this._wallet) { throw new ConnectorNotConnectedError(); } return await this._wallet.request(call); } async isLocked() { const accounts = await this.request({ type: "wallet_requestAccounts", params: { silent_mode: true } }); return accounts.length === 0; } async requestChainId() { const chainIdHex = await this.request({ type: "wallet_requestChainId" }); return BigInt(chainIdHex); } ensureWallet() { const global_object = globalThis; const wallet = global_object?.[`starknet_${this._options.id}`]; if (wallet) { this._wallet = wallet; } } async onAccountsChanged(accounts) { if (!accounts) { this.emit("disconnect"); } else { const [account] = accounts; if (account) { const chainId = await this.requestChainId(); this.emit("change", { account, chainId }); } else { this.emit("disconnect"); } } } onNetworkChanged(chainIdHex, accounts) { if (chainIdHex) { const chainId = BigInt(chainIdHex); const [account] = accounts || []; this.emit("change", { chainId, account }); } else { this.emit("change", {}); } } async switchChain(chainId) { await this.request({ type: "wallet_switchStarknetChain", params: { chainId: num.toHex(chainId) } }); } }; // src/connectors/legacy.ts import { Permission as Permission2 } from "@starknet-io/types-js"; import { mainnet, sepolia } from "@starknet-react/chains"; var WALLET_NOT_FOUND_ICON_LIGHT2 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0iYmxhY2siPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTkuODc5IDcuNTE5YzEuMTcxLTEuMDI1IDMuMDcxLTEuMDI1IDQuMjQyIDAgMS4xNzIgMS4wMjUgMS4xNzIgMi42ODcgMCAzLjcxMi0uMjAzLjE3OS0uNDMuMzI2LS42Ny40NDItLjc0NS4zNjEtMS40NS45OTktMS40NSAxLjgyN3YuNzVNMjEgMTJhOSA5IDAgMTEtMTggMCA5IDkgMCAwMTE4IDB6bS05IDUuMjVoLjAwOHYuMDA4SDEydi0uMDA4eiIgLz4KPC9zdmc+"; var WALLET_NOT_FOUND_ICON_DARK2 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0id2hpdGUiPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTkuODc5IDcuNTE5YzEuMTcxLTEuMDI1IDMuMDcxLTEuMDI1IDQuMjQyIDAgMS4xNzIgMS4wMjUgMS4xNzIgMi42ODcgMCAzLjcxMi0uMjAzLjE3OS0uNDMuMzI2LS42Ny40NDItLjc0NS4zNjEtMS40NS45OTktMS40NSAxLjgyN3YuNzVNMjEgMTJhOSA5IDAgMTEtMTggMCA5IDkgMCAwMTE4IDB6bS05IDUuMjVoLjAwOHYuMDA4SDEydi0uMDA4eiIgLz4KPC9zdmc+Cg=="; var walletIcons2 = { argentX: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA2NS4xOTUwOCA1Ny43MzU2MiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjUuMTk1MDggNTcuNzM1NjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkY4NzVCO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQwLjk4NTkyLDBIMjQuMjA4ODhjLTAuNTYsMC0xLjAxMDAxLDAuNDUxMDItMS4wMjE5NywxLjAxMjAyCgljLTAuMzM4OTksMTUuNzU1LTguNTgyMDMsMzAuNzA4OTgtMjIuNzcwMDIsNDEuMzAwOTljLTAuNDUwMDEsMC4zMzcwMS0wLjU1Mjk4LDAuOTY3OTktMC4yMjQsMS40MjNsOS44MTU5OCwxMy41NzMKCWMwLjMzNDA1LDAuNDYyMDEsMC45ODUwNSwwLjU2NTk4LDEuNDQyOTksMC4yMjY5OWM4Ljg3MTAzLTYuNTc5MDEsMTYuMDA3MDItMTQuNTE3LDIxLjE0NjA2LTIzLjMxNQoJYzUuMTM4LDguNzk4LDEyLjI3Mzk5LDE2LjczNTk5LDIxLjE0NiwyMy4zMTVjMC40NTY5NywwLjMzODk5LDEuMTA3OTcsMC4yMzUwMiwxLjQ0MTk2LTAuMjI2OTlsOS44MTYwNC0xMy41NzMKCWMwLjMyODk4LTAuNDU1MDIsMC4yMjY5OS0xLjA4Ni0wLjIyNC0xLjQyM0M1MC41ODk4NiwzMS43MjEwMSw0Mi4zNDY4OCwxNi43NjcwMyw0Mi4wMDc4OSwxLjAxMjAyCglDNDEuOTk1ODcsMC40NTEwMiw0MS41NDY4OSwwLDQwLjk4NTkyLDAiLz4KPC9zdmc+Cg==", braavos: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgdmlld0JveD0iMCAwIDUwMCA1MDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0zMjMuNDQgNDEuMzg4NkMzMjQuMTk4IDQyLjY3MjggMzIzLjE5NSA0NC4yNjAzIDMyMS43MDQgNDQuMjYwM0MyOTEuNTEgNDQuMjYwMyAyNjYuOTY1IDY4LjE2NTYgMjY2LjM4OSA5Ny44NzFDMjU2LjA1IDk1Ljk0MDcgMjQ1LjMzNyA5NS43OTU2IDIzNC43NTQgOTcuNTc4N0MyMzQuMDIzIDY4LjAwOSAyMDkuNTQgNDQuMjYwMyAxNzkuNDQ1IDQ0LjI2MDNDMTc3Ljk1MyA0NC4yNjAzIDE3Ni45NDkgNDIuNjcxNiAxNzcuNzA3IDQxLjM4NjVDMTkyLjMyMyAxNi42MzMgMjE5LjQ4MyAwIDI1MC41NzMgMEMyODEuNjY0IDAgMzA4LjgyNCAxNi42MzM5IDMyMy40NCA0MS4zODg2WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzIzMjRfNjE4NjkpIi8+CjxwYXRoIGQ9Ik00MTguNzU2IDIyNi44OTRDNDI2LjM3IDIyOS4yIDQzMy41ODEgMjIyLjUxNyA0MzEuMDM2IDIxNC45NzlDNDA0LjUwNyAxMzYuNDAxIDMxNi41MzUgMTA0LjM1OCAyNTAuMTU5IDEwNC4zNThDMTgzLjY3NCAxMDQuMzU4IDkzLjczOTEgMTM3LjQxOCA2OS4zMDUxIDIxNS4zMzFDNjYuOTU3NCAyMjIuODE4IDc0LjE0NjUgMjI5LjI3NSA4MS42NDc5IDIyNi45NzdMMjQ0LjI1IDE3Ny4xNTFDMjQ3LjU2OSAxNzYuMTM0IDI1MS4xMTYgMTc2LjEyOCAyNTQuNDM5IDE3Ny4xMzVMNDE4Ljc1NiAyMjYuODk0WiIgZmlsbD0idXJsKCNwYWludDFfbGluZWFyXzIzMjRfNjE4NjkpIi8+CjxwYXRoIGQ9Ik02OS43MTY1IDIzOS40MjZMMjQ0LjM3IDE4Ni40NTZDMjQ3LjY2OSAxODUuNDU2IDI1MS4xOTEgMTg1LjQ1MyAyNTQuNDkyIDE4Ni40NDhMNDMwLjIzMiAyMzkuNDUyQzQ0NC43NiAyNDMuODMzIDQ1NC43MDEgMjU3LjIxNiA0NTQuNzAxIDI3Mi4zOVY0MzAuNDgxQzQ1NC4wMjggNDY5LjA3IDQxOS4zNjIgNTAwIDM4MC43ODYgNTAwSDMxNi43MTJDMzEwLjM3OSA1MDAgMzA1LjI1IDQ5NC44NzcgMzA1LjI1IDQ4OC41NDNWNDMzLjExNUMzMDUuMjUgNDExLjI4OSAzMTguMTY3IDM5MS41MzUgMzM4LjE1NSAzODIuNzkyQzM2NC45NDkgMzcxLjA3MSAzOTYuNjQ2IDM1NS4yMTggNDAyLjYwOCAzMjMuNDA2QzQwNC41MzIgMzEzLjEzOCAzOTcuODM3IDMwMy4yMzQgMzg3LjU5NSAzMDEuMTk4QzM2MS42OTkgMjk2LjA1MSAzMzIuOTg5IDI5OC4wMzkgMzA4LjcxMSAzMDguODk4QzI4MS4xNSAzMjEuMjI1IDI3My45NCAzNDEuNzMxIDI3MS4yNzEgMzY5LjI3TDI2OC4wMzYgMzk4LjkzOEMyNjcuMDQ3IDQwOC4wMDUgMjU4LjU0NiA0MTQuOTUyIDI0OS40MjkgNDE0Ljk1MkMyMzkuOTk4IDQxNC45NTIgMjMyLjkyNiA0MDcuNzY5IDIzMS45MDMgMzk4LjM4OEwyMjguNzI4IDM2OS4yN0MyMjYuNDQyIDM0NS42ODEgMjIyLjI5OCAzMjIuNzY3IDE5Ny45MTIgMzExLjg2QzE3MC4wOTUgMjk5LjQxOSAxNDIuMTQxIDI5NS4yODcgMTEyLjQwNCAzMDEuMTk4QzEwMi4xNjIgMzAzLjIzNCA5NS40NjcgMzEzLjEzOCA5Ny4zOTEzIDMyMy40MDZDMTAzLjQwNSAzNTUuNDk1IDEzNC44NTQgMzcwLjk4NSAxNjEuODQ0IDM4Mi43OTJDMTgxLjgzMyAzOTEuNTM1IDE5NC43NSA0MTEuMjg5IDE5NC43NSA0MzMuMTE1VjQ4OC41MzNDMTk0Ljc1IDQ5NC44NjcgMTg5LjYyMiA1MDAgMTgzLjI4OSA1MDBIMTE5LjIxNEM4MC42Mzc0IDUwMCA0NS45NzE2IDQ2OS4wNyA0NS4yOTc5IDQzMC40ODFWMjcyLjM0OUM0NS4yOTc5IDI1Ny4xOTQgNTUuMjE0MiAyNDMuODI0IDY5LjcxNjUgMjM5LjQyNloiIGZpbGw9InVybCgjcGFpbnQyX2xpbmVhcl8yMzI0XzYxODY5KSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzIzMjRfNjE4NjkiIHgxPSIyNDUuOTg2IiB5MT0iLTI3IiB4Mj0iNDI1LjQ5NiIgeTI9IjUwMi4zNzYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0Y1RDQ1RSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjk2MDAiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4=" }; var LegacyInjectedConnector = class extends Connector { constructor({ options }) { super(); __publicField(this, "_wallet"); __publicField(this, "_options"); this._options = options; } get id() { return this._options.id; } get name() { return this._options.name ?? this._wallet?.name ?? this._options.id; } get icon() { const defaultIcon = { dark: walletIcons2[this.id] || WALLET_NOT_FOUND_ICON_DARK2, light: walletIcons2[this.id] || WALLET_NOT_FOUND_ICON_LIGHT2 }; return this._options.icon || this._wallet?.icon || defaultIcon; } available() { this.ensureWallet(); return this._wallet !== void 0; } async chainId() { this.ensureWallet(); if (!this._wallet || !this._wallet.provider) { throw new ConnectorNotConnectedError(); } const chainIdHex = await this._wallet.provider.getChainId(); const chainId = BigInt(chainIdHex); return chainId; } async ready() { this.ensureWallet(); if (!this._wallet) return false; return await this._wallet.isPreauthorized(); } async connect(_args = {}) { this.ensureWallet(); if (!this._wallet) { throw new ConnectorNotFoundError(); } let accounts; try { accounts = await this._wallet.enable({ starknetVersion: "v5" }); } catch { throw new UserRejectedRequestError(); } if (!this._wallet.isConnected || !this._wallet.account || !accounts) { throw new UserRejectedRequestError(); } this._wallet.on( "accountsChanged", async (accounts2) => { if (!accounts2) return; await this.onAccountsChanged(accounts2); } ); this._wallet.on("networkChanged", (network) => { this.onNetworkChanged(network); }); await this.onAccountsChanged(accounts); const account = this._wallet.account.address; const chainId = await this.chainId(); this.emit("connect", { account, chainId }); return { account, chainId }; } async disconnect() { this.ensureWallet(); if (!this.available()) { throw new ConnectorNotFoundError(); } if (!this._wallet?.isConnected) { throw new UserNotConnectedError(); } this.emit("disconnect"); } async account() { this.ensureWallet(); if (!this._wallet || !this._wallet.account) { throw new ConnectorNotConnectedError(); } return this._wallet.account; } async request(call) { this.ensureWallet(); if (!this._wallet) { throw new ConnectorNotConnectedError(); } try { switch (call.type) { case "wallet_getPermissions": { if (this._wallet) { return [Permission2.ACCOUNTS]; } return []; } case "wallet_requestAccounts": { if (this._wallet.account) { return [this._wallet.account.address]; } return []; } case "wallet_requestChainId": { if (this._wallet.chainId) { return this._wallet.chainId; } return null; } case "wallet_addInvokeTransaction": { if (!this._wallet) { throw new Error("Send transaction failed"); } const calls = (call.params.calls ?? []).map( // @ts-ignore ({ calldata, contract_address, entry_point }) => ({ calldata, contractAddress: contract_address, entrypoint: entry_point }) ); return await this._wallet.account?.execute(calls); } default: { throw new Error(`Wallet API method ${call.type} is not supported.`); } } } catch { throw new UserRejectedRequestError(); } } ensureWallet() { const installed = getAvailableWallets(globalThis); const wallet = installed.filter((w) => w.id === this._options.id)[0]; if (wallet) { this._wallet = wallet; } } async onAccountsChanged(accounts) { let account; if (typeof accounts === "string") { account = accounts; } else { account = accounts[0]; } if (account) { const chainId = await this.chainId(); this.emit("change", { account, chainId }); } else { this.emit("disconnect"); } } onNetworkChanged(network) { switch (network) { // Argent case "SN_MAIN": this.emit("change", { chainId: mainnet.id }); break; case "SN_SEPOLIA": this.emit("change", { chainId: sepolia.id }); break; // Braavos case "mainnet-alpha": this.emit("change", { chainId: mainnet.id }); break; case "sepolia-alpha": this.emit("change", { chainId: sepolia.id }); break; default: this.emit("change", {}); break; } } }; function getAvailableWallets(obj) { return Object.values( Object.getOwnPropertyNames(obj).reduce((wallets, key) => { if (key.startsWith("starknet")) { const wallet = obj[key]; if (isWalletObject(wallet) && !wallets[wallet.id]) { wallets[wallet.id] = wallet; } } return wallets; }, {}) ); } function isWalletObject(wallet) { try { return wallet && [ // wallet's must have methods/members, see IStarknetWindowObject "request", "isConnected", "provider", "enable", "isPreauthorized", "on", "off", "version", "id", "name", "icon" ].every((key) => key in wallet); } catch (_err) { } return false; } // src/connectors/helpers.ts function ready() { return new InjectedConnector({ options: { id: "argentX", name: "Ready Wallet (formerly Argent)" } }); } var argent = ready; function braavos() { return new InjectedConnector({ options: { id: "braavos", name: "Braavos" } }); } function injected({ id }) { return new InjectedConnector({ options: { id } }); } function legacyInjected({ id }) { return new LegacyInjectedConnector({ options: { id } }); } // src/connectors/discovery.ts function useInjectedConnectors({ recommended, includeRecommended = "always", order = "alphabetical", shimLegacyConnectors = [] }) { const [injectedConnectors, setInjectedConnectors] = useState([]); const refreshConnectors = useCallback(() => { const wallets = scanObjectForWallets(window); const connectors2 = wallets.map((wallet) => { if (shimLegacyConnectors.includes(wallet.id)) { return legacyInjected({ id: wallet.id }); } return injected({ id: wallet.id }); }); setInjectedConnectors(connectors2); }, [shimLegacyConnectors.includes]); useEffect(() => { refreshConnectors(); }, [refreshConnectors]); const connectors = useMemo(() => { return mergeConnectors(injectedConnectors, recommended ?? [], { includeRecommended, order }); }, [injectedConnectors, recommended, includeRecommended, order]); return { connectors }; } function mergeConnectors(injected2, recommended, { includeRecommended, order }) { const recommendedIds = new Set(recommended.map((connector) => connector.id)); const shouldAddRecommended = includeRecommended === "always" || includeRecommended === "onlyIfNoConnectors" && injected2.length === 0; const allConnectors = []; if (shouldAddRecommended) { allConnectors.push(...recommended); } allConnectors.push( ...injected2.filter((connector) => !recommendedIds.has(connector.id)) ); if (order === "random") { return shuffle(allConnectors); } return allConnectors.sort((a, b) => a.id.localeCompare(b.id)); } function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } function scanObjectForWallets(obj) { return Object.values( Object.getOwnPropertyNames(obj).reduce((wallets, key) => { if (key.startsWith("starknet")) { const wallet = obj[key]; if (isWalletObject2(wallet) && !wallets[wallet.id]) { wallets[wallet.id] = wallet; } } return wallets; }, {}) ); } function isWalletObject2(wallet) { try { return wallet && [ // wallet's must have methods/members, see IStarknetWindowObject "request", "isConnected", "provider", "enable", "isPreauthorized", "on", "off", "version", "id", "name", "icon" ].every((key) => key in wallet); } catch (_err) { } return false; } // src/connectors/mock.ts import { Permission as Permission3 } from "@starknet-io/types-js"; import { devnet, mainnet as mainnet2 } from "@starknet-react/chains"; var MockConnector = class extends Connector { constructor({ accounts, options }) { super(); __publicField(this, "_accounts"); __publicField(this, "_accountIndex", 0); __publicField(this, "_connected", false); __publicField(this, "_chainId", devnet.id); __publicField(this, "options"); if (accounts.mainnet.length === 0 || accounts.sepolia.length === 0) { throw new Error("MockConnector: accounts must not be empty"); } this._accounts = accounts; this.options = options; } switchChain(chainId) { this._chainId = chainId; this._accountIndex = 0; let account; if (this.options.unifiedSwitchAccountAndChain) { account = this._account.address; } this.emit("change", { chainId, account }); if (this.options.emitChangeAccountOnChainSwitch ?? true) { this.switchAccount(this._accountIndex); } } switchAccount(accountIndex) { this._accountIndex = accountIndex; this.emit("change", { account: this._account.address }); } get id() { return this.options.id; } get name() { return this.options.name; } get icon() { return this.options.icon ?? ""; } available() { return this.options.available ?? true; } async chainId() { const chainIdHex = await this.request({ type: "wallet_requestChainId" }); const chainId = BigInt(chainIdHex); return chainId; } async ready() { const permissions = await this.request({ type: "wallet_getPermissions" }); if (!permissions?.includes(Permission3.ACCOUNTS)) { return false; } return true; } async connect() { if (this.options.failConnect) { throw new UserRejectedRequestError(); } this._connected = true; const accounts = await this.request({ type: "wallet_requestAccounts", params: { silent_mode: true } }); const chainId = await this.chainId(); const [account] = accounts; return { account, chainId }; } async disconnect() { this._connected = false; this.emit("disconnect"); } async request(call) { const { type, params } = call; if (!this.available()) { throw new ConnectorNotFoundError(); } if (this.options.rejectRequest) { throw new UserRejectedRequestError(); } switch (type) { case "wallet_requestChainId": return this._chainId.toString(); case "wallet_getPermissions": if (this._connected) return [Permission3.ACCOUNTS]; return []; case "wallet_requestAccounts": return [this._account.address]; case "wallet_addStarknetChain": return true; case "wallet_watchAsset": return true; case "wallet_switchStarknetChain": { if (!params) throw new Error("Params are missing"); const { chainId } = params; this.switchChain(BigInt(chainId)); return true; } case "wallet_addDeclareTransaction": { if (!params) throw new Error("Params are missing"); const { compiled_class_hash, contract_class, class_hash } = params; return await this._account.declare({ compiledClassHash: compiled_class_hash, contract: { ...contract_class, abi: JSON.parse(contract_class.abi) }, classHash: class_hash }); } case "wallet_addInvokeTransaction": { if (!params) throw new Error("Params are missing"); const { calls } = params; return await this._account.execute(transformCalls(calls)); } case "wallet_signTypedData": { if (!params) throw new Error("Params are missing"); const { domain, message, primaryType, types } = params; return await this._account.signMessage({ domain, message, primaryType, types }); } default: throw new Error("Unknown request type"); } } async account(_provider, _paymasterProvider) { if (!this.available()) { throw new ConnectorNotFoundError(); } if (!this._connected) { throw new ConnectorNotConnectedError(); } return this._account; } get _account() { let account; if (this._chainId === mainnet2.id) { account = this._accounts.mainnet[this._accountIndex]; } else { account = this._accounts.sepolia[this._accountIndex]; } if (!account) { throw new ConnectorNotConnectedError(); } return account; } }; function transformCalls(calls) { return calls.map( (call) => ({ contractAddress: call.contract_address, entrypoint: call.entry_point, calldata: call.calldata }) ); } // src/context/starknet.tsx import { mainnet as mainnet3, sepolia as sepolia2 } from "@starknet-react/chains"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { createContext, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useRef, useState as useState2 } from "react"; import { constants } from "starknet"; // src/providers/paymaster/paymasterrpc.ts import { PaymasterRpc } from "starknet"; function paymasterRpcProvider({ rpc }) { return (chain) => { const config = rpc(chain); if (!config) return null; const provider = new PaymasterRpc(config); return provider; }; } // src/providers/paymaster/avnu.ts function avnuPaymasterProvider({ apiKey }) { return paymasterRpcProvider({ rpc: (chain) => { const baseHttpUrl = chain.paymasterRpcUrls.avnu.http[0]; if (!baseHttpUrl) return null; return { nodeUrl: baseHttpUrl, headers: { "x-paymaster-api-key": apiKey ?? "" } }; } }); } // src/context/account.tsx import React, { useContext } from "react"; import { jsx } from "react/jsx-runtime"; var AccountContext = React.createContext({ account: void 0, address: void 0 }); function useStarknetAccount() { const { account, address } = useContext(AccountContext); return { account, address }; } function AccountProvider({ address, account, children }) { return /* @__PURE__ */ jsx(AccountContext.Provider, { value: { account, address }, children }); } // src/context/starknet.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var defaultQueryClient = new QueryClient(); var StarknetContext = createContext(void 0); function useStarknet() { const state = useContext2(StarknetContext); if (!state) { throw new Error( "useStarknet must be used within a StarknetProvider or StarknetConfig" ); } return state; } function useStarknetManager({ chains, provider, paymasterProvider, explorer, connectors = [], autoConnect = false, defaultChainId }) { const defaultChain = defaultChainId ? chains.find((c) => c.id === defaultChainId) ?? chains[0] : chains[0]; if (defaultChain === void 0) { throw new Error("Must provide at least one chain."); } const seen = /* @__PURE__ */ new Set(); for (const chain of chains) { if (seen.has(chain.id)) { throw new Error(`Duplicated chain id found: ${chain.id}`); } seen.add(chain.id); } const { chain: _, provider: defaultProvider } = providerForChain( defaultChain, provider ); const { paymasterProvider: defaultPaymasterProvider } = paymasterProviderForChain(defaultChain, paymasterProvider); const connectorRef = useRef(); const [state, setState] = useState2({ currentChain: defaultChain, currentProvider: defaultProvider, currentPaymasterProvider: defaultPaymasterProvider, connectors }); const updateChainAndProvider = useCallback2( ({ chainId }) => { if (!chainId) return; for (const chain of chains) { if (chain.id === chainId) { const { chain: newChain, provider: newProvider } = providerForChain( chain, provider ); const { paymasterProvider: newPaymasterProvider } = paymasterProviderForChain(chain, paymasterProvider); setState((state2) => ({ ...state2, currentChain: newChain, currentProvider: newProvider, currentPaymasterProvider: newPaymasterProvider })); return; } } }, [chains, provider, paymasterProvider] ); const handleConnectorChange = useCallback2( async ({ chainId, account: address }) => { if (chainId) { updateChainAndProvider({ chainId }); } if (address && connectorRef.current) { setState((state2) => ({ ...state2, currentAddress: address })); } }, [updateChainAndProvider] ); useEffect2(() => { if (!connectorRef.current) { setState((state2) => ({ ...state2, currentChain: defaultChain, currentProvider: providerForChain(defaultChain, provider).provider, currentPaymasterProvider: paymasterProviderForChain( defaultChain, paymasterProvider ).paymasterProvider })); } }, [defaultChain]); const disconnect = useCallback2(async () => { setState((state2) => ({ ...state2, currentAddress: void 0, currentProvider: defaultProvider, currentPaymasterProvider: defaultPaymasterProvider, currentChain: defaultChain })); if (autoConnect) { localStorage.removeItem("lastUsedConnector"); } if (!connectorRef.current) return; connectorRef.current.off("change", handleConnectorChange); connectorRef.current.off("disconnect", disconnect); try { await connectorRef.current.disconnect(); } catch { } connectorRef.current = void 0; }, [ autoConnect, handleConnectorChange, defaultProvider, defaultPaymasterProvider, defaultChain ]); const connect = useCallback2( async ({ connector }) => { if (!connector) { throw new Error("Must provide a connector."); } const needsListenerSetup = connectorRef.current?.id !== connector.id; if (needsListenerSetup) { connectorRef.current?.off("change", handleConnectorChange); connectorRef.current?.off("disconnect", disconnect); } try { const { chainId, account: address } = await connector.connect({ chainIdHint: defaultChain.id }); if (address !== state.currentAddress) { connectorRef.current = connector; setState((state2) => ({ ...state2, currentAddress: address })); } if (autoConnect) { localStorage.setItem("lastUsedConnector", connector.id); } if (needsListenerSetup) { connector.on("change", handleConnectorChange); connector.on("disconnect", disconnect); } updateChainAndProvider({ chainId }); } catch (err) { setState((state2) => ({ ...state2, error: new ConnectorNotFoundError() })); throw err; } }, [ autoConnect, state.currentAddress, defaultChain.id, handleConnectorChange, updateChainAndProvider, disconnect ] ); useEffect2(() => { async function tryAutoConnect(connectors2) { const lastConnectedConnectorId = localStorage.getItem("lastUsedConnector"); if (lastConnectedConnectorId === null) { return; } const lastConnectedConnector = connectors2.find( (connector) => connector.id === lastConnectedConnectorId ); if (lastConnectedConnector === void 0) { return; } try { if (!await lastConnectedConnector.ready()) { return; } connect({ connector: lastConnectedConnector }); } catch { } } if (autoConnect && !connectorRef.current) { tryAutoConnect(connectors); } }, []); return { address: state.currentAddress, provider: state.currentProvider, paymasterProvider: state.currentPaymasterProvider, chain: state.currentChain, connector: connectorRef.current, explorer, connect, disconnect, connectors, chains }; } function StarknetProvider({ chains, provider, paymasterProvider, connectors, explorer, autoConnect, queryClient, defaultChainId, children }) { const _paymasterProvider = paymasterProvider ?? avnuPaymasterProvider({}); const { account, address, ...state } = useStarknetManager({ chains, provider, paymasterProvider: _paymasterProvider, explorer, connectors, autoConnect, defaultChainId }); return /* @__PURE__ */ jsx2(QueryClientProvider, { client: queryClient ?? defaultQueryClient, children: /* @__PURE__ */ jsx2(StarknetContext.Provider, { value: state, children: /* @__PURE__ */ jsx2(AccountProvider, { address, account, children }) }) }); } function providerForChain(chain, factory) { const provider = factory(chain); if (provider) { return { chain, provider }; } throw new Error(`No provider found for chain ${chain.name}`); } function paymasterProviderForChain(chain, factory) { const paymasterProvider = factory(chain); if (paymasterProvider) { return { chain, paymasterProvider }; } throw new Error(`No paymaster provider found for chain ${chain.name}`); } function starknetChainId(chainId) { switch (chainId) { case mainnet3.id: return constants.StarknetChainId.SN_MAIN; case sepolia2.id: return constants.StarknetChainId.SN_SEPOLIA; default: return void 0; } } // src/context/index.tsx import { jsx as jsx3 } from "react/jsx-runtime"; function StarknetConfig({ children, ...config }) { return /* @__PURE__ */ jsx3(StarknetProvider, { ...config, children }); } // src/explorers/cartridge.ts var CartridgeExplorer = class { constructor(chain) { __publicField(this, "name", "Cartridge Explorer"); __publicField(this, "link"); this.link = chain.explorers?.["cartridge"]?.toString() ?? ""; } block(hashOrNumber) { return `${this.link}/block/${hashOrNumber.hash ?? hashOrNumber.number}`; } transaction(hash3) { return `${this.link}/tx/${hash3}`; } contract(address) { return `${this.link}/contract/${address}`; } class(hash3) { return `${this.link}/class/${hash3}`; } }; var cartridge = (chain) => { return new CartridgeExplorer(chain); }; // src/explorers/starkscan.ts var StarkscanExplorer = class { constructor(chain) { __publicField(this, "name", "Starkscan"); __publicField(this, "link"); this.link = chain.explorers?.["starkscan"]?.toString() ?? ""; } block(hashOrNumber) { return `${this.link}/block/${hashOrNumber.hash ?? hashOrNumber.number}`; } transaction(hash3) { return `${this.link}/tx/${hash3}`; } contract(address) { return `${this.link}/contract/${address}`; } class(hash3) { return `${this.link}/class/${hash3}`; } }; var starkscan = (chain) => { return new StarkscanExplorer(chain); }; // src/explorers/viewblock.ts var ViewblockExplorer = class { constructor(chain) { __publicField(this, "name", "Viewblock"); __publicField(this, "link"); this.link = chain.explorers?.["viewblock"]?.toString() ?? ""; } block(hashOrNumber) { if (hashOrNumber.hash && hashOrNumber.number === void 0) { throw new Error( "The viewblock explorer doesnt support hashes for blocks. Please provide a hash." ); } return `${this.link}/block/${hashOrNumber.number}`; } transaction(hash3) { return `${this.link}/tx/${hash3}`; } contract(address) { return `${this.link}/contract/${address}`; } class(hash3) { return `${this.link}/class/${hash3}`; } }; var viewblock = (chain) => { return new ViewblockExplorer(chain); }; // src/explorers/voyager.ts var VoyagerExplorer = class { constructor(chain) { __publicField(this, "name", "Voyager"); __publicField(this, "link"); this.link = chain.explorers?.["voyager"]?.toString() ?? ""; } block(hashOrNumber) { if (hashOrNumber.number !== void 0 && hashOrNumber.hash === void 0) { throw new Error( "The voyager explorer doesn't support numbers for blocks. Please provide a hash." ); } return `${this.link}/block/${hashOrNumber.hash}`; } transaction(hash3) { return `${this.link}/tx/${hash3}`; } contract(address) { return `${this.link}/contract/${address}`; } class(hash3) { return `${this.link}/class/${hash3}`; } }; var voyager = (chain) => { return new VoyagerExplorer(chain); }; // src/hooks/use-account.ts import { useCallback as useCallback3, useEffect as useEffect3, useState as useState3 } from "react"; // src/utils.ts import { validateAndParseAddress } from "starknet"; function getAddress(address) { return validateAndParseAddress(address); } // src/hooks/use-provider.ts function useProvider() { const { provider, paymasterProvider } = useStarknet(); return { provider, paymasterProvider }; } // src/hooks/use-account.ts function useAccount() { const { connector, chain } = useStarknet(); const { provider, paymasterProvider } = useProvider(); const { address: connectedAddress } = useStarknetAccount(); const [state, setState] = useState3( connectedAddress === void 0 ? { status: "disconnected" } : { status: "connected", connector, chainId: chain.id, account: void 0, address: getAddress(connectedAddress), isConnected: true, isConnecting: false, isDisconnected: false, isReconnecting: false } ); const refreshState = useCallback3(async () => { if (connector && provider && connectedAddress) { setState({ status: "connected", connector, chainId: chain.id, account: void 0, address: getAddress(connectedAddress), isConnected: true, isConnecting: false, isDisconnected: false, isReconnecting: false }); connector.account(provider, paymasterProvider).then( (connectedAccount) => setState((state2) => ({ ...state2, account: connectedAccount })) ); } else { return setState({ status: "disconnected", connector: void 0, chainId: void 0, account: void 0, address: void 0, isConnected: false, isConnecting: false, isDisconnected: true, isReconnecting: false }); } }, [provider, paymasterProvider, connector, chain.id, connectedAddress]); useEffect3(() => { refreshState(); }, [refreshState]); return state; } // src/hooks/use-wallet-request.ts import { useCallback as useCallback4 } from "react"; // src/query.ts import { useInfiniteQuery as useInfiniteQuery_, useMutation as useMutation_, useQuery as useQuery_ } from "@tanstack/react-query"; function useQuery(args) { const base = useQuery_({ ...args, structuralSharing: false }); return { data: base.data, error: base.error, status: base.status, isSuccess: base.isSuccess, isError: base.isError, isPending: base.isPending, fetchStatus: base.fetchStatus, isFetching: base.isFetching, isLoading: base.isLoading, refetch: base.refetch }; } function useMutation(args) { const base = useMutation_(args); return { data: base.data, error: base.error, reset: base.reset, isError: base.isError, isIdle: base.isIdle, isPending: base.isPending, isSuccess: base.isSuccess, isPaused: base.isPaused, mutate: base.mutate, mutateAsync: base.mutateAsync, status: base.status, variables: base.variables }; } function useInfiniteQuery(args) { const base = useInfiniteQuery_({ ...args, structuralSharing: false }); return { data: base.data, error: base.error, status: base.status, isSuccess: base.isSuccess, isError: base.isError, isPending: base.isPending, fetchStatus: base.fetchStatus, isFetching: base.isFetching, isLoading: base.isLoading, refetch: base.refetch, fetchNextPage: base.fetchNextPage, fetchPreviousPage: base.fetchPreviousPage, hasNextPage: base.hasNextPage, hasPreviousPage: base.hasPreviousPage, isFetchingNextPage: base.isFetchingNextPage, isFetchingPreviousPage: base.isFetchingPreviousPage }; } // src/hooks/use-wallet-request.ts function useWalletRequest(props) { const { connector } = useStarknet(); const { type, params, ...rest } = props; const { mutate, mutateAsync, ...result } = useMutation({ mutationKey: mutationKey({ type, params }), mutationFn: mutationFn({ connector }), ...rest }); const request = useCallback4( (args) => mutate(args ?? { type, params }), [mutate, type, params] ); const requestAsync = useCallback4( (args) => mutateAsync(args ?? { type, params }), [mutateAsync, type, params] ); return { request, requestAsync, ...result }; } function mutationKey({ type, params }) { return [{ entity: "walletRequest", type, params }]; } function mutationFn({ connector }) { return async ({ type, params }) => { if (!connector) throw new Error("No connector connected"); if (!type) throw new Error("Type is required"); return await connector.request({ type, params }); }; } // src/hooks/use-add-chain.ts function useAddChain(props) { const { params, ...rest } = props; const { request, requestAsync, ...result } = useWalletRequest({ type: "wallet_addStarknetChain", params, ...rest }); const addChain = (args) => { return request( args ? { params: args, type: "wallet_addStarknetChain" } : void 0 ); }; const addChainAsync = (args) => { return requestAsync( args ? { params: args, type: "wallet_addStarknetChain" } : void 0 ); }; return { addChain, addChainAsync, ...result }; } // src/hooks/use-balance.ts import { useMemo as useMemo3 } from "react"; import { BlockTag as BlockTag2, num as num2, shortString } from "starknet"; import { formatUnits } from "viem"; // src/hooks/use-contract.ts import { useMemo as useMemo2 } from "react"; import { Contract } from "starknet"; function useContract({ abi: abi2, address, provider: providedProvider }) { const { provider: currentProvider } = useStarknet(); const contract = useMemo2(() => { const provider = providedProvider ? providedProvider : currentProvider; if (abi2 && address && provider) { return new Contract({ abi: abi2, address, providerOrAccount: provider }).typedv2(abi2); } return void 0; }, [abi2, address, providedProvider, currentProvider]); return { contract }; } // src/hooks/use-invalidate-