@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 +11 -0
- package/LICENSE.md +21 -0
- package/README.md +137 -0
- package/dist/esm/context.d.ts +9 -0
- package/dist/esm/context.js +10 -0
- package/dist/esm/context.js.map +1 -0
- package/dist/esm/errors/context.d.ts +8 -0
- package/dist/esm/errors/context.js +8 -0
- package/dist/esm/errors/context.js.map +1 -0
- package/dist/esm/hooks/useAccount.d.ts +3 -0
- package/dist/esm/hooks/useAccount.js +10 -0
- package/dist/esm/hooks/useAccount.js.map +1 -0
- package/dist/esm/hooks/useConfig.d.ts +3 -0
- package/dist/esm/hooks/useConfig.js +14 -0
- package/dist/esm/hooks/useConfig.js.map +1 -0
- package/dist/esm/hooks/useReconnect.d.ts +2 -0
- package/dist/esm/hooks/useReconnect.js +8 -0
- package/dist/esm/hooks/useReconnect.js.map +1 -0
- package/dist/esm/hooks/useSyncExternalStoreWithTracked.d.ts +1 -0
- package/dist/esm/hooks/useSyncExternalStoreWithTracked.js +43 -0
- package/dist/esm/hooks/useSyncExternalStoreWithTracked.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +51 -0
- package/src/context.ts +27 -0
- package/src/errors/context.ts +11 -0
- package/src/hooks/useAccount.ts +22 -0
- package/src/hooks/useConfig.ts +22 -0
- package/src/hooks/useReconnect.ts +9 -0
- package/src/hooks/useSyncExternalStoreWithTracked.ts +66 -0
- package/src/index.ts +4 -0
- package/tsconfig.json +17 -0
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.md)
|
|
7
|
+
[](https://www.npmjs.com/package/@bigmi/core)
|
|
8
|
+
[](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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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,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
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
|
+
}
|