@bigmi/react 0.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 ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
+
5
+ ### 0.0.1 (2024-10-15)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * biome checks ([bc348fa](https://github.com/lifinance/bigmi/commit/bc348faad5cec9ddada1a0c82f4d34e68b85c1c4))
11
+ * tsconfig ([bf6ccea](https://github.com/lifinance/bigmi/commit/bf6cceae3a1602b99b4825ee3695b367d5935226))
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Bigmi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+
3
+ <h1 align="center">Bigmi</h1>
4
+ <p align="center"><strong>TypeScript library and reactive primitives for Bitcoin apps.</strong></p>
5
+
6
+ [![license](https://img.shields.io/npm/l/@bigmi/core)](/LICENSE.md)
7
+ [![npm latest package](https://img.shields.io/npm/v/@bigmi/core/latest.svg)](https://www.npmjs.com/package/@bigmi/core)
8
+ [![npm downloads](https://img.shields.io/npm/dm/@bigmi/core.svg)](https://www.npmjs.com/package/@bigmi/core)
9
+
10
+ </div>
11
+
12
+ **Bigmi** (short for *Bitcoin Is Gonna Make It*) is a TypeScript library that provides reactive primitives for building Bitcoin applications. Bigmi simplifies Bitcoin app development by offering:
13
+
14
+ - Abstractions over the [Bitcoin JSON-RPC API](https://developer.bitcoin.org/reference/rpc/)
15
+ - First-class APIs for interacting with the [Bitcoin](https://bitcoin.design/) network, including sending transactions and tracking with [Replace-By-Fee (RBF)](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki) support
16
+ - Connectors for popular Bitcoin wallet extensions
17
+ - TypeScript support
18
+
19
+ Whether you're building a Node.js application or a client-side app, Bigmi provides the tools you need to interact with the Bitcoin.
20
+
21
+ ### Packages
22
+
23
+ Bigmi is modularized into several packages, each suited to different use cases:
24
+
25
+ - [@bigmi/core](https://www.npmjs.com/package/@bigmi/core) - Actions, transports, utilities, and other core primitives for Node.js or client-side applications.
26
+ - [@bigmi/react](https://www.npmjs.com/package/@bigmi/react) - Hooks, providers, and other useful primitives for React applications.
27
+ - [@bigmi/client](https://www.npmjs.com/package/@bigmi/client) - Wallet connectors and other tools to connect wallet extensions with Bitcoin applications.
28
+
29
+ ## Installation
30
+
31
+ ```sh
32
+ pnpm add @bigmi/react
33
+ ```
34
+ ```sh
35
+ pnpm add @bigmi/core
36
+ ```
37
+ ```sh
38
+ pnpm add @bigmi/client
39
+ ```
40
+
41
+ ## Getting Started
42
+
43
+ Here is an example of a basic usage:
44
+
45
+ ```tsx
46
+ import {
47
+ type UTXOAPISchema,
48
+ bitcoin,
49
+ getBalance,
50
+ getBlockCount,
51
+ sendUTXOTransaction,
52
+ utxo,
53
+ waitForTransaction,
54
+ } from '@bigmi/core'
55
+ import { createClient, fallback, rpcSchema } from 'viem'
56
+
57
+ // Create a public client for interactions with the Bitcoin
58
+ const publicClient = createClient({
59
+ chain: bitcoin,
60
+ rpcSchema: rpcSchema<UTXOAPISchema>(),
61
+ transport: fallback([
62
+ utxo('https://api.blockchair.com', {
63
+ key: 'blockchair',
64
+ includeChainToURL: true,
65
+ }),
66
+ utxo('https://rpc.ankr.com/http/btc_blockbook/api/v2', {
67
+ key: 'ankr',
68
+ }),
69
+ utxo('https://api.blockcypher.com/v1/btc/main', {
70
+ key: 'blockcypher',
71
+ }),
72
+ utxo('https://mempool.space/api', {
73
+ key: 'mempool',
74
+ }),
75
+ ]),
76
+ })
77
+
78
+ // Define the Bitcoin address you're working with
79
+ const address = 'BITCOIN_ADDRESS';
80
+
81
+ // Fetch the balance of the address
82
+ const balance = await getBalance(publicClient, { address });
83
+ console.log(`Balance for ${address}:`, balance);
84
+
85
+ // Fetch the current block count (height)
86
+ const blockCount = await getBlockCount(publicClient);
87
+ console.log('Current block count:', blockCount);
88
+
89
+ // Prepare the transaction hex (as a string)
90
+ const txHex = 'TRANSACTION_HEX';
91
+
92
+ // Send the transaction to the network
93
+ const txId = await sendUTXOTransaction(publicClient, { hex: txHex });
94
+ console.log('Transaction sent with ID:', txId);
95
+
96
+ // Wait for the transaction to be confirmed
97
+ const transaction = await waitForTransaction(publicClient, {
98
+ txId,
99
+ txHex,
100
+ senderAddress: address,
101
+ onReplaced: (response) => {
102
+ console.log('Transaction replaced due to:', response.reason);
103
+ },
104
+ });
105
+
106
+ console.log('Transaction confirmed:', transaction);
107
+ ```
108
+
109
+ ## Examples
110
+
111
+ We are working on examples to showcase Bigmi's capabilities. Stay tuned!
112
+
113
+ In the meantime, explore the [LI.FI Widget](https://github.com/lifinance/widget) and [LI.FI SDK](https://github.com/lifinance/sdk) for inspiration.
114
+
115
+ ## Documentation
116
+
117
+ Detailed documentation is coming soon. For now, refer to the source code and type definitions for guidance.
118
+
119
+ ## Support
120
+
121
+ If you encounter any issues or have questions, please open an issue.
122
+
123
+ ## Contributing
124
+
125
+ We welcome contributions from the community!
126
+
127
+ ## Changelog
128
+
129
+ The [changelog](/CHANGELOG.md) is regularly updated to reflect what's changed in each new release.
130
+
131
+ ## License
132
+
133
+ This project is licensed under the terms of the [MIT License](/LICENSE.md).
134
+
135
+ ## Acknowledgments
136
+
137
+ Bigmi is inspired by the [wevm](https://github.com/wevm) stack. We appreciate the open-source community's contributions to advancing blockchain development.
@@ -0,0 +1,9 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import type { ResolvedRegister, State } from 'wagmi';
3
+ export declare const BigmiContext: import("react").Context<import("wagmi").Config | undefined>;
4
+ export type BigmiProviderProps = {
5
+ config: ResolvedRegister['config'];
6
+ initialState?: State | undefined;
7
+ reconnectOnMount?: boolean | undefined;
8
+ };
9
+ export declare function BigmiProvider(parameters: PropsWithChildren<BigmiProviderProps>): import("react").FunctionComponentElement<PropsWithChildren<import("wagmi").HydrateProps>>;
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ import { createContext, createElement } from 'react';
3
+ import { Hydrate } from 'wagmi';
4
+ export const BigmiContext = createContext(undefined);
5
+ export function BigmiProvider(parameters) {
6
+ const { children, config } = parameters;
7
+ const props = { value: config };
8
+ return createElement(Hydrate, parameters, createElement(BigmiContext.Provider, props, children));
9
+ }
10
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAA0B,aAAa,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE5E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAEvC,SAAS,CAAC,CAAA;AAQZ,MAAM,UAAU,aAAa,CAC3B,UAAiD;IAEjD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;IAEvC,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAC/B,OAAO,aAAa,CAClB,OAAO,EACP,UAAU,EACV,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CACtD,CAAA;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { BaseError } from 'wagmi';
2
+ export type BigmiProviderNotFoundErrorType = BigmiProviderNotFoundError & {
3
+ name: 'BigmiProviderNotFoundError';
4
+ };
5
+ export declare class BigmiProviderNotFoundError extends BaseError {
6
+ name: string;
7
+ constructor();
8
+ }
@@ -0,0 +1,8 @@
1
+ import { BaseError } from 'wagmi';
2
+ export class BigmiProviderNotFoundError extends BaseError {
3
+ constructor() {
4
+ super('`useConfig` must be used within `BigmiProvider`.');
5
+ this.name = 'BigmiProviderNotFoundError';
6
+ }
7
+ }
8
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/errors/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKjC,MAAM,OAAO,0BAA2B,SAAQ,SAAS;IAEvD;QACE,KAAK,CAAC,kDAAkD,CAAC,CAAA;QAFlD,SAAI,GAAG,4BAA4B,CAAA;IAG5C,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ import type { Config, ResolvedRegister, UseAccountParameters, UseAccountReturnType } from 'wagmi';
2
+ /** https://wagmi.sh/react/api/hooks/useAccount */
3
+ export declare function useAccount<C extends Config = ResolvedRegister['config']>(parameters?: UseAccountParameters<C>): UseAccountReturnType<C>;
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ import { getAccount, watchAccount } from 'wagmi/actions';
3
+ import { useConfig } from './useConfig.js';
4
+ import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js';
5
+ /** https://wagmi.sh/react/api/hooks/useAccount */
6
+ export function useAccount(parameters = {}) {
7
+ const config = useConfig(parameters);
8
+ return useSyncExternalStoreWithTracked((onChange) => watchAccount(config, { onChange }), () => getAccount(config));
9
+ }
10
+ //# sourceMappingURL=useAccount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAccount.js","sourceRoot":"","sources":["../../../src/hooks/useAccount.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAOZ,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAA;AAEtF,kDAAkD;AAClD,MAAM,UAAU,UAAU,CACxB,aAAsC,EAAE;IAExC,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;IAEpC,OAAO,+BAA+B,CACpC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,EAChD,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CACzB,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Config, ResolvedRegister, UseConfigParameters, UseConfigReturnType } from 'wagmi';
2
+ /** https://wagmi.sh/react/api/hooks/useConfig */
3
+ export declare function useConfig<C extends Config = ResolvedRegister['config']>(parameters?: UseConfigParameters<C>): UseConfigReturnType<C>;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { useContext } from 'react';
3
+ import { BigmiContext } from '../context.js';
4
+ import { BigmiProviderNotFoundError } from '../errors/context.js';
5
+ /** https://wagmi.sh/react/api/hooks/useConfig */
6
+ export function useConfig(parameters = {}) {
7
+ // biome-ignore lint/correctness/useHookAtTopLevel:
8
+ const config = parameters.config ?? useContext(BigmiContext);
9
+ if (!config) {
10
+ throw new BigmiProviderNotFoundError();
11
+ }
12
+ return config;
13
+ }
14
+ //# sourceMappingURL=useConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConfig.js","sourceRoot":"","sources":["../../../src/hooks/useConfig.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAOlC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA;AAEjE,iDAAiD;AACjD,MAAM,UAAU,SAAS,CACvB,aAAqC,EAAE;IAEvC,mDAAmD;IACnD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,CAAA;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,0BAA0B,EAAE,CAAA;IACxC,CAAC;IACD,OAAO,MAAgC,CAAA;AACzC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Config } from 'wagmi';
2
+ export declare const useReconnect: (config: Config) => void;
@@ -0,0 +1,8 @@
1
+ import { reconnect } from '@bigmi/client';
2
+ import { useEffect } from 'react';
3
+ export const useReconnect = (config) => {
4
+ useEffect(() => {
5
+ reconnect(config);
6
+ }, [config]);
7
+ };
8
+ //# sourceMappingURL=useReconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReconnect.js","sourceRoot":"","sources":["../../../src/hooks/useReconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,EAAE;IAC7C,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AACd,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export declare function useSyncExternalStoreWithTracked<snapshot extends selection, selection = snapshot>(subscribe: (onStoreChange: () => void) => () => void, getSnapshot: () => snapshot, getServerSnapshot?: undefined | null | (() => snapshot), isEqual?: (a: selection, b: selection) => boolean): snapshot;
@@ -0,0 +1,43 @@
1
+ 'use client';
2
+ import { useRef } from 'react';
3
+ import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js';
4
+ import { deepEqual } from 'wagmi';
5
+ const isPlainObject = (obj) => typeof obj === 'object' && !Array.isArray(obj);
6
+ export function useSyncExternalStoreWithTracked(subscribe, getSnapshot, getServerSnapshot = getSnapshot, isEqual = deepEqual) {
7
+ const trackedKeys = useRef([]);
8
+ const result = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, (x) => x, (a, b) => {
9
+ if (isPlainObject(a) && isPlainObject(b) && trackedKeys.current.length) {
10
+ for (const key of trackedKeys.current) {
11
+ const equal = isEqual(a[key], b[key]);
12
+ if (!equal) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
18
+ return isEqual(a, b);
19
+ });
20
+ if (isPlainObject(result)) {
21
+ const trackedResult = { ...result };
22
+ let properties = {};
23
+ for (const [key, value] of Object.entries(trackedResult)) {
24
+ properties = {
25
+ ...properties,
26
+ [key]: {
27
+ configurable: false,
28
+ enumerable: true,
29
+ get: () => {
30
+ if (!trackedKeys.current.includes(key)) {
31
+ trackedKeys.current.push(key);
32
+ }
33
+ return value;
34
+ },
35
+ },
36
+ };
37
+ }
38
+ Object.defineProperties(trackedResult, properties);
39
+ return trackedResult;
40
+ }
41
+ return result;
42
+ }
43
+ //# sourceMappingURL=useSyncExternalStoreWithTracked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSyncExternalStoreWithTracked.js","sourceRoot":"","sources":["../../../src/hooks/useSyncExternalStoreWithTracked.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,gCAAgC,EAAE,MAAM,+CAA+C,CAAA;AAChG,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,MAAM,aAAa,GAAG,CAAC,GAAY,EAAE,EAAE,CACrC,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAEhD,MAAM,UAAU,+BAA+B,CAI7C,SAAoD,EACpD,WAA2B,EAC3B,oBAAyD,WAAW,EACpE,UAAmD,SAAS;IAE5D,MAAM,WAAW,GAAG,MAAM,CAAW,EAAE,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,gCAAgC,CAC7C,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EACR,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACP,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACvE,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,OAAO,CAClB,CAA2B,CAAC,GAAG,CAAC,EAChC,CAA2B,CAAC,GAAG,CAAC,CAClC,CAAA;gBACD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtB,CAAC,CACF,CAAA;IAED,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;QACnC,IAAI,UAAU,GAAG,EAAE,CAAA;QACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CACvC,aAAuC,CACxC,EAAE,CAAC;YACF,UAAU,GAAG;gBACX,GAAG,UAAU;gBACb,CAAC,GAAG,CAAC,EAAE;oBACL,YAAY,EAAE,KAAK;oBACnB,UAAU,EAAE,IAAI;oBAChB,GAAG,EAAE,GAAG,EAAE;wBACR,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;4BACvC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;wBAC/B,CAAC;wBACD,OAAO,KAAK,CAAA;oBACd,CAAC;iBACF;aACF,CAAA;QACH,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;QAClD,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { BigmiContext, BigmiProvider } from './context.js';
2
+ export type { BigmiProviderProps } from './context.js';
3
+ export { useConfig } from './hooks/useConfig.js';
4
+ export { useReconnect } from './hooks/useReconnect.js';
@@ -0,0 +1,4 @@
1
+ export { BigmiContext, BigmiProvider } from './context.js';
2
+ export { useConfig } from './hooks/useConfig.js';
3
+ export { useReconnect } from './hooks/useReconnect.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@bigmi/react",
3
+ "version": "0.0.1",
4
+ "description": "React primitives for Bitcoin apps.",
5
+ "type": "module",
6
+ "main": "./dist/esm/index.js",
7
+ "types": "./dist/esm/index.d.ts",
8
+ "sideEffects": false,
9
+ "author": "Eugene Chybisov <eugene@li.finance>",
10
+ "homepage": "https://github.com/lifinance/bigmi",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/lifinance/bigmi.git",
14
+ "directory": "packages/react"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/lifinance/bigmi/issues"
18
+ },
19
+ "license": "MIT",
20
+ "keywords": [
21
+ "bitcoin",
22
+ "bitcoinjs",
23
+ "btc",
24
+ "utxo",
25
+ "web3",
26
+ "dapp",
27
+ "typescript",
28
+ "react",
29
+ "hooks"
30
+ ],
31
+ "dependencies": {
32
+ "use-sync-external-store": "^1.2.2",
33
+ "viem": "^2.21.25",
34
+ "wagmi": "^2.12.16",
35
+ "@bigmi/client": "^0.0.1",
36
+ "@bigmi/core": "^0.0.1"
37
+ },
38
+ "peerDependencies": {
39
+ "react": ">=18",
40
+ "react-dom": ">=18",
41
+ "viem": "^2.21.0",
42
+ "wagmi": "^2.12.0"
43
+ },
44
+ "exports": {
45
+ ".": {
46
+ "types": "./dist/esm/index.d.ts",
47
+ "default": "./dist/esm/index.js"
48
+ },
49
+ "./package.json": "./package.json"
50
+ }
51
+ }
package/src/context.ts ADDED
@@ -0,0 +1,27 @@
1
+ 'use client'
2
+ import { type PropsWithChildren, createContext, createElement } from 'react'
3
+ import type { ResolvedRegister, State } from 'wagmi'
4
+ import { Hydrate } from 'wagmi'
5
+
6
+ export const BigmiContext = createContext<
7
+ ResolvedRegister['config'] | undefined
8
+ >(undefined)
9
+
10
+ export type BigmiProviderProps = {
11
+ config: ResolvedRegister['config']
12
+ initialState?: State | undefined
13
+ reconnectOnMount?: boolean | undefined
14
+ }
15
+
16
+ export function BigmiProvider(
17
+ parameters: PropsWithChildren<BigmiProviderProps>
18
+ ) {
19
+ const { children, config } = parameters
20
+
21
+ const props = { value: config }
22
+ return createElement(
23
+ Hydrate,
24
+ parameters,
25
+ createElement(BigmiContext.Provider, props, children)
26
+ )
27
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseError } from 'wagmi'
2
+
3
+ export type BigmiProviderNotFoundErrorType = BigmiProviderNotFoundError & {
4
+ name: 'BigmiProviderNotFoundError'
5
+ }
6
+ export class BigmiProviderNotFoundError extends BaseError {
7
+ override name = 'BigmiProviderNotFoundError'
8
+ constructor() {
9
+ super('`useConfig` must be used within `BigmiProvider`.')
10
+ }
11
+ }
@@ -0,0 +1,22 @@
1
+ 'use client'
2
+ import type {
3
+ Config,
4
+ ResolvedRegister,
5
+ UseAccountParameters,
6
+ UseAccountReturnType,
7
+ } from 'wagmi'
8
+ import { getAccount, watchAccount } from 'wagmi/actions'
9
+ import { useConfig } from './useConfig.js'
10
+ import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js'
11
+
12
+ /** https://wagmi.sh/react/api/hooks/useAccount */
13
+ export function useAccount<C extends Config = ResolvedRegister['config']>(
14
+ parameters: UseAccountParameters<C> = {}
15
+ ): UseAccountReturnType<C> {
16
+ const config = useConfig(parameters)
17
+
18
+ return useSyncExternalStoreWithTracked(
19
+ (onChange) => watchAccount(config, { onChange }),
20
+ () => getAccount(config)
21
+ )
22
+ }
@@ -0,0 +1,22 @@
1
+ 'use client'
2
+ import { useContext } from 'react'
3
+ import type {
4
+ Config,
5
+ ResolvedRegister,
6
+ UseConfigParameters,
7
+ UseConfigReturnType,
8
+ } from 'wagmi'
9
+ import { BigmiContext } from '../context.js'
10
+ import { BigmiProviderNotFoundError } from '../errors/context.js'
11
+
12
+ /** https://wagmi.sh/react/api/hooks/useConfig */
13
+ export function useConfig<C extends Config = ResolvedRegister['config']>(
14
+ parameters: UseConfigParameters<C> = {}
15
+ ): UseConfigReturnType<C> {
16
+ // biome-ignore lint/correctness/useHookAtTopLevel:
17
+ const config = parameters.config ?? useContext(BigmiContext)
18
+ if (!config) {
19
+ throw new BigmiProviderNotFoundError()
20
+ }
21
+ return config as UseConfigReturnType<C>
22
+ }
@@ -0,0 +1,9 @@
1
+ import { reconnect } from '@bigmi/client'
2
+ import { useEffect } from 'react'
3
+ import type { Config } from 'wagmi'
4
+
5
+ export const useReconnect = (config: Config) => {
6
+ useEffect(() => {
7
+ reconnect(config)
8
+ }, [config])
9
+ }
@@ -0,0 +1,66 @@
1
+ 'use client'
2
+ import { useRef } from 'react'
3
+ import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js'
4
+ import { deepEqual } from 'wagmi'
5
+
6
+ const isPlainObject = (obj: unknown) =>
7
+ typeof obj === 'object' && !Array.isArray(obj)
8
+
9
+ export function useSyncExternalStoreWithTracked<
10
+ snapshot extends selection,
11
+ selection = snapshot,
12
+ >(
13
+ subscribe: (onStoreChange: () => void) => () => void,
14
+ getSnapshot: () => snapshot,
15
+ getServerSnapshot: undefined | null | (() => snapshot) = getSnapshot,
16
+ isEqual: (a: selection, b: selection) => boolean = deepEqual
17
+ ) {
18
+ const trackedKeys = useRef<string[]>([])
19
+ const result = useSyncExternalStoreWithSelector(
20
+ subscribe,
21
+ getSnapshot,
22
+ getServerSnapshot,
23
+ (x) => x,
24
+ (a, b) => {
25
+ if (isPlainObject(a) && isPlainObject(b) && trackedKeys.current.length) {
26
+ for (const key of trackedKeys.current) {
27
+ const equal = isEqual(
28
+ (a as { [_a: string]: any })[key],
29
+ (b as { [_b: string]: any })[key]
30
+ )
31
+ if (!equal) {
32
+ return false
33
+ }
34
+ }
35
+ return true
36
+ }
37
+ return isEqual(a, b)
38
+ }
39
+ )
40
+
41
+ if (isPlainObject(result)) {
42
+ const trackedResult = { ...result }
43
+ let properties = {}
44
+ for (const [key, value] of Object.entries(
45
+ trackedResult as { [key: string]: any }
46
+ )) {
47
+ properties = {
48
+ ...properties,
49
+ [key]: {
50
+ configurable: false,
51
+ enumerable: true,
52
+ get: () => {
53
+ if (!trackedKeys.current.includes(key)) {
54
+ trackedKeys.current.push(key)
55
+ }
56
+ return value
57
+ },
58
+ },
59
+ }
60
+ }
61
+ Object.defineProperties(trackedResult, properties)
62
+ return trackedResult
63
+ }
64
+
65
+ return result
66
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { BigmiContext, BigmiProvider } from './context.js'
2
+ export type { BigmiProviderProps } from './context.js'
3
+ export { useConfig } from './hooks/useConfig.js'
4
+ export { useReconnect } from './hooks/useReconnect.js'
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "composite": true,
5
+ "declaration": true,
6
+ "sourceMap": true,
7
+ "outDir": "dist/esm",
8
+ "rootDir": "./src",
9
+ "module": "NodeNext",
10
+ "moduleResolution": "NodeNext"
11
+ },
12
+ "include": [
13
+ "./src/**/*",
14
+ "./src/**/*.json",
15
+ "../client/src/createDefaultBigmiConfig.ts"
16
+ ]
17
+ }