@usebutr/evm 1.1.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +20 -4
- package/dist/index.d.ts +15 -72
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -193
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @usebutr/evm
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`488fe13`](https://github.com/pedroapfilho/usebutr/commit/488fe13fe9cddb99ff6c5d60f798140e6ac4076f)]:
|
|
8
|
+
- @usebutr/core@3.0.1
|
|
9
|
+
|
|
10
|
+
## 2.0.0
|
|
11
|
+
|
|
12
|
+
### Major Changes
|
|
13
|
+
|
|
14
|
+
- [#203](https://github.com/pedroapfilho/usebutr/pull/203) [`1263f86`](https://github.com/pedroapfilho/usebutr/commit/1263f8666afd43b4f7dbf8df1763709c3edf09d9) Thanks [@pedroapfilho](https://github.com/pedroapfilho)! - Adapters now say what they can do by having the method: `capabilities` is gone, and an optional method (`sendTx`, `signMessage`, `getBalance`, `switchChain`, …) exists only when it works for that wallet. No adapter returns a placeholder balance or a receipt that stays pending anymore.
|
|
15
|
+
|
|
16
|
+
- `sendTx(tx, { account, chain })` replaces `sendTx` and `sendTxToChain`, and `signMessage`, `signTransaction` and `getBalance` take options objects. `chain` is a `ChainBase`. An adapter either routes the call to that chain, switches the wallet to it, or rejects; none ignores it.
|
|
17
|
+
- An `account` the wallet does not expose now rejects instead of signing with the first account. `chain.name` is the chain's name, never the wallet's.
|
|
18
|
+
- `getAccounts()` resolves the active account first. `getAccount` and `switchAccount` are removed.
|
|
19
|
+
- `getSigner()` resolves a tagged `WalletSigner` (`eip1193`, `wallet-standard`, `walletconnect`, `ledger-*`, …), so it can be narrowed with `switch (signer.kind)` instead of cast.
|
|
20
|
+
- `createWalletManager(config, { initialState })` owns discovery, hydration and persistence, and works without React. `config.sources` replaces the `discovery`, `connectors` and `createConnector` props. `fromAdapters` registers WalletConnect, Ledger and hand-built adapters, which now also appear in `useDiscoveredWallets()`.
|
|
21
|
+
- `WalletManagerProvider` takes `config` and `initialState`. `useSigner(wallet)` and `useBalance(wallet, { token, account })` take the wallet entry itself, and id-taking hooks read the active wallet only when the id is omitted (`null` reads none). The hooks are `useWalletManager`, `useWalletState`, `useConnect`, `useWallet`, `useSelectedWallet` (now typed per platform), `useAccounts`, `useConnectionStatus`, `useIsHydrated`, `useIsReconnecting`, `useDiscoveredWallets`, `useConnectedWallets`, the `…ByPlatform` groupings, `useBalance` and `useSigner`.
|
|
22
|
+
- `manager.connect()` and `useConnect().connectAsync()` resolve the `ConnectedWallet` and reject with a `ConnectionError`, now an `Error` subclass with a `kind` and a new `WalletNotFound` kind. `useConnect().connect()` never rejects: the failure lands in its `error`.
|
|
23
|
+
- `WalletPersistence` is `load()` / `save(state)`, and `createWalletStorage` replaces `new WalletStorage`. Storage keys are unchanged.
|
|
24
|
+
- Chain registries (`EVM_CHAINS`, `SVM_CHAINS`, …, `CHAINS_BY_PLATFORM`) move to `@usebutr/core`, and `BITCOIN_CHAINS` gains `testnet4`. `@usebutr/wallets` loads every platform's signer kinds, so an app that imports only it can narrow `signer.kind`.
|
|
25
|
+
- `@usebutr/react` requires React 19, which its `use()` call already needed.
|
|
26
|
+
- WalletConnect requests on Solana, Sui and Bitcoin now carry their chain, so they no longer fall through to the first namespace in a multi-namespace session. Solana takes `SVM_CHAINS` chains and maps them to the genesis-hash ids WalletConnect sessions use.
|
|
27
|
+
- Ledger's Solana `signTransaction` returns the full signed transaction, Sui signs the intent message, and Bitcoin `signMessage` returns a BIP-137 signature.
|
|
28
|
+
- `@usebutr/testing`'s fake adapter resolves a `signer` you pass instead of registering a test-only signer kind.
|
|
29
|
+
- `setAccount` selects an exposed account without changing any account's chain. Unknown accounts are ignored; chain changes come from the adapter.
|
|
30
|
+
- WalletConnect EVM events use the namespace in `session_event`, including empty account lists that end the connection. Local chain switches still update the manager.
|
|
31
|
+
- Failed persistence saves wait for every key write to finish before reporting failure, so delayed writes cannot overwrite a later disconnect.
|
|
32
|
+
- `@usebutr/svm/transaction` provides the shared legacy/v0 signing codec used by Ledger and WalletConnect, with consistent layout and signature validation.
|
|
33
|
+
|
|
34
|
+
See the migration guide at https://docs.usebutr.com/migration.
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [[`1263f86`](https://github.com/pedroapfilho/usebutr/commit/1263f8666afd43b4f7dbf8df1763709c3edf09d9), [`5d1f234`](https://github.com/pedroapfilho/usebutr/commit/5d1f23403263f7a1f8a48be061727972fe749b5f)]:
|
|
39
|
+
- @usebutr/core@3.0.0
|
|
40
|
+
|
|
3
41
|
## 1.1.1
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -11,22 +11,38 @@ connection-state library. Your application owns the picker UI and chain client.
|
|
|
11
11
|
npm install @usebutr/react @usebutr/core @usebutr/evm zustand
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
React
|
|
14
|
+
React 19 is a peer dependency of the provider. Discovery does not render a connect modal; add your picker as the provider child. `discoverEvmAdapters` (EIP-6963) and `discoverInjectedAdapter` (the legacy `window.ethereum` fallback) are wallet sources as-is; `autoDiscovery()` from `@usebutr/wallets` combines both with the other platforms.
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
18
|
```tsx
|
|
19
19
|
import type { ReactNode } from "react";
|
|
20
|
-
import {
|
|
20
|
+
import type { WalletManagerConfig } from "@usebutr/core";
|
|
21
21
|
import { discoverEvmAdapters } from "@usebutr/evm";
|
|
22
22
|
import { WalletManagerProvider } from "@usebutr/react";
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const config: WalletManagerConfig = { sources: [discoverEvmAdapters] };
|
|
25
|
+
|
|
25
26
|
export const WalletProvider = ({ children }: { children: ReactNode }) => (
|
|
26
|
-
<WalletManagerProvider
|
|
27
|
+
<WalletManagerProvider config={config}>{children}</WalletManagerProvider>
|
|
27
28
|
);
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
Every EVM adapter defines `requestAccounts`, `switchChain`, `signMessage`, `sendTx`, `getBalance`, `getTransactionReceipt` and `subscribe`. `getSigner()` resolves `{ kind: "eip1193", provider }` for your own viem or ethers client. Chain registries (`EVM_CHAINS`, `EVM_CHAINS_LIST`) live in `@usebutr/core`.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import type { ConnectedWallet } from "@usebutr/core";
|
|
35
|
+
import { EVM_CHAINS } from "@usebutr/core";
|
|
36
|
+
|
|
37
|
+
// `sendTx` switches the wallet to `chain` first when it is elsewhere, and
|
|
38
|
+
// sends from `account`, which must be one the wallet exposes.
|
|
39
|
+
export const pay = (wallet: ConnectedWallet<"evm">, to: string) =>
|
|
40
|
+
wallet.connector.sendTx?.(
|
|
41
|
+
{ to, value: 10_000_000_000_000_000n },
|
|
42
|
+
{ account: wallet.account, chain: EVM_CHAINS.base },
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
30
46
|
## Documentation
|
|
31
47
|
|
|
32
48
|
- [Package reference](https://docs.usebutr.com/api/evm)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EvmAdapter, PlatformDiscoverer } from "@usebutr/core";
|
|
2
2
|
//#region src/eip1193.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Declared inline rather than taken from `viem`, which would expand butr's
|
|
@@ -39,7 +39,7 @@ type Eip6963AnnounceEvent = CustomEvent<Eip6963ProviderDetail>;
|
|
|
39
39
|
//#region src/eip6963.d.ts
|
|
40
40
|
declare const ANNOUNCE_EVENT = "eip6963:announceProvider";
|
|
41
41
|
declare const REQUEST_EVENT = "eip6963:requestProvider";
|
|
42
|
-
type AdapterCallback = (adapter:
|
|
42
|
+
type AdapterCallback = (adapter: EvmAdapter, info: Eip6963ProviderInfo) => void;
|
|
43
43
|
type DiscoverOptions = {
|
|
44
44
|
/** Event target to listen on. Defaults to `window` in browser/RN/
|
|
45
45
|
* SSR'd environments; tests can pass a fresh `new EventTarget()` to
|
|
@@ -64,7 +64,7 @@ declare const chainIdDecimalToHex: (dec: string) => string;
|
|
|
64
64
|
* implement and silently ignore, so their own auto-reconnect may outlive it.
|
|
65
65
|
* `getBalance()` labels the native balance `"ETH"` on every EVM chain.
|
|
66
66
|
*/
|
|
67
|
-
declare const buildEvmAdapter: (info: Eip6963ProviderInfo, provider: Eip1193Provider) =>
|
|
67
|
+
declare const buildEvmAdapter: (info: Eip6963ProviderInfo, provider: Eip1193Provider) => EvmAdapter;
|
|
68
68
|
//#endregion
|
|
69
69
|
//#region src/injected.d.ts
|
|
70
70
|
/**
|
|
@@ -95,72 +95,16 @@ declare global {
|
|
|
95
95
|
ethereum?: Partial<Eip1193Provider>;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
/** Structural check for code that holds a provider of unknown origin, such
|
|
99
|
+
* as `window.ethereum`. A butr signer narrows on `kind === "eip1193"`
|
|
100
|
+
* instead. */
|
|
101
|
+
declare const isEip1193Provider: (value: unknown) => value is Eip1193Provider;
|
|
99
102
|
/**
|
|
100
103
|
* Last-resort path for the long tail of EVM wallets that expose only
|
|
101
104
|
* `window.ethereum` and never announce via EIP-6963. The emitted adapter
|
|
102
105
|
* carries `rdns: "injected:legacy"` so consumers can tell it apart.
|
|
103
106
|
*/
|
|
104
|
-
declare const discoverInjectedAdapter: (onAdapter: (adapter:
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region src/chains.d.ts
|
|
107
|
-
/**
|
|
108
|
-
* Common EVM chain registry keyed by CAIP-2 id. Useful for chain-
|
|
109
|
-
* switcher UIs. butr itself doesn't read this: `Connector.switchChain`
|
|
110
|
-
* accepts any `ChainBase`.
|
|
111
|
-
*/
|
|
112
|
-
declare const EVM_CHAINS: {
|
|
113
|
-
readonly arbitrum: {
|
|
114
|
-
readonly id: "eip155:42161";
|
|
115
|
-
readonly name: "Arbitrum One";
|
|
116
|
-
readonly namespace: "eip155";
|
|
117
|
-
readonly reference: "42161";
|
|
118
|
-
};
|
|
119
|
-
readonly base: {
|
|
120
|
-
readonly id: "eip155:8453";
|
|
121
|
-
readonly name: "Base";
|
|
122
|
-
readonly namespace: "eip155";
|
|
123
|
-
readonly reference: "8453";
|
|
124
|
-
};
|
|
125
|
-
readonly bsc: {
|
|
126
|
-
readonly id: "eip155:56";
|
|
127
|
-
readonly name: "BNB Smart Chain";
|
|
128
|
-
readonly namespace: "eip155";
|
|
129
|
-
readonly reference: "56";
|
|
130
|
-
};
|
|
131
|
-
readonly ethereum: {
|
|
132
|
-
readonly id: "eip155:1";
|
|
133
|
-
readonly name: "Ethereum";
|
|
134
|
-
readonly namespace: "eip155";
|
|
135
|
-
readonly reference: "1";
|
|
136
|
-
};
|
|
137
|
-
readonly optimism: {
|
|
138
|
-
readonly id: "eip155:10";
|
|
139
|
-
readonly name: "Optimism";
|
|
140
|
-
readonly namespace: "eip155";
|
|
141
|
-
readonly reference: "10";
|
|
142
|
-
};
|
|
143
|
-
readonly polygon: {
|
|
144
|
-
readonly id: "eip155:137";
|
|
145
|
-
readonly name: "Polygon";
|
|
146
|
-
readonly namespace: "eip155";
|
|
147
|
-
readonly reference: "137";
|
|
148
|
-
};
|
|
149
|
-
readonly sepolia: {
|
|
150
|
-
readonly id: "eip155:11155111";
|
|
151
|
-
readonly name: "Sepolia";
|
|
152
|
-
readonly namespace: "eip155";
|
|
153
|
-
readonly reference: "11155111";
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
declare const EVM_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
157
|
-
//#endregion
|
|
158
|
-
//#region src/capabilities.d.ts
|
|
159
|
-
declare const EIP6963_RDNS_WITH_REQUEST_ACCOUNTS: Set<string>;
|
|
160
|
-
type Eip6963CapabilityInput = {
|
|
161
|
-
rdns: string;
|
|
162
|
-
};
|
|
163
|
-
declare const resolveEip6963Capabilities: (input: Eip6963CapabilityInput) => WalletCapabilities;
|
|
107
|
+
declare const discoverInjectedAdapter: (onAdapter: (adapter: EvmAdapter) => void, options?: InjectedDiscoveryOptions) => (() => void);
|
|
164
108
|
//#endregion
|
|
165
109
|
//#region src/discoverer.d.ts
|
|
166
110
|
/**
|
|
@@ -170,16 +114,15 @@ declare const resolveEip6963Capabilities: (input: Eip6963CapabilityInput) => Wal
|
|
|
170
114
|
declare const evmDiscoverer: PlatformDiscoverer;
|
|
171
115
|
//#endregion
|
|
172
116
|
//#region src/signer-augmentation.d.ts
|
|
173
|
-
/**
|
|
174
|
-
*
|
|
175
|
-
* `packages/core/src/types/signer.ts` for why); this only changes what
|
|
176
|
-
* `SignerForPlatform["evm"]` evaluates to.
|
|
177
|
-
*/
|
|
117
|
+
/** Every EVM adapter built on an EIP-1193 provider (injected, EIP-6963,
|
|
118
|
+
* WalletConnect's EVM namespace) hands back that provider. */
|
|
178
119
|
declare module "@usebutr/core" {
|
|
179
|
-
interface
|
|
180
|
-
|
|
120
|
+
interface WalletSignerRegistry {
|
|
121
|
+
eip1193: {
|
|
122
|
+
provider: Eip1193Provider;
|
|
123
|
+
};
|
|
181
124
|
}
|
|
182
125
|
}
|
|
183
126
|
//#endregion
|
|
184
|
-
export { ANNOUNCE_EVENT,
|
|
127
|
+
export { ANNOUNCE_EVENT, type Eip1193Listener, type Eip1193Object, type Eip1193Provider, type Eip1193RequestArgs, type Eip1193Value, type Eip6963AnnounceEvent, type Eip6963ProviderDetail, type Eip6963ProviderInfo, GENERIC_INJECTED_ICON, type InjectedDiscoveryOptions, REQUEST_EVENT, buildEvmAdapter, chainIdDecimalToHex, chainIdHexToDecimal, discoverEvmAdapters, discoverInjectedAdapter, evmDiscoverer, formatEther, isEip1193Provider };
|
|
185
128
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/eip1193.ts","../src/eip6963.ts","../src/evm-balance.ts","../src/eip6963-adapter.ts","../src/injected.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["_0"],"sources":["../src/eip1193.ts","../src/eip6963.ts","../src/evm-balance.ts","../src/eip6963-adapter.ts","../src/injected.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;;;;;KAMK;GAAmB,cAAc;;KACjC,2DAMD,aACA,cAAc,gBACd;KAEC;EACH;EACA,SAAS,cAAc,gBAAgB;;KAGpC,sBAAsB,MAAM,cAAc;KAE1C;EACH,KAAK,eAAe,UAAU;EAC9B,iBAAiB,eAAe,UAAU;EAC1C,UAAU,MAAM,uBAAuB,QAAQ;;KAG5C;;EAEH;;EAEA;;;EAGA;;EAEA;;KAGG;EACH,MAAM;EACN,UAAU;;KAGP,uBAAuB,YAAY;;;cC1ClC;cACA;KAED,mBAAmB,SAAS,YAAY,MAAM;KAE9C;;;;EAIH,SAAS;;;;;;;cAmDL,sBAAmB,WACZ,iBAAe,UACjB;;;cClCL,cAAW;;;cCUX,sBAAmB;cACnB,sBAAmB;;;;;;cAyCnB,kBAAe,MAAU,qBAAmB,UAAY,oBAAkB;;;;;;;;cC3E1E;KAKD;;;;;;EAMH;;;;;EAKA;;EAEA;IAAW,WAAW,QAAQ;;;QAGxB;YAEI;IACR,WAAW,QAAQ;;;;;;cAOjB,oBAAiB,mBAAqB,SAAS;;;;;;cAoB/C,0BAAuB,YACf,SAAS,qBAAmB,UAC/B;;;;;;;cCtDL,eAAe;;;;;;YCHT;IACR;MAAW,UAAU"}
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EVM_CHAINS_LIST, buildAccount, bytesToHexPrefixed, hexToBytes, resolveChain, sanitizeIcon } from "@usebutr/core";
|
|
2
2
|
|
|
3
|
-
//#region src/capabilities.ts
|
|
4
|
-
const EIP6963_RDNS_WITH_REQUEST_ACCOUNTS = /* @__PURE__ */ new Set(["io.metamask"]);
|
|
5
|
-
const resolveEip6963Capabilities = (input) => ({
|
|
6
|
-
getBalance: true,
|
|
7
|
-
getTransactionReceipt: true,
|
|
8
|
-
requestAccounts: EIP6963_RDNS_WITH_REQUEST_ACCOUNTS.has(input.rdns),
|
|
9
|
-
sendTransaction: true,
|
|
10
|
-
signIn: false,
|
|
11
|
-
signMessage: true,
|
|
12
|
-
signTransaction: false,
|
|
13
|
-
subscribe: true,
|
|
14
|
-
switchAccount: false,
|
|
15
|
-
switchChain: true
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
3
|
//#region src/eip1193.ts
|
|
20
4
|
/** `provider.request` is typed `unknown` by design; these helpers narrow
|
|
21
5
|
* the well-known EVM RPC shapes at the boundary with runtime guards so
|
|
@@ -33,7 +17,7 @@ const requestStringArray = async (provider, args) => {
|
|
|
33
17
|
|
|
34
18
|
//#endregion
|
|
35
19
|
//#region src/evm-balance.ts
|
|
36
|
-
const HEX_PREFIX
|
|
20
|
+
const HEX_PREFIX = "0x";
|
|
37
21
|
const ETH_DECIMALS = 18n;
|
|
38
22
|
const ERC20_BALANCE_OF_SELECTOR = "0x70a08231";
|
|
39
23
|
const ERC20_DECIMALS_SELECTOR = "0x313ce567";
|
|
@@ -54,14 +38,14 @@ const formatUnits = (raw, decimals) => {
|
|
|
54
38
|
const formatEther = (wei) => formatUnits(wei, Number(ETH_DECIMALS));
|
|
55
39
|
const padAddressForCall = (address) => address.replace(new RegExp("^0x", "v"), "").toLowerCase().padStart(64, "0");
|
|
56
40
|
const decodeAbiString = (hex) => {
|
|
57
|
-
const clean = hex.startsWith(HEX_PREFIX
|
|
41
|
+
const clean = hex.startsWith(HEX_PREFIX) ? hex.slice(2) : hex;
|
|
58
42
|
if (clean.length === 0) return "";
|
|
59
43
|
if (clean.length >= 128) {
|
|
60
44
|
const lengthHex = clean.slice(64, 128);
|
|
61
45
|
const length = Number(BigInt(`0x${lengthHex}`));
|
|
62
|
-
if (length > 0 && clean.length >= 128 + length * 2) return new TextDecoder().decode(hexToBytes
|
|
46
|
+
if (length > 0 && clean.length >= 128 + length * 2) return new TextDecoder().decode(hexToBytes(clean.slice(128, 128 + length * 2)));
|
|
63
47
|
}
|
|
64
|
-
const bytes = hexToBytes
|
|
48
|
+
const bytes = hexToBytes(clean.slice(0, 64));
|
|
65
49
|
let end = bytes.length;
|
|
66
50
|
while (end > 0 && bytes[end - 1] === 0) end -= 1;
|
|
67
51
|
return new TextDecoder().decode(bytes.subarray(0, end));
|
|
@@ -115,69 +99,73 @@ const readEvmBalance = async (provider, address, tokenAddress) => {
|
|
|
115
99
|
|
|
116
100
|
//#endregion
|
|
117
101
|
//#region src/eip6963-adapter.ts
|
|
118
|
-
const
|
|
102
|
+
const EVM_NAMESPACE = "eip155";
|
|
119
103
|
const toStringArray = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
if (value
|
|
124
|
-
if (typeof value
|
|
125
|
-
const result = {};
|
|
126
|
-
for (const [key, nested] of Object.entries(value)) result[key] = nested === void 0 ? void 0 : toEip1193Value(nested);
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
return value;
|
|
130
|
-
};
|
|
131
|
-
const withFrom = (tx, from) => {
|
|
132
|
-
if (typeof tx === "string" || tx instanceof Uint8Array) return tx;
|
|
104
|
+
/** JSON-RPC cannot carry a `bigint`, so quantities go out as `0x` hex. */
|
|
105
|
+
const encodeValue = (value) => {
|
|
106
|
+
if (typeof value === "bigint") return `0x${value.toString(16)}`;
|
|
107
|
+
if (Array.isArray(value)) return value.map(encodeValue);
|
|
108
|
+
if (typeof value !== "object" || value === null) return value;
|
|
133
109
|
const result = {};
|
|
134
|
-
for (const [key,
|
|
135
|
-
if (from !== void 0) result.from = from;
|
|
110
|
+
for (const [key, nested] of Object.entries(value)) result[key] = nested === void 0 ? void 0 : encodeValue(nested);
|
|
136
111
|
return result;
|
|
137
112
|
};
|
|
138
113
|
const chainIdHexToDecimal = (hex) => BigInt(hex).toString(10);
|
|
139
|
-
const chainIdDecimalToHex = (dec) =>
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
};
|
|
148
|
-
};
|
|
149
|
-
const buildEvmAccount = (address, chain) => ({
|
|
150
|
-
chain,
|
|
151
|
-
id: `${chain.id}:${address.toLowerCase()}`,
|
|
152
|
-
walletAddress: address
|
|
153
|
-
});
|
|
154
|
-
/** Rejections propagate: `getAccount`/`getAccounts` surface the wallet's
|
|
155
|
-
* own provider error, while the `subscribe` bridge swallows it because a
|
|
156
|
-
* later event retries synchronization. */
|
|
157
|
-
const readAccountState = async (provider, walletName, options = {}) => {
|
|
158
|
-
const accounts = options.accounts ?? await requestStringArray(provider, { method: "eth_accounts" });
|
|
159
|
-
if (accounts.length === 0) return null;
|
|
160
|
-
const chainIdHex = options.chainIdHex ?? await requestString(provider, { method: "eth_chainId" });
|
|
114
|
+
const chainIdDecimalToHex = (dec) => `0x${BigInt(dec).toString(16)}`;
|
|
115
|
+
const evmChainFromHex = (chainIdHex) => resolveChain(`${EVM_NAMESPACE}:${chainIdHexToDecimal(chainIdHex)}`, EVM_CHAINS_LIST);
|
|
116
|
+
/** Rejections propagate: `getAccounts` surfaces the wallet's own provider
|
|
117
|
+
* error, while the `subscribe` bridge swallows it because a later event
|
|
118
|
+
* retries synchronization. */
|
|
119
|
+
const readAccounts = async (provider, known = {}) => {
|
|
120
|
+
const addresses = known.addresses ?? await requestStringArray(provider, { method: "eth_accounts" });
|
|
121
|
+
if (addresses.length === 0) return [];
|
|
122
|
+
const chainIdHex = known.chainIdHex ?? await requestString(provider, { method: "eth_chainId" });
|
|
161
123
|
if (chainIdHex === null) throw new Error("Wallet returned a malformed eth_chainId response");
|
|
162
|
-
const chain =
|
|
163
|
-
|
|
164
|
-
const account = builtAccounts[0];
|
|
165
|
-
return account === void 0 ? null : {
|
|
166
|
-
account,
|
|
167
|
-
accounts: builtAccounts
|
|
168
|
-
};
|
|
124
|
+
const chain = evmChainFromHex(chainIdHex);
|
|
125
|
+
return addresses.map((address) => buildAccount(address, chain));
|
|
169
126
|
};
|
|
127
|
+
/** EIP-1474 / JSON-RPC codes wallets use for an unimplemented method.
|
|
128
|
+
* Coinbase wraps its own -32604 inside a -32603 `data.originalError`. */
|
|
129
|
+
const METHOD_NOT_SUPPORTED_CODES = /* @__PURE__ */ new Set([
|
|
130
|
+
4200,
|
|
131
|
+
-32601,
|
|
132
|
+
-32603,
|
|
133
|
+
-32604
|
|
134
|
+
]);
|
|
170
135
|
/**
|
|
171
136
|
* `disconnect` calls `wallet_revokePermissions`, which many wallets don't
|
|
172
137
|
* implement and silently ignore, so their own auto-reconnect may outlive it.
|
|
173
138
|
* `getBalance()` labels the native balance `"ETH"` on every EVM chain.
|
|
174
139
|
*/
|
|
175
140
|
const buildEvmAdapter = (info, provider) => {
|
|
141
|
+
/** The address to act as, in the wallet's own casing. Hex addresses are
|
|
142
|
+
* case-insensitive (EIP-55 casing is only a checksum), so they compare
|
|
143
|
+
* lowercased. */
|
|
144
|
+
const resolveAddress = async (account) => {
|
|
145
|
+
const exposed = await requestStringArray(provider, { method: "eth_accounts" });
|
|
146
|
+
if (account === void 0) {
|
|
147
|
+
const active = exposed.at(0);
|
|
148
|
+
if (active === void 0) throw new Error(`Wallet ${info.name} has no connected account`);
|
|
149
|
+
return active;
|
|
150
|
+
}
|
|
151
|
+
const wanted = account.walletAddress.toLowerCase();
|
|
152
|
+
const match = exposed.find((address) => address.toLowerCase() === wanted);
|
|
153
|
+
if (match === void 0) throw new Error(`Wallet ${info.name} does not expose account ${account.walletAddress}`);
|
|
154
|
+
return match;
|
|
155
|
+
};
|
|
156
|
+
const switchChain = async (chain) => {
|
|
157
|
+
if (chain.namespace !== EVM_NAMESPACE || !new RegExp("^\\d+$", "v").test(chain.reference)) throw new Error(`EVM adapter received non-EVM chain "${chain.id}". Pass a chain with namespace "${EVM_NAMESPACE}" and a numeric reference.`);
|
|
158
|
+
const target = chainIdDecimalToHex(chain.reference);
|
|
159
|
+
if ((await requestString(provider, { method: "eth_chainId" }))?.toLowerCase() === target) return;
|
|
160
|
+
await provider.request({
|
|
161
|
+
method: "wallet_switchEthereumChain",
|
|
162
|
+
params: [{ chainId: target }]
|
|
163
|
+
});
|
|
164
|
+
};
|
|
176
165
|
return {
|
|
177
|
-
capabilities: resolveEip6963Capabilities({ rdns: info.rdns }),
|
|
178
166
|
chainPlatform: "evm",
|
|
179
|
-
async connect(
|
|
180
|
-
if (
|
|
167
|
+
async connect(options) {
|
|
168
|
+
if (options?.silent === true) {
|
|
181
169
|
if ((await requestStringArray(provider, { method: "eth_accounts" })).length === 0) throw new Error("No authorized accounts for silent reconnect");
|
|
182
170
|
return;
|
|
183
171
|
}
|
|
@@ -191,22 +179,18 @@ const buildEvmAdapter = (info, provider) => {
|
|
|
191
179
|
});
|
|
192
180
|
} catch {}
|
|
193
181
|
},
|
|
194
|
-
|
|
195
|
-
|
|
182
|
+
getAccounts: () => readAccounts(provider),
|
|
183
|
+
async getBalance(options) {
|
|
184
|
+
return readEvmBalance(provider, await resolveAddress(options?.account), options?.token);
|
|
196
185
|
},
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (first === void 0) throw new Error("No connected account");
|
|
203
|
-
return readEvmBalance(provider, first, mint);
|
|
204
|
-
},
|
|
205
|
-
getSigner: () => Promise.resolve(provider),
|
|
206
|
-
async getTransactionReceipt(tx) {
|
|
186
|
+
getSigner: () => Promise.resolve({
|
|
187
|
+
kind: "eip1193",
|
|
188
|
+
provider
|
|
189
|
+
}),
|
|
190
|
+
async getTransactionReceipt(hash) {
|
|
207
191
|
const receipt = await provider.request({
|
|
208
192
|
method: "eth_getTransactionReceipt",
|
|
209
|
-
params: [
|
|
193
|
+
params: [hash]
|
|
210
194
|
});
|
|
211
195
|
if (receipt === null || typeof receipt !== "object" || !("status" in receipt)) return { status: "Pending" };
|
|
212
196
|
return { status: receipt.status === "0x1" ? "Success" : "Error" };
|
|
@@ -221,86 +205,66 @@ const buildEvmAdapter = (info, provider) => {
|
|
|
221
205
|
params: [{ eth_accounts: {} }]
|
|
222
206
|
});
|
|
223
207
|
} catch (error) {
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
await provider.request({ method: "eth_requestAccounts" });
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
throw error;
|
|
208
|
+
const outer = typeof error === "object" && error !== null ? error : {};
|
|
209
|
+
const data = "data" in outer ? outer.data : void 0;
|
|
210
|
+
const inner = typeof data === "object" && data !== null && "originalError" in data ? data.originalError : void 0;
|
|
211
|
+
if (!("code" in outer && METHOD_NOT_SUPPORTED_CODES.has(outer.code) || typeof inner === "object" && inner !== null && "code" in inner && METHOD_NOT_SUPPORTED_CODES.has(inner.code))) throw error;
|
|
212
|
+
await provider.request({ method: "eth_requestAccounts" });
|
|
233
213
|
}
|
|
234
214
|
},
|
|
235
|
-
async sendTx(tx,
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
method: "eth_sendTransaction",
|
|
239
|
-
params: [txWithFrom]
|
|
240
|
-
});
|
|
241
|
-
if (hash === null) throw new Error("Wallet returned no transaction hash");
|
|
242
|
-
return hash;
|
|
243
|
-
},
|
|
244
|
-
async sendTxToChain(tx, targetChainIdDecimal, account, cb) {
|
|
245
|
-
const current = await requestString(provider, { method: "eth_chainId" });
|
|
246
|
-
const targetHex = chainIdDecimalToHex(targetChainIdDecimal);
|
|
247
|
-
if (current?.toLowerCase() !== targetHex.toLowerCase()) {
|
|
248
|
-
await provider.request({
|
|
249
|
-
method: "wallet_switchEthereumChain",
|
|
250
|
-
params: [{ chainId: targetHex }]
|
|
251
|
-
});
|
|
252
|
-
cb?.();
|
|
253
|
-
}
|
|
254
|
-
const txWithFrom = withFrom(tx, account?.walletAddress);
|
|
215
|
+
async sendTx(tx, options) {
|
|
216
|
+
const from = await resolveAddress(options?.account);
|
|
217
|
+
if (options?.chain !== void 0) await switchChain(options.chain);
|
|
255
218
|
const hash = await requestString(provider, {
|
|
256
219
|
method: "eth_sendTransaction",
|
|
257
|
-
params: [
|
|
220
|
+
params: [encodeValue({
|
|
221
|
+
...tx,
|
|
222
|
+
from
|
|
223
|
+
})]
|
|
258
224
|
});
|
|
259
225
|
if (hash === null) throw new Error("Wallet returned no transaction hash");
|
|
260
226
|
return hash;
|
|
261
227
|
},
|
|
262
|
-
async signMessage(
|
|
263
|
-
|
|
264
|
-
if (signer === void 0 || signer === "") signer = (await requestStringArray(provider, { method: "eth_accounts" }))[0];
|
|
265
|
-
if (signer === void 0 || signer === "") throw new Error("No connected account");
|
|
228
|
+
async signMessage(message, options) {
|
|
229
|
+
const address = await resolveAddress(options?.account);
|
|
266
230
|
const signatureHex = await requestString(provider, {
|
|
267
231
|
method: "personal_sign",
|
|
268
|
-
params: [bytesToHexPrefixed(
|
|
232
|
+
params: [bytesToHexPrefixed(message), address]
|
|
269
233
|
});
|
|
270
234
|
if (signatureHex === null) throw new Error("Wallet returned a malformed personal_sign response");
|
|
271
235
|
return {
|
|
272
|
-
signature: hexToBytes
|
|
273
|
-
signedMessage:
|
|
236
|
+
signature: hexToBytes(signatureHex),
|
|
237
|
+
signedMessage: message
|
|
274
238
|
};
|
|
275
239
|
},
|
|
276
240
|
subscribe(listener) {
|
|
277
|
-
const
|
|
241
|
+
const synchronize = async (known) => {
|
|
278
242
|
try {
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
type: "
|
|
243
|
+
const accounts = await readAccounts(provider, known);
|
|
244
|
+
if (accounts.length > 0) listener({
|
|
245
|
+
accounts,
|
|
246
|
+
type: "accountsChanged"
|
|
283
247
|
});
|
|
284
248
|
} catch {}
|
|
285
249
|
};
|
|
286
250
|
const onAccountsChanged = (...args) => {
|
|
287
|
-
const
|
|
288
|
-
if (
|
|
251
|
+
const addresses = toStringArray(args[0]);
|
|
252
|
+
if (addresses.length === 0) {
|
|
289
253
|
listener({ type: "disconnected" });
|
|
290
254
|
return;
|
|
291
255
|
}
|
|
292
|
-
|
|
256
|
+
synchronize({ addresses });
|
|
293
257
|
};
|
|
294
258
|
const onChainChanged = (...args) => {
|
|
295
259
|
const [chainId] = args;
|
|
296
260
|
const chainIdHex = typeof chainId === "string" && chainId.length > 0 ? chainId : void 0;
|
|
297
|
-
|
|
261
|
+
synchronize({ chainIdHex });
|
|
298
262
|
};
|
|
299
263
|
const onDisconnect = () => {
|
|
300
264
|
listener({ type: "disconnected" });
|
|
301
265
|
};
|
|
302
266
|
const onConnect = () => {
|
|
303
|
-
|
|
267
|
+
synchronize();
|
|
304
268
|
};
|
|
305
269
|
provider.on("accountsChanged", onAccountsChanged);
|
|
306
270
|
provider.on("chainChanged", onChainChanged);
|
|
@@ -313,14 +277,7 @@ const buildEvmAdapter = (info, provider) => {
|
|
|
313
277
|
provider.removeListener("disconnect", onDisconnect);
|
|
314
278
|
};
|
|
315
279
|
},
|
|
316
|
-
|
|
317
|
-
const targetHex = chainIdDecimalToHex(chain.reference);
|
|
318
|
-
if ((await requestString(provider, { method: "eth_chainId" }))?.toLowerCase() === targetHex.toLowerCase()) return;
|
|
319
|
-
await provider.request({
|
|
320
|
-
method: "wallet_switchEthereumChain",
|
|
321
|
-
params: [{ chainId: targetHex }]
|
|
322
|
-
});
|
|
323
|
-
}
|
|
280
|
+
switchChain
|
|
324
281
|
};
|
|
325
282
|
};
|
|
326
283
|
|
|
@@ -336,9 +293,10 @@ const isEip6963AnnounceEvent = (event) => {
|
|
|
336
293
|
const { info, provider } = detail;
|
|
337
294
|
return typeof info === "object" && info !== null && "icon" in info && typeof info.icon === "string" && "name" in info && typeof info.name === "string" && "rdns" in info && typeof info.rdns === "string" && "uuid" in info && typeof info.uuid === "string" && typeof provider === "object" && provider !== null && "on" in provider && typeof provider.on === "function" && "removeListener" in provider && typeof provider.removeListener === "function" && "request" in provider && typeof provider.request === "function";
|
|
338
295
|
};
|
|
296
|
+
const windowGlobal = globalThis;
|
|
339
297
|
const resolveTarget = (target) => {
|
|
340
298
|
if (target !== void 0) return target;
|
|
341
|
-
return
|
|
299
|
+
return windowGlobal.window ?? null;
|
|
342
300
|
};
|
|
343
301
|
/**
|
|
344
302
|
* Spec: https://eips.ethereum.org/EIPS/eip-6963. Dedupe is by `info.rdns`
|
|
@@ -373,7 +331,10 @@ const discoverEvmAdapters = (onAdapter, options = {}) => {
|
|
|
373
331
|
*/
|
|
374
332
|
const GENERIC_INJECTED_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjEgMTJWN0g1YTIgMiAwIDAgMSAwLTQgaDE0djQiLz48cGF0aCBkPSJNMyA1djE0YTIgMiAwIDAgMCAyIDJoMTZ2LTVNMjEgMTIgaC0zYTIgMiAwIDAgMC0yIDJ2MGEyIDIgMCAwIDAgMiAyaDN6Ii8+PC9zdmc+";
|
|
375
333
|
const DEFAULT_SETTLE_MS = 150;
|
|
376
|
-
|
|
334
|
+
/** Structural check for code that holds a provider of unknown origin, such
|
|
335
|
+
* as `window.ethereum`. A butr signer narrows on `kind === "eip1193"`
|
|
336
|
+
* instead. */
|
|
337
|
+
const isEip1193Provider = (value) => typeof value === "object" && value !== null && "on" in value && typeof value.on === "function" && "removeListener" in value && typeof value.removeListener === "function" && "request" in value && typeof value.request === "function";
|
|
377
338
|
const readEthereum = (target) => {
|
|
378
339
|
const host = target === void 0 ? globalThis.window : target;
|
|
379
340
|
return isEip1193Provider(host?.ethereum) ? host.ethereum : null;
|
|
@@ -404,59 +365,6 @@ const discoverInjectedAdapter = (onAdapter, options = {}) => {
|
|
|
404
365
|
};
|
|
405
366
|
};
|
|
406
367
|
|
|
407
|
-
//#endregion
|
|
408
|
-
//#region src/chains.ts
|
|
409
|
-
/**
|
|
410
|
-
* Common EVM chain registry keyed by CAIP-2 id. Useful for chain-
|
|
411
|
-
* switcher UIs. butr itself doesn't read this: `Connector.switchChain`
|
|
412
|
-
* accepts any `ChainBase`.
|
|
413
|
-
*/
|
|
414
|
-
const EVM_CHAINS = {
|
|
415
|
-
arbitrum: {
|
|
416
|
-
id: "eip155:42161",
|
|
417
|
-
name: "Arbitrum One",
|
|
418
|
-
namespace: "eip155",
|
|
419
|
-
reference: "42161"
|
|
420
|
-
},
|
|
421
|
-
base: {
|
|
422
|
-
id: "eip155:8453",
|
|
423
|
-
name: "Base",
|
|
424
|
-
namespace: "eip155",
|
|
425
|
-
reference: "8453"
|
|
426
|
-
},
|
|
427
|
-
bsc: {
|
|
428
|
-
id: "eip155:56",
|
|
429
|
-
name: "BNB Smart Chain",
|
|
430
|
-
namespace: "eip155",
|
|
431
|
-
reference: "56"
|
|
432
|
-
},
|
|
433
|
-
ethereum: {
|
|
434
|
-
id: "eip155:1",
|
|
435
|
-
name: "Ethereum",
|
|
436
|
-
namespace: "eip155",
|
|
437
|
-
reference: "1"
|
|
438
|
-
},
|
|
439
|
-
optimism: {
|
|
440
|
-
id: "eip155:10",
|
|
441
|
-
name: "Optimism",
|
|
442
|
-
namespace: "eip155",
|
|
443
|
-
reference: "10"
|
|
444
|
-
},
|
|
445
|
-
polygon: {
|
|
446
|
-
id: "eip155:137",
|
|
447
|
-
name: "Polygon",
|
|
448
|
-
namespace: "eip155",
|
|
449
|
-
reference: "137"
|
|
450
|
-
},
|
|
451
|
-
sepolia: {
|
|
452
|
-
id: "eip155:11155111",
|
|
453
|
-
name: "Sepolia",
|
|
454
|
-
namespace: "eip155",
|
|
455
|
-
reference: "11155111"
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
const EVM_CHAINS_LIST = Object.values(EVM_CHAINS);
|
|
459
|
-
|
|
460
368
|
//#endregion
|
|
461
369
|
//#region src/discoverer.ts
|
|
462
370
|
/**
|
|
@@ -469,5 +377,5 @@ const evmDiscoverer = {
|
|
|
469
377
|
};
|
|
470
378
|
|
|
471
379
|
//#endregion
|
|
472
|
-
export { ANNOUNCE_EVENT,
|
|
380
|
+
export { ANNOUNCE_EVENT, GENERIC_INJECTED_ICON, REQUEST_EVENT, buildEvmAdapter, chainIdDecimalToHex, chainIdHexToDecimal, discoverEvmAdapters, discoverInjectedAdapter, evmDiscoverer, formatEther, isEip1193Provider };
|
|
473
381
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["HEX_PREFIX","hexToBytes","bytesToHex","hexToBytes"],"sources":["../src/capabilities.ts","../src/eip1193.ts","../src/evm-balance.ts","../src/eip6963-adapter.ts","../src/eip6963.ts","../src/injected.ts","../src/chains.ts","../src/discoverer.ts"],"sourcesContent":["import type { WalletCapabilities } from \"@usebutr/core\";\n\nconst EIP6963_RDNS_WITH_REQUEST_ACCOUNTS = new Set<string>([\n \"io.metamask\", // MetaMask: verified May 2026\n]);\n\ntype Eip6963CapabilityInput = { rdns: string };\n\nconst resolveEip6963Capabilities = (input: Eip6963CapabilityInput): WalletCapabilities => ({\n getBalance: true,\n getTransactionReceipt: true,\n requestAccounts: EIP6963_RDNS_WITH_REQUEST_ACCOUNTS.has(input.rdns),\n sendTransaction: true,\n signIn: false,\n signMessage: true,\n signTransaction: false,\n subscribe: true,\n switchAccount: false,\n switchChain: true,\n});\n\nexport type { Eip6963CapabilityInput };\nexport { EIP6963_RDNS_WITH_REQUEST_ACCOUNTS, resolveEip6963Capabilities };\n","/**\n * Declared inline rather than taken from `viem`, which would expand butr's\n * footprint. Loose on purpose: `request(...)` returns `unknown` and the\n * `request*` helpers narrow it at the boundary.\n */\n\ntype Eip1193Object = { [key: string]: Eip1193Value | undefined };\ntype Eip1193Value =\n | bigint\n | boolean\n | number\n | string\n | null\n | Uint8Array\n | ReadonlyArray<Eip1193Value>\n | Eip1193Object;\n\ntype Eip1193RequestArgs = {\n method: string;\n params?: ReadonlyArray<Eip1193Value> | Eip1193Object;\n};\n\ntype Eip1193Listener = (...args: ReadonlyArray<Eip1193Value | undefined>) => void;\n\ntype Eip1193Provider = {\n on: (event: string, listener: Eip1193Listener) => void;\n removeListener: (event: string, listener: Eip1193Listener) => void;\n request: (args: Eip1193RequestArgs) => Promise<Eip1193Value | undefined>;\n};\n\ntype Eip6963ProviderInfo = {\n /** Data URI or absolute URL pointing at the wallet's icon. */\n icon: string;\n /** Human-readable wallet name shown in pickers. */\n name: string;\n /** Reverse-DNS identifier: `io.metamask`, `io.rabby`, `app.phantom`.\n * Stable across versions, unique per wallet, used as the pool key. */\n rdns: string;\n /** Per-page UUID generated by the wallet. Not stable across reloads. */\n uuid: string;\n};\n\ntype Eip6963ProviderDetail = {\n info: Eip6963ProviderInfo;\n provider: Eip1193Provider;\n};\n\ntype Eip6963AnnounceEvent = CustomEvent<Eip6963ProviderDetail>;\n\n/** `provider.request` is typed `unknown` by design; these helpers narrow\n * the well-known EVM RPC shapes at the boundary with runtime guards so\n * call sites stay assertion-free. A malformed response is reported as\n * `null` / `[]` rather than a blank value, so call sites that cannot\n * proceed without a real one fail instead of inventing a default. */\nconst requestString = async (\n provider: Eip1193Provider,\n args: Eip1193RequestArgs,\n): Promise<string | null> => {\n const result = await provider.request(args);\n return typeof result === \"string\" ? result : null;\n};\n\nconst requestStringArray = async (\n provider: Eip1193Provider,\n args: Eip1193RequestArgs,\n): Promise<Array<string>> => {\n const result = await provider.request(args);\n return Array.isArray(result)\n ? result.filter((item): item is string => typeof item === \"string\")\n : [];\n};\n\nexport { requestString, requestStringArray };\n\nexport type {\n Eip1193Listener,\n Eip1193Object,\n Eip1193Provider,\n Eip1193RequestArgs,\n Eip1193Value,\n Eip6963AnnounceEvent,\n Eip6963ProviderDetail,\n Eip6963ProviderInfo,\n};\n","import { hexToBytes } from \"@usebutr/core\";\n\nimport type { Eip1193Provider } from \"./eip1193\";\nimport { requestString } from \"./eip1193\";\n\nconst HEX_PREFIX = \"0x\";\nconst ETH_DECIMALS = 18n;\nconst ERC20_BALANCE_OF_SELECTOR = \"0x70a08231\";\nconst ERC20_DECIMALS_SELECTOR = \"0x313ce567\";\nconst ERC20_SYMBOL_SELECTOR = \"0x95d89b41\";\n\n/** A failed read must not render as a confident zero balance. */\nconst requireHex = (hex: string | null, label: string): string => {\n if (hex === null) {\n throw new Error(`Wallet returned a malformed ${label} response`);\n }\n return hex;\n};\n\nconst formatUnits = (raw: bigint, decimals: number): string => {\n if (decimals === 0) {\n return raw.toString();\n }\n const unit = 10n ** BigInt(decimals);\n const integer = raw / unit;\n const remainder = raw % unit;\n if (remainder === 0n) {\n return integer.toString();\n }\n const fraction = remainder.toString().padStart(decimals, \"0\").replace(/0+$/v, \"\");\n return `${integer}.${fraction}`;\n};\n\nconst formatEther = (wei: bigint): string => formatUnits(wei, Number(ETH_DECIMALS));\n\nconst padAddressForCall = (address: string): string =>\n address.replace(/^0x/v, \"\").toLowerCase().padStart(64, \"0\");\n\nconst decodeAbiString = (hex: string): string => {\n const clean = hex.startsWith(HEX_PREFIX) ? hex.slice(2) : hex;\n if (clean.length === 0) {\n return \"\";\n }\n if (clean.length >= 128) {\n const lengthHex = clean.slice(64, 128);\n const length = Number(BigInt(`0x${lengthHex}`));\n if (length > 0 && clean.length >= 128 + length * 2) {\n return new TextDecoder().decode(hexToBytes(clean.slice(128, 128 + length * 2)));\n }\n }\n const bytes = hexToBytes(clean.slice(0, 64));\n let end = bytes.length;\n while (end > 0 && bytes[end - 1] === 0) {\n end -= 1;\n }\n return new TextDecoder().decode(bytes.subarray(0, end));\n};\n\nconst readEvmBalance = async (\n provider: Eip1193Provider,\n address: string,\n tokenAddress?: string,\n) => {\n if (tokenAddress === undefined || tokenAddress === \"\") {\n const balanceHex = await requestString(provider, {\n method: \"eth_getBalance\",\n params: [address, \"latest\"],\n });\n const value = BigInt(requireHex(balanceHex, \"eth_getBalance\"));\n return {\n decimals: Number(ETH_DECIMALS),\n formatted: formatEther(value),\n symbol: \"ETH\",\n value,\n };\n }\n\n const [balanceHex, decimalsHex, symbolHex] = await Promise.all([\n requestString(provider, {\n method: \"eth_call\",\n params: [\n { data: `${ERC20_BALANCE_OF_SELECTOR}${padAddressForCall(address)}`, to: tokenAddress },\n \"latest\",\n ],\n }),\n requestString(provider, {\n method: \"eth_call\",\n params: [{ data: ERC20_DECIMALS_SELECTOR, to: tokenAddress }, \"latest\"],\n }),\n requestString(provider, {\n method: \"eth_call\",\n params: [{ data: ERC20_SYMBOL_SELECTOR, to: tokenAddress }, \"latest\"],\n }),\n ]);\n const value = BigInt(requireHex(balanceHex, \"balanceOf()\"));\n const decimals = Number(BigInt(requireHex(decimalsHex, \"decimals()\")));\n return {\n decimals,\n formatted: formatUnits(value, decimals),\n symbol: decodeAbiString(symbolHex ?? \"\"),\n value,\n };\n};\n\nexport { formatEther, readEvmBalance };\n","import type {\n Account,\n ChainBase,\n TransactionInput,\n TransactionValue,\n WalletAdapter,\n} from \"@usebutr/core\";\nimport { bytesToHexPrefixed as bytesToHex, hexToBytes, sanitizeIcon } from \"@usebutr/core\";\n\nimport { resolveEip6963Capabilities } from \"./capabilities\";\nimport type {\n Eip1193Listener,\n Eip1193Object,\n Eip1193Provider,\n Eip1193Value,\n Eip6963ProviderInfo,\n} from \"./eip1193\";\nimport { requestString, requestStringArray } from \"./eip1193\";\nimport { readEvmBalance } from \"./evm-balance\";\n\nconst HEX_PREFIX = \"0x\";\n\nconst toStringArray = (value: Eip1193Value | undefined): Array<string> =>\n Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n\nconst toEip1193Value = (value: TransactionValue): Eip1193Value => {\n if (typeof value === \"function\") {\n throw new TypeError(\"EVM transactions cannot contain functions\");\n }\n if (Array.isArray(value)) {\n return value.map(toEip1193Value);\n }\n if (value instanceof Uint8Array) {\n return value;\n }\n if (typeof value === \"object\" && value !== null) {\n const result: Eip1193Object = {};\n for (const [key, nested] of Object.entries(value)) {\n result[key] = nested === undefined ? undefined : toEip1193Value(nested);\n }\n return result;\n }\n return value;\n};\n\nconst withFrom = (tx: TransactionInput, from?: string): Eip1193Value => {\n if (typeof tx === \"string\" || tx instanceof Uint8Array) {\n return tx;\n }\n const result: Eip1193Object = {};\n for (const [key, value] of Object.entries(tx)) {\n result[key] = value === undefined ? undefined : toEip1193Value(value);\n }\n if (from !== undefined) {\n result.from = from;\n }\n return result;\n};\n\nconst chainIdHexToDecimal = (hex: string): string => BigInt(hex).toString(10);\nconst chainIdDecimalToHex = (dec: string): string => `${HEX_PREFIX}${BigInt(dec).toString(16)}`;\n\nconst buildEvmChain = (chainIdHex: string, walletName: string): ChainBase => {\n const reference = chainIdHexToDecimal(chainIdHex);\n return {\n id: `eip155:${reference}`,\n name: walletName,\n namespace: \"eip155\",\n reference,\n };\n};\n\nconst buildEvmAccount = (address: string, chain: ChainBase): Account => ({\n chain,\n id: `${chain.id}:${address.toLowerCase()}`,\n walletAddress: address,\n});\n\ntype AccountStateOptions = {\n accounts?: Array<string>;\n chainIdHex?: string;\n};\n\n/** Rejections propagate: `getAccount`/`getAccounts` surface the wallet's\n * own provider error, while the `subscribe` bridge swallows it because a\n * later event retries synchronization. */\nconst readAccountState = async (\n provider: Eip1193Provider,\n walletName: string,\n options: AccountStateOptions = {},\n) => {\n const accounts =\n options.accounts ?? (await requestStringArray(provider, { method: \"eth_accounts\" }));\n if (accounts.length === 0) {\n return null;\n }\n const chainIdHex =\n options.chainIdHex ?? (await requestString(provider, { method: \"eth_chainId\" }));\n if (chainIdHex === null) {\n throw new Error(\"Wallet returned a malformed eth_chainId response\");\n }\n const chain = buildEvmChain(chainIdHex, walletName);\n const builtAccounts = accounts.map((address) => buildEvmAccount(address, chain));\n const account = builtAccounts[0];\n return account === undefined ? null : { account, accounts: builtAccounts };\n};\n\n/**\n * `disconnect` calls `wallet_revokePermissions`, which many wallets don't\n * implement and silently ignore, so their own auto-reconnect may outlive it.\n * `getBalance()` labels the native balance `\"ETH\"` on every EVM chain.\n */\nconst buildEvmAdapter = (info: Eip6963ProviderInfo, provider: Eip1193Provider): WalletAdapter => {\n return {\n capabilities: resolveEip6963Capabilities({ rdns: info.rdns }),\n chainPlatform: \"evm\",\n\n async connect(opts) {\n if (opts?.silent === true) {\n const accounts = await requestStringArray(provider, {\n method: \"eth_accounts\",\n });\n if (accounts.length === 0) {\n throw new Error(\"No authorized accounts for silent reconnect\");\n }\n return;\n }\n await provider.request({ method: \"eth_requestAccounts\" });\n },\n\n async disconnect() {\n try {\n await provider.request({\n method: \"wallet_revokePermissions\",\n params: [{ eth_accounts: {} }],\n });\n } catch {\n // Many wallets don't implement wallet_revokePermissions yet;\n // not a failure.\n }\n },\n\n async getAccount() {\n const state = await readAccountState(provider, info.name);\n return state?.account ?? null;\n },\n\n async getAccounts() {\n const state = await readAccountState(provider, info.name);\n return state?.accounts ?? [];\n },\n\n async getBalance(mint) {\n const accounts = await requestStringArray(provider, { method: \"eth_accounts\" });\n const first = accounts[0];\n if (first === undefined) {\n throw new Error(\"No connected account\");\n }\n return readEvmBalance(provider, first, mint);\n },\n\n getSigner: () => Promise.resolve(provider),\n\n async getTransactionReceipt(tx) {\n const receipt = await provider.request({\n method: \"eth_getTransactionReceipt\",\n params: [tx],\n });\n if (receipt === null || typeof receipt !== \"object\" || !(\"status\" in receipt)) {\n return { status: \"Pending\" };\n }\n return { status: receipt.status === \"0x1\" ? \"Success\" : \"Error\" };\n },\n\n icon: sanitizeIcon(info.icon),\n id: info.rdns,\n name: info.name,\n\n async requestAccounts() {\n try {\n await provider.request({\n method: \"wallet_requestPermissions\",\n params: [{ eth_accounts: {} }],\n });\n } catch (error) {\n const outerCode =\n typeof error === \"object\" && error !== null && \"code\" in error ? error.code : undefined;\n const errData =\n typeof error === \"object\" && error !== null && \"data\" in error ? error.data : undefined;\n const originalError =\n typeof errData === \"object\" && errData !== null && \"originalError\" in errData\n ? errData.originalError\n : undefined;\n const innerCode =\n typeof originalError === \"object\" && originalError !== null && \"code\" in originalError\n ? originalError.code\n : undefined;\n const isMethodNotSupported =\n outerCode === 4200 || // EIP-1474 \"method not supported\"\n outerCode === -32_601 || // JSON-RPC \"method not found\"\n outerCode === -32_603 || // JSON-RPC \"internal error\" (Coinbase wraps -32604 here)\n innerCode === 4200 ||\n innerCode === -32_601 ||\n innerCode === -32_604; // Coinbase's custom \"method not supported\"\n if (isMethodNotSupported) {\n await provider.request({ method: \"eth_requestAccounts\" });\n return;\n }\n throw error;\n }\n },\n\n async sendTx(tx, account) {\n const txWithFrom = withFrom(tx, account?.walletAddress);\n const hash = await requestString(provider, {\n method: \"eth_sendTransaction\",\n params: [txWithFrom],\n });\n if (hash === null) {\n throw new Error(\"Wallet returned no transaction hash\");\n }\n return hash;\n },\n\n async sendTxToChain(tx, targetChainIdDecimal, account, cb) {\n const current = await requestString(provider, { method: \"eth_chainId\" });\n const targetHex = chainIdDecimalToHex(targetChainIdDecimal);\n if (current?.toLowerCase() !== targetHex.toLowerCase()) {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: targetHex }],\n });\n cb?.();\n }\n const txWithFrom = withFrom(tx, account?.walletAddress);\n const hash = await requestString(provider, {\n method: \"eth_sendTransaction\",\n params: [txWithFrom],\n });\n if (hash === null) {\n throw new Error(\"Wallet returned no transaction hash\");\n }\n return hash;\n },\n\n async signMessage(msg, account) {\n let signer = account?.walletAddress;\n if (signer === undefined || signer === \"\") {\n const accounts = await requestStringArray(provider, { method: \"eth_accounts\" });\n signer = accounts[0];\n }\n if (signer === undefined || signer === \"\") {\n throw new Error(\"No connected account\");\n }\n const signatureHex = await requestString(provider, {\n method: \"personal_sign\",\n params: [bytesToHex(msg), signer],\n });\n if (signatureHex === null) {\n throw new Error(\"Wallet returned a malformed personal_sign response\");\n }\n return { signature: hexToBytes(signatureHex), signedMessage: msg };\n },\n\n subscribe(listener) {\n const synchronizeAccount = async (options?: AccountStateOptions) => {\n try {\n const state = await readAccountState(provider, info.name, options);\n if (state !== null) {\n listener({ ...state, type: \"accountChanged\" });\n }\n } catch {\n // EIP-1193 event reads are best-effort; a later event retries synchronization.\n }\n };\n\n const onAccountsChanged: Eip1193Listener = (...args) => {\n const accs = toStringArray(args[0]);\n if (accs.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n void synchronizeAccount({ accounts: accs });\n };\n\n const onChainChanged: Eip1193Listener = (...args) => {\n const [chainId] = args;\n // Some wallets emit a decimal number here instead of the EIP-1193\n // hex string; leaving it absent re-engages the eth_chainId read.\n const chainIdHex = typeof chainId === \"string\" && chainId.length > 0 ? chainId : undefined;\n void synchronizeAccount({ chainIdHex });\n };\n\n const onDisconnect: Eip1193Listener = () => {\n listener({ type: \"disconnected\" });\n };\n\n const onConnect: Eip1193Listener = () => {\n void synchronizeAccount();\n };\n\n provider.on(\"accountsChanged\", onAccountsChanged);\n provider.on(\"chainChanged\", onChainChanged);\n provider.on(\"connect\", onConnect);\n provider.on(\"disconnect\", onDisconnect);\n\n return () => {\n provider.removeListener(\"accountsChanged\", onAccountsChanged);\n provider.removeListener(\"chainChanged\", onChainChanged);\n provider.removeListener(\"connect\", onConnect);\n provider.removeListener(\"disconnect\", onDisconnect);\n };\n },\n\n async switchChain(chain) {\n const targetHex = chainIdDecimalToHex(chain.reference);\n const current = await requestString(provider, { method: \"eth_chainId\" });\n if (current?.toLowerCase() === targetHex.toLowerCase()) {\n return;\n }\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: targetHex }],\n });\n },\n };\n};\n\nexport { bytesToHexPrefixed as bytesToHex, hexToBytes } from \"@usebutr/core\";\nexport { formatEther } from \"./evm-balance\";\nexport { buildEvmAdapter, chainIdDecimalToHex, chainIdHexToDecimal };\n","import type { WalletAdapter } from \"@usebutr/core\";\n\nimport type { Eip6963AnnounceEvent, Eip6963ProviderInfo } from \"./eip1193\";\nimport { buildEvmAdapter } from \"./eip6963-adapter\";\n\nconst ANNOUNCE_EVENT = \"eip6963:announceProvider\";\nconst REQUEST_EVENT = \"eip6963:requestProvider\";\n\ntype AdapterCallback = (adapter: WalletAdapter, info: Eip6963ProviderInfo) => void;\n\ntype DiscoverOptions = {\n /** Event target to listen on. Defaults to `window` in browser/RN/\n * SSR'd environments; tests can pass a fresh `new EventTarget()` to\n * exercise the discovery loop without a DOM. */\n target?: EventTarget;\n};\n\nconst isEip6963AnnounceEvent = (event: Event): event is Eip6963AnnounceEvent => {\n if (!(\"detail\" in event)) {\n return false;\n }\n const detail: unknown = event.detail;\n if (typeof detail !== \"object\" || detail === null) {\n return false;\n }\n if (!(\"info\" in detail) || !(\"provider\" in detail)) {\n return false;\n }\n const { info, provider } = detail;\n return (\n typeof info === \"object\" &&\n info !== null &&\n \"icon\" in info &&\n typeof info.icon === \"string\" &&\n \"name\" in info &&\n typeof info.name === \"string\" &&\n \"rdns\" in info &&\n typeof info.rdns === \"string\" &&\n \"uuid\" in info &&\n typeof info.uuid === \"string\" &&\n typeof provider === \"object\" &&\n provider !== null &&\n \"on\" in provider &&\n typeof provider.on === \"function\" &&\n \"removeListener\" in provider &&\n typeof provider.removeListener === \"function\" &&\n \"request\" in provider &&\n typeof provider.request === \"function\"\n );\n};\n\nconst resolveTarget = (target?: EventTarget): EventTarget | null => {\n if (target !== undefined) {\n return target;\n }\n return globalThis.window ?? null;\n};\n\n/**\n * Spec: https://eips.ethereum.org/EIPS/eip-6963. Dedupe is by `info.rdns`\n * because `info.uuid` is regenerated per page load. The listener stays\n * attached for the session so wallets that boot late still register.\n */\nconst discoverEvmAdapters = (\n onAdapter: AdapterCallback,\n options: DiscoverOptions = {},\n): (() => void) => {\n const target = resolveTarget(options.target);\n if (!target) {\n return () => {};\n }\n\n const seen = new Set<string>();\n const handler = (event: Event) => {\n if (!isEip6963AnnounceEvent(event)) {\n return;\n }\n const { info, provider } = event.detail;\n if (info.rdns.length === 0) {\n return;\n }\n if (seen.has(info.rdns)) {\n return;\n }\n seen.add(info.rdns);\n onAdapter(buildEvmAdapter(info, provider), info);\n };\n\n target.addEventListener(ANNOUNCE_EVENT, handler);\n target.dispatchEvent(new Event(REQUEST_EVENT));\n\n return () => {\n target.removeEventListener(ANNOUNCE_EVENT, handler);\n };\n};\n\nexport { ANNOUNCE_EVENT, REQUEST_EVENT, discoverEvmAdapters };\n","import type { WalletAdapter, WalletSigner } from \"@usebutr/core\";\n\nimport type { Eip1193Provider, Eip6963ProviderInfo } from \"./eip1193\";\nimport { buildEvmAdapter } from \"./eip6963-adapter\";\n\n/**\n * Generic wallet icon (a stylised purse SVG, ~600 bytes). Used as\n * the fallback icon when an injected provider has no EIP-6963 info.\n * Inline rather than a network fetch so the picker doesn't flicker.\n */\nconst GENERIC_INJECTED_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjEgMTJWN0g1YTIgMiAwIDAgMSAwLTQgaDE0djQiLz48cGF0aCBkPSJNMyA1djE0YTIgMiAwIDAgMCAyIDJoMTZ2LTVNMjEgMTIgaC0zYTIgMiAwIDAgMC0yIDJ2MGEyIDIgMCAwIDAgMiAyaDN6Ii8+PC9zdmc+\";\n\nconst DEFAULT_SETTLE_MS = 150;\n\ntype InjectedDiscoveryOptions = {\n /**\n * Consulted before emitting: an already-registered EIP-6963 adapter means\n * the wallet is covered by the standards path and emitting would duplicate\n * it. Omit to always emit.\n */\n hasAnyEip6963Adapter?: () => boolean;\n /**\n * Most wallets announce within the first frame; 150ms leaves room for slow\n * announcements without stalling the picker.\n */\n settleMs?: number;\n /** Override the global `window` reference (tests, iframes). */\n target?: { ethereum?: Partial<Eip1193Provider> } | null;\n};\n\ndeclare global {\n // oxlint-disable-next-line typescript/consistent-type-definitions -- DOM globals require interface merging.\n interface Window {\n ethereum?: Partial<Eip1193Provider>;\n }\n}\n\nconst isEip1193Provider = (value: WalletSigner | undefined): value is Eip1193Provider =>\n value !== undefined &&\n \"on\" in value &&\n typeof value.on === \"function\" &&\n \"removeListener\" in value &&\n typeof value.removeListener === \"function\" &&\n \"request\" in value &&\n typeof value.request === \"function\";\n\nconst readEthereum = (target: InjectedDiscoveryOptions[\"target\"]): Eip1193Provider | null => {\n const host = target === undefined ? globalThis.window : target;\n return isEip1193Provider(host?.ethereum) ? host.ethereum : null;\n};\n\n/**\n * Last-resort path for the long tail of EVM wallets that expose only\n * `window.ethereum` and never announce via EIP-6963. The emitted adapter\n * carries `rdns: \"injected:legacy\"` so consumers can tell it apart.\n */\nconst discoverInjectedAdapter = (\n onAdapter: (adapter: WalletAdapter) => void,\n options: InjectedDiscoveryOptions = {},\n): (() => void) => {\n const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;\n let cancelled = false;\n const timer = setTimeout(() => {\n if (cancelled) {\n return;\n }\n if (options.hasAnyEip6963Adapter?.() === true) {\n return;\n }\n const provider = readEthereum(options.target);\n if (provider === null) {\n return;\n }\n const info: Eip6963ProviderInfo = {\n icon: GENERIC_INJECTED_ICON,\n name: \"Browser wallet\",\n rdns: \"injected:legacy\",\n uuid: \"injected:legacy\",\n };\n onAdapter(buildEvmAdapter(info, provider));\n }, settleMs);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n};\n\nexport type { InjectedDiscoveryOptions };\nexport { GENERIC_INJECTED_ICON, discoverInjectedAdapter, isEip1193Provider };\n","import type { ChainBase } from \"@usebutr/core\";\n\n/**\n * Common EVM chain registry keyed by CAIP-2 id. Useful for chain-\n * switcher UIs. butr itself doesn't read this: `Connector.switchChain`\n * accepts any `ChainBase`.\n */\nconst EVM_CHAINS = {\n arbitrum: {\n id: \"eip155:42161\",\n name: \"Arbitrum One\",\n namespace: \"eip155\",\n reference: \"42161\",\n },\n base: { id: \"eip155:8453\", name: \"Base\", namespace: \"eip155\", reference: \"8453\" },\n bsc: { id: \"eip155:56\", name: \"BNB Smart Chain\", namespace: \"eip155\", reference: \"56\" },\n ethereum: { id: \"eip155:1\", name: \"Ethereum\", namespace: \"eip155\", reference: \"1\" },\n optimism: { id: \"eip155:10\", name: \"Optimism\", namespace: \"eip155\", reference: \"10\" },\n polygon: { id: \"eip155:137\", name: \"Polygon\", namespace: \"eip155\", reference: \"137\" },\n sepolia: { id: \"eip155:11155111\", name: \"Sepolia\", namespace: \"eip155\", reference: \"11155111\" },\n} as const satisfies Record<string, ChainBase>;\n\nconst EVM_CHAINS_LIST: ReadonlyArray<ChainBase> = Object.values(EVM_CHAINS);\n\nexport { EVM_CHAINS, EVM_CHAINS_LIST };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverEvmAdapters } from \"./eip6963\";\nimport { discoverInjectedAdapter } from \"./injected\";\n\n/**\n * EIP-6963 is primary; the legacy `window.ethereum` fallback defers until\n * EIP-6963 has had a chance to fire.\n */\nconst evmDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) =>\n discoverInjectedAdapter(onAdapter, {\n hasAnyEip6963Adapter: opts.hasAnyPrimaryAdapter,\n }),\n },\n subscribe: discoverEvmAdapters,\n};\n\nexport { evmDiscoverer };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/eip1193.ts","../src/evm-balance.ts","../src/eip6963-adapter.ts","../src/eip6963.ts","../src/injected.ts","../src/discoverer.ts"],"sourcesContent":["/**\n * Declared inline rather than taken from `viem`, which would expand butr's\n * footprint. Loose on purpose: `request(...)` returns `unknown` and the\n * `request*` helpers narrow it at the boundary.\n */\n\ntype Eip1193Object = { [key: string]: Eip1193Value | undefined };\ntype Eip1193Value =\n | bigint\n | boolean\n | number\n | string\n | null\n | Uint8Array\n | ReadonlyArray<Eip1193Value>\n | Eip1193Object;\n\ntype Eip1193RequestArgs = {\n method: string;\n params?: ReadonlyArray<Eip1193Value> | Eip1193Object;\n};\n\ntype Eip1193Listener = (...args: ReadonlyArray<Eip1193Value | undefined>) => void;\n\ntype Eip1193Provider = {\n on: (event: string, listener: Eip1193Listener) => void;\n removeListener: (event: string, listener: Eip1193Listener) => void;\n request: (args: Eip1193RequestArgs) => Promise<Eip1193Value | undefined>;\n};\n\ntype Eip6963ProviderInfo = {\n /** Data URI or absolute URL pointing at the wallet's icon. */\n icon: string;\n /** Human-readable wallet name shown in pickers. */\n name: string;\n /** Reverse-DNS identifier: `io.metamask`, `io.rabby`, `app.phantom`.\n * Stable across versions, unique per wallet, used as the pool key. */\n rdns: string;\n /** Per-page UUID generated by the wallet. Not stable across reloads. */\n uuid: string;\n};\n\ntype Eip6963ProviderDetail = {\n info: Eip6963ProviderInfo;\n provider: Eip1193Provider;\n};\n\ntype Eip6963AnnounceEvent = CustomEvent<Eip6963ProviderDetail>;\n\n/** `provider.request` is typed `unknown` by design; these helpers narrow\n * the well-known EVM RPC shapes at the boundary with runtime guards so\n * call sites stay assertion-free. A malformed response is reported as\n * `null` / `[]` rather than a blank value, so call sites that cannot\n * proceed without a real one fail instead of inventing a default. */\nconst requestString = async (\n provider: Eip1193Provider,\n args: Eip1193RequestArgs,\n): Promise<string | null> => {\n const result = await provider.request(args);\n return typeof result === \"string\" ? result : null;\n};\n\nconst requestStringArray = async (\n provider: Eip1193Provider,\n args: Eip1193RequestArgs,\n): Promise<Array<string>> => {\n const result = await provider.request(args);\n return Array.isArray(result)\n ? result.filter((item): item is string => typeof item === \"string\")\n : [];\n};\n\nexport { requestString, requestStringArray };\n\nexport type {\n Eip1193Listener,\n Eip1193Object,\n Eip1193Provider,\n Eip1193RequestArgs,\n Eip1193Value,\n Eip6963AnnounceEvent,\n Eip6963ProviderDetail,\n Eip6963ProviderInfo,\n};\n","import { hexToBytes } from \"@usebutr/core\";\n\nimport type { Eip1193Provider } from \"./eip1193\";\nimport { requestString } from \"./eip1193\";\n\nconst HEX_PREFIX = \"0x\";\nconst ETH_DECIMALS = 18n;\nconst ERC20_BALANCE_OF_SELECTOR = \"0x70a08231\";\nconst ERC20_DECIMALS_SELECTOR = \"0x313ce567\";\nconst ERC20_SYMBOL_SELECTOR = \"0x95d89b41\";\n\n/** A failed read must not render as a confident zero balance. */\nconst requireHex = (hex: string | null, label: string): string => {\n if (hex === null) {\n throw new Error(`Wallet returned a malformed ${label} response`);\n }\n return hex;\n};\n\nconst formatUnits = (raw: bigint, decimals: number): string => {\n if (decimals === 0) {\n return raw.toString();\n }\n const unit = 10n ** BigInt(decimals);\n const integer = raw / unit;\n const remainder = raw % unit;\n if (remainder === 0n) {\n return integer.toString();\n }\n const fraction = remainder.toString().padStart(decimals, \"0\").replace(/0+$/v, \"\");\n return `${integer}.${fraction}`;\n};\n\nconst formatEther = (wei: bigint): string => formatUnits(wei, Number(ETH_DECIMALS));\n\nconst padAddressForCall = (address: string): string =>\n address.replace(/^0x/v, \"\").toLowerCase().padStart(64, \"0\");\n\nconst decodeAbiString = (hex: string): string => {\n const clean = hex.startsWith(HEX_PREFIX) ? hex.slice(2) : hex;\n if (clean.length === 0) {\n return \"\";\n }\n if (clean.length >= 128) {\n const lengthHex = clean.slice(64, 128);\n const length = Number(BigInt(`0x${lengthHex}`));\n if (length > 0 && clean.length >= 128 + length * 2) {\n return new TextDecoder().decode(hexToBytes(clean.slice(128, 128 + length * 2)));\n }\n }\n const bytes = hexToBytes(clean.slice(0, 64));\n let end = bytes.length;\n while (end > 0 && bytes[end - 1] === 0) {\n end -= 1;\n }\n return new TextDecoder().decode(bytes.subarray(0, end));\n};\n\nconst readEvmBalance = async (\n provider: Eip1193Provider,\n address: string,\n tokenAddress?: string,\n) => {\n if (tokenAddress === undefined || tokenAddress === \"\") {\n const balanceHex = await requestString(provider, {\n method: \"eth_getBalance\",\n params: [address, \"latest\"],\n });\n const value = BigInt(requireHex(balanceHex, \"eth_getBalance\"));\n return {\n decimals: Number(ETH_DECIMALS),\n formatted: formatEther(value),\n symbol: \"ETH\",\n value,\n };\n }\n\n const [balanceHex, decimalsHex, symbolHex] = await Promise.all([\n requestString(provider, {\n method: \"eth_call\",\n params: [\n { data: `${ERC20_BALANCE_OF_SELECTOR}${padAddressForCall(address)}`, to: tokenAddress },\n \"latest\",\n ],\n }),\n requestString(provider, {\n method: \"eth_call\",\n params: [{ data: ERC20_DECIMALS_SELECTOR, to: tokenAddress }, \"latest\"],\n }),\n requestString(provider, {\n method: \"eth_call\",\n params: [{ data: ERC20_SYMBOL_SELECTOR, to: tokenAddress }, \"latest\"],\n }),\n ]);\n const value = BigInt(requireHex(balanceHex, \"balanceOf()\"));\n const decimals = Number(BigInt(requireHex(decimalsHex, \"decimals()\")));\n return {\n decimals,\n formatted: formatUnits(value, decimals),\n symbol: decodeAbiString(symbolHex ?? \"\"),\n value,\n };\n};\n\nexport { formatEther, readEvmBalance };\n","import type { Account, ChainBase, EvmAdapter, EvmTransactionValue } from \"@usebutr/core\";\nimport {\n buildAccount,\n bytesToHexPrefixed,\n EVM_CHAINS_LIST,\n hexToBytes,\n resolveChain,\n sanitizeIcon,\n} from \"@usebutr/core\";\n\nimport type {\n Eip1193Listener,\n Eip1193Object,\n Eip1193Provider,\n Eip1193Value,\n Eip6963ProviderInfo,\n} from \"./eip1193\";\nimport { requestString, requestStringArray } from \"./eip1193\";\nimport { readEvmBalance } from \"./evm-balance\";\n\nconst EVM_NAMESPACE = \"eip155\";\n\nconst toStringArray = (value: Eip1193Value | undefined): Array<string> =>\n Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n\n/** JSON-RPC cannot carry a `bigint`, so quantities go out as `0x` hex. */\nconst encodeValue = (value: EvmTransactionValue): Eip1193Value => {\n if (typeof value === \"bigint\") {\n return `0x${value.toString(16)}`;\n }\n if (Array.isArray(value)) {\n return value.map(encodeValue);\n }\n if (typeof value !== \"object\" || value === null) {\n return value;\n }\n const result: Eip1193Object = {};\n for (const [key, nested] of Object.entries(value)) {\n result[key] = nested === undefined ? undefined : encodeValue(nested);\n }\n return result;\n};\n\nconst chainIdHexToDecimal = (hex: string): string => BigInt(hex).toString(10);\nconst chainIdDecimalToHex = (dec: string): string => `0x${BigInt(dec).toString(16)}`;\n\nconst evmChainFromHex = (chainIdHex: string): ChainBase =>\n resolveChain(`${EVM_NAMESPACE}:${chainIdHexToDecimal(chainIdHex)}`, EVM_CHAINS_LIST);\n\n/** An event may already carry the addresses or the chain; only the missing\n * half is read back from the wallet. */\ntype KnownAccountState = {\n addresses?: ReadonlyArray<string>;\n chainIdHex?: string;\n};\n\n/** Rejections propagate: `getAccounts` surfaces the wallet's own provider\n * error, while the `subscribe` bridge swallows it because a later event\n * retries synchronization. */\nconst readAccounts = async (\n provider: Eip1193Provider,\n known: KnownAccountState = {},\n): Promise<Array<Account>> => {\n const addresses =\n known.addresses ?? (await requestStringArray(provider, { method: \"eth_accounts\" }));\n if (addresses.length === 0) {\n return [];\n }\n const chainIdHex = known.chainIdHex ?? (await requestString(provider, { method: \"eth_chainId\" }));\n if (chainIdHex === null) {\n throw new Error(\"Wallet returned a malformed eth_chainId response\");\n }\n const chain = evmChainFromHex(chainIdHex);\n return addresses.map((address) => buildAccount(address, chain));\n};\n\n/** EIP-1474 / JSON-RPC codes wallets use for an unimplemented method.\n * Coinbase wraps its own -32604 inside a -32603 `data.originalError`. */\nconst METHOD_NOT_SUPPORTED_CODES = new Set<unknown>([4200, -32_601, -32_603, -32_604]);\n\n/**\n * `disconnect` calls `wallet_revokePermissions`, which many wallets don't\n * implement and silently ignore, so their own auto-reconnect may outlive it.\n * `getBalance()` labels the native balance `\"ETH\"` on every EVM chain.\n */\nconst buildEvmAdapter = (info: Eip6963ProviderInfo, provider: Eip1193Provider): EvmAdapter => {\n /** The address to act as, in the wallet's own casing. Hex addresses are\n * case-insensitive (EIP-55 casing is only a checksum), so they compare\n * lowercased. */\n const resolveAddress = async (account?: Account): Promise<string> => {\n const exposed = await requestStringArray(provider, { method: \"eth_accounts\" });\n if (account === undefined) {\n const active = exposed.at(0);\n if (active === undefined) {\n throw new Error(`Wallet ${info.name} has no connected account`);\n }\n return active;\n }\n const wanted = account.walletAddress.toLowerCase();\n const match = exposed.find((address) => address.toLowerCase() === wanted);\n if (match === undefined) {\n throw new Error(`Wallet ${info.name} does not expose account ${account.walletAddress}`);\n }\n return match;\n };\n\n const switchChain = async (chain: ChainBase): Promise<void> => {\n if (chain.namespace !== EVM_NAMESPACE || !/^\\d+$/v.test(chain.reference)) {\n throw new Error(\n `EVM adapter received non-EVM chain \"${chain.id}\". Pass a chain with namespace \"${EVM_NAMESPACE}\" and a numeric reference.`,\n );\n }\n const target = chainIdDecimalToHex(chain.reference);\n const current = await requestString(provider, { method: \"eth_chainId\" });\n if (current?.toLowerCase() === target) {\n return;\n }\n await provider.request({ method: \"wallet_switchEthereumChain\", params: [{ chainId: target }] });\n };\n\n return {\n chainPlatform: \"evm\",\n\n async connect(options) {\n if (options?.silent === true) {\n const accounts = await requestStringArray(provider, { method: \"eth_accounts\" });\n if (accounts.length === 0) {\n throw new Error(\"No authorized accounts for silent reconnect\");\n }\n return;\n }\n await provider.request({ method: \"eth_requestAccounts\" });\n },\n\n async disconnect() {\n try {\n await provider.request({\n method: \"wallet_revokePermissions\",\n params: [{ eth_accounts: {} }],\n });\n } catch {\n // Many wallets don't implement wallet_revokePermissions yet;\n // not a failure.\n }\n },\n\n getAccounts: () => readAccounts(provider),\n\n async getBalance(options) {\n return readEvmBalance(provider, await resolveAddress(options?.account), options?.token);\n },\n\n getSigner: () => Promise.resolve({ kind: \"eip1193\", provider }),\n\n async getTransactionReceipt(hash) {\n const receipt = await provider.request({\n method: \"eth_getTransactionReceipt\",\n params: [hash],\n });\n // `null` is the RPC's answer for a transaction not yet mined.\n if (receipt === null || typeof receipt !== \"object\" || !(\"status\" in receipt)) {\n return { status: \"Pending\" };\n }\n return { status: receipt.status === \"0x1\" ? \"Success\" : \"Error\" };\n },\n\n icon: sanitizeIcon(info.icon),\n id: info.rdns,\n name: info.name,\n\n async requestAccounts() {\n try {\n await provider.request({\n method: \"wallet_requestPermissions\",\n params: [{ eth_accounts: {} }],\n });\n } catch (error) {\n const outer = typeof error === \"object\" && error !== null ? error : {};\n const data = \"data\" in outer ? outer.data : undefined;\n const inner =\n typeof data === \"object\" && data !== null && \"originalError\" in data\n ? data.originalError\n : undefined;\n const unsupported =\n (\"code\" in outer && METHOD_NOT_SUPPORTED_CODES.has(outer.code)) ||\n (typeof inner === \"object\" &&\n inner !== null &&\n \"code\" in inner &&\n METHOD_NOT_SUPPORTED_CODES.has(inner.code));\n if (!unsupported) {\n throw error;\n }\n await provider.request({ method: \"eth_requestAccounts\" });\n }\n },\n\n // EVM wallets have one global network, so a `chain` switches it before\n // the send rather than routing the one call. `from` is always the\n // resolved account, replacing any `from` inside `tx`.\n async sendTx(tx, options) {\n const from = await resolveAddress(options?.account);\n if (options?.chain !== undefined) {\n await switchChain(options.chain);\n }\n const hash = await requestString(provider, {\n method: \"eth_sendTransaction\",\n params: [encodeValue({ ...tx, from })],\n });\n if (hash === null) {\n throw new Error(\"Wallet returned no transaction hash\");\n }\n return hash;\n },\n\n async signMessage(message, options) {\n const address = await resolveAddress(options?.account);\n const signatureHex = await requestString(provider, {\n method: \"personal_sign\",\n params: [bytesToHexPrefixed(message), address],\n });\n if (signatureHex === null) {\n throw new Error(\"Wallet returned a malformed personal_sign response\");\n }\n return { signature: hexToBytes(signatureHex), signedMessage: message };\n },\n\n subscribe(listener) {\n const synchronize = async (known?: KnownAccountState) => {\n try {\n const accounts = await readAccounts(provider, known);\n if (accounts.length > 0) {\n listener({ accounts, type: \"accountsChanged\" });\n }\n } catch {\n // EIP-1193 event reads are best-effort; a later event retries synchronization.\n }\n };\n\n const onAccountsChanged: Eip1193Listener = (...args) => {\n const addresses = toStringArray(args[0]);\n if (addresses.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n void synchronize({ addresses });\n };\n\n const onChainChanged: Eip1193Listener = (...args) => {\n const [chainId] = args;\n // Some wallets emit a decimal number here instead of the EIP-1193\n // hex string; leaving it absent re-engages the eth_chainId read.\n const chainIdHex = typeof chainId === \"string\" && chainId.length > 0 ? chainId : undefined;\n void synchronize({ chainIdHex });\n };\n\n const onDisconnect: Eip1193Listener = () => {\n listener({ type: \"disconnected\" });\n };\n\n const onConnect: Eip1193Listener = () => {\n void synchronize();\n };\n\n provider.on(\"accountsChanged\", onAccountsChanged);\n provider.on(\"chainChanged\", onChainChanged);\n provider.on(\"connect\", onConnect);\n provider.on(\"disconnect\", onDisconnect);\n\n return () => {\n provider.removeListener(\"accountsChanged\", onAccountsChanged);\n provider.removeListener(\"chainChanged\", onChainChanged);\n provider.removeListener(\"connect\", onConnect);\n provider.removeListener(\"disconnect\", onDisconnect);\n };\n },\n\n switchChain,\n };\n};\n\nexport { formatEther } from \"./evm-balance\";\nexport { buildEvmAdapter, chainIdDecimalToHex, chainIdHexToDecimal };\n","import type { EvmAdapter } from \"@usebutr/core\";\n\nimport type { Eip6963AnnounceEvent, Eip6963ProviderInfo } from \"./eip1193\";\nimport { buildEvmAdapter } from \"./eip6963-adapter\";\n\nconst ANNOUNCE_EVENT = \"eip6963:announceProvider\";\nconst REQUEST_EVENT = \"eip6963:requestProvider\";\n\ntype AdapterCallback = (adapter: EvmAdapter, info: Eip6963ProviderInfo) => void;\n\ntype DiscoverOptions = {\n /** Event target to listen on. Defaults to `window` in browser/RN/\n * SSR'd environments; tests can pass a fresh `new EventTarget()` to\n * exercise the discovery loop without a DOM. */\n target?: EventTarget;\n};\n\nconst isEip6963AnnounceEvent = (event: Event): event is Eip6963AnnounceEvent => {\n if (!(\"detail\" in event)) {\n return false;\n }\n const detail: unknown = event.detail;\n if (typeof detail !== \"object\" || detail === null) {\n return false;\n }\n if (!(\"info\" in detail) || !(\"provider\" in detail)) {\n return false;\n }\n const { info, provider } = detail;\n return (\n typeof info === \"object\" &&\n info !== null &&\n \"icon\" in info &&\n typeof info.icon === \"string\" &&\n \"name\" in info &&\n typeof info.name === \"string\" &&\n \"rdns\" in info &&\n typeof info.rdns === \"string\" &&\n \"uuid\" in info &&\n typeof info.uuid === \"string\" &&\n typeof provider === \"object\" &&\n provider !== null &&\n \"on\" in provider &&\n typeof provider.on === \"function\" &&\n \"removeListener\" in provider &&\n typeof provider.removeListener === \"function\" &&\n \"request\" in provider &&\n typeof provider.request === \"function\"\n );\n};\n\nconst windowGlobal: Partial<Pick<typeof globalThis, \"window\">> = globalThis;\n\nconst resolveTarget = (target?: EventTarget): EventTarget | null => {\n if (target !== undefined) {\n return target;\n }\n return windowGlobal.window ?? null;\n};\n\n/**\n * Spec: https://eips.ethereum.org/EIPS/eip-6963. Dedupe is by `info.rdns`\n * because `info.uuid` is regenerated per page load. The listener stays\n * attached for the session so wallets that boot late still register.\n */\nconst discoverEvmAdapters = (\n onAdapter: AdapterCallback,\n options: DiscoverOptions = {},\n): (() => void) => {\n const target = resolveTarget(options.target);\n if (!target) {\n return () => {};\n }\n\n const seen = new Set<string>();\n const handler = (event: Event) => {\n if (!isEip6963AnnounceEvent(event)) {\n return;\n }\n const { info, provider } = event.detail;\n if (info.rdns.length === 0) {\n return;\n }\n if (seen.has(info.rdns)) {\n return;\n }\n seen.add(info.rdns);\n onAdapter(buildEvmAdapter(info, provider), info);\n };\n\n target.addEventListener(ANNOUNCE_EVENT, handler);\n target.dispatchEvent(new Event(REQUEST_EVENT));\n\n return () => {\n target.removeEventListener(ANNOUNCE_EVENT, handler);\n };\n};\n\nexport { ANNOUNCE_EVENT, REQUEST_EVENT, discoverEvmAdapters };\n","import type { EvmAdapter } from \"@usebutr/core\";\n\nimport type { Eip1193Provider, Eip6963ProviderInfo } from \"./eip1193\";\nimport { buildEvmAdapter } from \"./eip6963-adapter\";\n\n/**\n * Generic wallet icon (a stylised purse SVG, ~600 bytes). Used as\n * the fallback icon when an injected provider has no EIP-6963 info.\n * Inline rather than a network fetch so the picker doesn't flicker.\n */\nconst GENERIC_INJECTED_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjEgMTJWN0g1YTIgMiAwIDAgMSAwLTQgaDE0djQiLz48cGF0aCBkPSJNMyA1djE0YTIgMiAwIDAgMCAyIDJoMTZ2LTVNMjEgMTIgaC0zYTIgMiAwIDAgMC0yIDJ2MGEyIDIgMCAwIDAgMiAyaDN6Ii8+PC9zdmc+\";\n\nconst DEFAULT_SETTLE_MS = 150;\n\ntype InjectedDiscoveryOptions = {\n /**\n * Consulted before emitting: an already-registered EIP-6963 adapter means\n * the wallet is covered by the standards path and emitting would duplicate\n * it. Omit to always emit.\n */\n hasAnyEip6963Adapter?: () => boolean;\n /**\n * Most wallets announce within the first frame; 150ms leaves room for slow\n * announcements without stalling the picker.\n */\n settleMs?: number;\n /** Override the global `window` reference (tests, iframes). */\n target?: { ethereum?: Partial<Eip1193Provider> } | null;\n};\n\ndeclare global {\n // oxlint-disable-next-line typescript/consistent-type-definitions -- DOM globals require interface merging.\n interface Window {\n ethereum?: Partial<Eip1193Provider>;\n }\n}\n\n/** Structural check for code that holds a provider of unknown origin, such\n * as `window.ethereum`. A butr signer narrows on `kind === \"eip1193\"`\n * instead. */\nconst isEip1193Provider = (value: unknown): value is Eip1193Provider =>\n typeof value === \"object\" &&\n value !== null &&\n \"on\" in value &&\n typeof value.on === \"function\" &&\n \"removeListener\" in value &&\n typeof value.removeListener === \"function\" &&\n \"request\" in value &&\n typeof value.request === \"function\";\n\nconst readEthereum = (target: InjectedDiscoveryOptions[\"target\"]): Eip1193Provider | null => {\n const host = target === undefined ? globalThis.window : target;\n return isEip1193Provider(host?.ethereum) ? host.ethereum : null;\n};\n\n/**\n * Last-resort path for the long tail of EVM wallets that expose only\n * `window.ethereum` and never announce via EIP-6963. The emitted adapter\n * carries `rdns: \"injected:legacy\"` so consumers can tell it apart.\n */\nconst discoverInjectedAdapter = (\n onAdapter: (adapter: EvmAdapter) => void,\n options: InjectedDiscoveryOptions = {},\n): (() => void) => {\n const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;\n let cancelled = false;\n const timer = setTimeout(() => {\n if (cancelled) {\n return;\n }\n if (options.hasAnyEip6963Adapter?.() === true) {\n return;\n }\n const provider = readEthereum(options.target);\n if (provider === null) {\n return;\n }\n const info: Eip6963ProviderInfo = {\n icon: GENERIC_INJECTED_ICON,\n name: \"Browser wallet\",\n rdns: \"injected:legacy\",\n uuid: \"injected:legacy\",\n };\n onAdapter(buildEvmAdapter(info, provider));\n }, settleMs);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n};\n\nexport type { InjectedDiscoveryOptions };\nexport { GENERIC_INJECTED_ICON, discoverInjectedAdapter, isEip1193Provider };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverEvmAdapters } from \"./eip6963\";\nimport { discoverInjectedAdapter } from \"./injected\";\n\n/**\n * EIP-6963 is primary; the legacy `window.ethereum` fallback defers until\n * EIP-6963 has had a chance to fire.\n */\nconst evmDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) =>\n discoverInjectedAdapter(onAdapter, {\n hasAnyEip6963Adapter: opts.hasAnyPrimaryAdapter,\n }),\n },\n subscribe: discoverEvmAdapters,\n};\n\nexport { evmDiscoverer };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebutr/evm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "EIP-1193 / EIP-6963 / injected wallet discovery + adapters for butr.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"butr",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@usebutr/core": "
|
|
44
|
+
"@usebutr/core": "3.0.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"typescript": "^7.0.2",
|
|
48
|
-
"vitest": "^
|
|
48
|
+
"vitest": "^5.0.1",
|
|
49
49
|
"@repo/config-vitest": "0.0.0",
|
|
50
50
|
"@repo/typescript-config": "0.0.0"
|
|
51
51
|
},
|