generated from ChainSafe/yarn-workspaces-typescript-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
closes #47
- Loading branch information
Showing
34 changed files
with
2,112 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
{ | ||
"packages/sdk": "0.1.0" | ||
"packages/sdk": "0.1.0", | ||
"packages/react": "0.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
*.tsbuildinfo | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Sprinter React SDK | ||
|
||
The Sprinter React SDK is a React wrapper for the [Sprinter SDK](https://github.com/ChainSafe/sprinter-sdk), enabling easy interaction with blockchain networks through React components and hooks. It provides context management and custom hooks for retrieving balances, tokens, supported chains, and solutions for asset transfers. | ||
|
||
## Installation | ||
|
||
To install the package, use npm or yarn: | ||
|
||
```bash | ||
npm install @chainsafe/sprinter-react | ||
# or | ||
yarn add @chainsafe/sprinter-react | ||
``` | ||
|
||
## Usage | ||
|
||
Wrap your application in the `SprinterContext` to gain access to blockchain-related data within your component tree. | ||
|
||
### Example | ||
|
||
```tsx | ||
import React from 'react'; | ||
import { SprinterContext } from '@chainsafe/sprinter-react'; | ||
|
||
const App = () => ( | ||
<SprinterContext> | ||
<YourComponent /> | ||
</SprinterContext> | ||
); | ||
|
||
export default App; | ||
``` | ||
|
||
Inside your components, you can use the provided hooks to interact with blockchain data: | ||
|
||
```tsx | ||
import React, { useEffect } from 'react'; | ||
import { useSprinterBalances, useSprinterTokens } from '@chainsafe/sprinter-react'; | ||
|
||
const YourComponent = () => { | ||
const ownerAddress = "0xYourAddressHere"; | ||
const { balances, getUserBalances } = useSprinterBalances(ownerAddress); | ||
|
||
useEffect(() => { | ||
getUserBalances(); | ||
}, [getUserBalances]); | ||
|
||
return ( | ||
<div> | ||
<h1>Balances:</h1> | ||
<pre>{JSON.stringify(balances, null, 2)}</pre> | ||
<h1>Available Tokens:</h1> | ||
<pre>{JSON.stringify(tokens, null, 2)}</pre> | ||
</div> | ||
); | ||
}; | ||
|
||
export default YourComponent; | ||
``` | ||
|
||
### Available Hooks | ||
|
||
The following hooks are provided by the SDK: | ||
|
||
- **`useSprinter()`**: Access everything from the Sprinter context. | ||
- **`useSprinterBalances(account: Address)`**: Retrieve user balances for a given account. | ||
- **`useSprinterTokens()`**: Retrieve available tokens. | ||
- **`useSprinterChains()`**: Retrieve available blockchain chains. | ||
- **`useSprinterSolution()`**: Retrieve solutions for asset transfers. | ||
- **`useSprinterCallSolution()`**: Call solutions for transferring assets. | ||
|
||
### Custom Fetch Options | ||
|
||
You can pass custom fetch options when initializing the context: | ||
|
||
```tsx | ||
<SprinterContext fetchOptions={{ baseUrl: "https://api.test.sprinter.buildwithsygma.com/" }}> | ||
<YourComponent /> | ||
</SprinterContext> | ||
``` | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! Feel free to open issues or submit pull requests for new features or bug fixes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import js from '@eslint/js' | ||
import globals from 'globals' | ||
import reactHooks from 'eslint-plugin-react-hooks' | ||
import reactRefresh from 'eslint-plugin-react-refresh' | ||
import tseslint from 'typescript-eslint' | ||
|
||
export default tseslint.config( | ||
{ ignores: ['dist'] }, | ||
{ | ||
extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||
files: ['**/*.{ts,tsx}'], | ||
languageOptions: { | ||
ecmaVersion: 2020, | ||
globals: globals.browser, | ||
}, | ||
plugins: { | ||
'react-hooks': reactHooks, | ||
'react-refresh': reactRefresh, | ||
}, | ||
rules: { | ||
...reactHooks.configs.recommended.rules, | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vite + React + TS</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import {createContext, ReactNode, useEffect, useState} from "react"; | ||
import {type FetchOptions, Sprinter} from "@chainsafe/sprinter-sdk"; | ||
import {useTokens} from "./internal/useTokens.ts"; | ||
import {useChains} from "./internal/useChains.ts"; | ||
import {useSolution} from "./internal/useSolution.ts"; | ||
import {useCallSolution} from "./internal/useCallSolution.ts"; | ||
import {useBalances} from "./internal/useBalances.ts"; | ||
|
||
type SprinterContext = ReturnType<typeof useBalances> & ReturnType<typeof useTokens> & ReturnType<typeof useChains> & ReturnType<typeof useSolution> & ReturnType<typeof useCallSolution>; | ||
|
||
export const Context = createContext<SprinterContext | null>(null); | ||
|
||
interface SprinterContextProps { | ||
children?: ReactNode | undefined; | ||
fetchOptions?: Omit<FetchOptions, "signal">; | ||
} | ||
|
||
export function SprinterContext({ children, fetchOptions }: SprinterContextProps) { | ||
const [sprinter] = useState(new Sprinter(fetchOptions)); | ||
|
||
/** Balances */ | ||
const { balances, getUserBalances } = useBalances(sprinter); | ||
|
||
/** Tokens */ | ||
const { tokens, getAvailableTokens } = useTokens(sprinter); | ||
|
||
/** Chains */ | ||
const { chains, getAvailableChains } = useChains(sprinter); | ||
|
||
/** Solutions */ | ||
const { solution, getSolution } = useSolution(sprinter); | ||
|
||
/** Call Solution */ | ||
const { callSolution, getCallSolution } = useCallSolution(sprinter); | ||
|
||
/** Initialization */ | ||
useEffect(() => { | ||
getAvailableTokens(); | ||
getAvailableChains(); | ||
}, [sprinter]); | ||
|
||
return <Context.Provider value={{ | ||
balances, getUserBalances, | ||
tokens, getAvailableTokens, | ||
chains, getAvailableChains, | ||
solution, getSolution, | ||
callSolution, getCallSolution | ||
}}>{children}</Context.Provider>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import {useCallback, useContext} from "react"; | ||
import {Context} from "./context.tsx"; | ||
import {Address} from "@chainsafe/sprinter-sdk"; | ||
import {BalancesEntry} from "./internal/useBalances.ts"; | ||
|
||
/** Everything from context */ | ||
export function useSprinter() { | ||
const context = useContext(Context); | ||
|
||
if (!context) throw new Error('Sprinter Context is not defined'); | ||
|
||
return context; | ||
} | ||
|
||
/** Balances */ | ||
const balancesEmptyState = { | ||
data: null, | ||
loading: false, | ||
error: null, | ||
}; | ||
|
||
export function useSprinterBalances(account: Address) { | ||
const { balances: _balances, getUserBalances: _getUserBalances } = useSprinter(); | ||
|
||
const balances: BalancesEntry = _balances[account] || balancesEmptyState; | ||
const getUserBalances = useCallback(() => _getUserBalances(account), [account]); | ||
|
||
return { balances, getUserBalances }; | ||
} | ||
|
||
/** Tokens */ | ||
export function useSprinterTokens() { | ||
const { tokens, getAvailableTokens } = useSprinter(); | ||
return { tokens, getAvailableTokens }; | ||
} | ||
|
||
/** Chains */ | ||
export function useSprinterChains() { | ||
const { chains, getAvailableChains } = useSprinter(); | ||
return { chains, getAvailableChains }; | ||
} | ||
|
||
/** Solutions */ | ||
export function useSprinterSolution() { | ||
const { solution, getSolution } = useSprinter(); | ||
return { solution, getSolution }; | ||
} | ||
|
||
/** Call Solution */ | ||
export function useSprinterCallSolution() { | ||
const { callSolution, getCallSolution } = useSprinter(); | ||
return { callSolution, getCallSolution }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import {useCallback, useReducer} from "react"; | ||
|
||
const initialState = { | ||
data: null, | ||
loading: false, | ||
error: null, | ||
}; | ||
|
||
export function useAsyncRequest<T>() { | ||
const [state, dispatch] = useReducer(fetchReducer<T>, initialState as AsyncRequestState<T>); | ||
|
||
const makeRequest = useCallback((request: Promise<T>) => { | ||
dispatch({ type: RequestAction.INIT }); | ||
|
||
request.then(result => { | ||
dispatch({ type: RequestAction.SUCCESS, payload: result }); | ||
}).catch((error: Error) => { | ||
dispatch({ type: RequestAction.FAILURE, error: error.message }); | ||
}); | ||
}, [dispatch]); | ||
|
||
return { state, makeRequest }; | ||
} | ||
|
||
enum RequestAction { | ||
INIT = 'REQUEST_INIT', | ||
SUCCESS = 'REQUEST_SUCCESS', | ||
FAILURE = "REQUEST_FAILURE", | ||
} | ||
|
||
export interface AsyncRequestState<T> { | ||
data: T | null; | ||
loading: boolean; | ||
error: string | null; | ||
} | ||
|
||
type AsyncRequestActions<T> = | ||
| { type: RequestAction.INIT } | ||
| { type: RequestAction.SUCCESS; payload: T } | ||
| { type: RequestAction.FAILURE; error: string }; | ||
|
||
const fetchReducer = <T>(state: AsyncRequestState<T>, action: AsyncRequestActions<T>): AsyncRequestState<T> => { | ||
switch (action.type) { | ||
case RequestAction.INIT: | ||
return { | ||
...state, | ||
loading: true, | ||
error: null, | ||
}; | ||
case RequestAction.SUCCESS: | ||
return { | ||
...state, | ||
loading: false, | ||
data: action.payload, | ||
}; | ||
case RequestAction.FAILURE: | ||
return { | ||
...state, | ||
loading: false, | ||
error: action.error, | ||
}; | ||
default: | ||
throw new Error('Unknown action type'); | ||
} | ||
}; |
Oops, something went wrong.