Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #67: Update CRA template/React SDK to use new SDK version #68

Merged
merged 18 commits into from
Dec 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,21 @@
"packages/*"
]
},
"peerDependencies": {
"react": "^16.8.2"
},
"dependencies": {
"lerna": "^3.22.1"
},
"devDependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1",
"@typescript-eslint/eslint-plugin": "^4.10.0",
"@typescript-eslint/parser": "^4.10.0",
"eslint": "7.15.0",
"eslint-config-prettier": "^7.0.0",
"eslint-plugin-prettier": "^3.2.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^26.6.3",
"ts-jest": "^26.4.4",
"typescript": "~4.1.2"
"typescript": "^4.1.3"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/safe-app-cra-template",
"version": "1.0.1",
"name": "@gnosis.pm/cra-template-safe-app",
"version": "2.0.0-beta.4",
"description": "Gnosis Safe App Starter",
"author": "Gnosis (https://gnosis.pm)",
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@
"package": {
"homepage": "./",
"dependencies": {
"@gnosis.pm/safe-apps-sdk": "^0.3.1",
"@gnosis.pm/safe-react-components": "^0.2.0",
"@gnosis.pm/safe-apps-react-sdk": "1.0.0-beta.1",
"@gnosis.pm/safe-react-components": "^0.3.0",
"@material-ui/core": "^4.11.0",
"@rmeissner/safe-apps-react-sdk": "0.4.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^10.4.9",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.1.3",
"@types/jest": "^26.0.10",
"@types/node": "^14.6.2",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/styled-components": "^5.1.2",
"react": "^16.13.1",
"react": "^17.0.1",
"react-app-rewired": "^2.1.6",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"styled-components": "^5.1.1",
"typescript": "~4.0.2"
"typescript": "~4.1.3"
},
"scripts": {
"start": "react-app-rewired start",
Expand All @@ -32,11 +31,7 @@
},
"browserslist": {
"production": [">0.2%", "not dead", "not op_mini all"],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
"development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback, useState } from 'react';
import styled from 'styled-components';
import { Button, Loader, Title } from '@gnosis.pm/safe-react-components';
import { useSafe } from '@rmeissner/safe-apps-react-sdk';
import { useSafeAppsSDK } from '@gnosis.pm/safe-apps-react-sdk';

const Container = styled.form`
margin-bottom: 2rem;
Expand All @@ -15,29 +15,33 @@ const Container = styled.form`
`;

const App: React.FC = () => {
const safe = useSafe();
const { sdk, safe } = useSafeAppsSDK();
const [submitting, setSubmitting] = useState(false);

const submitTx = useCallback(async () => {
setSubmitting(true);
try {
const safeTxHash = await safe.sendTransactions([
{
to: safe.info.safeAddress,
value: '0',
data: '0x',
},
]);
const { safeTxHash } = await sdk.txs.send({
txs: [
{
to: safe.safeAddress,
value: '0',
data: '0x',
},
],
});
console.log({ safeTxHash });
const safeTx = await safe.loadSafeTransaction(safeTxHash);
const safeTx = await sdk.txs.getBySafeTxHash(safeTxHash);
console.log({ safeTx });
} catch (e) {
console.error(e);
}
setSubmitting(false);
}, [safe]);
}, [safe, sdk]);

return (
<Container>
<Title size="md">{safe.info.safeAddress}</Title>
<Title size="md">{safe.safeAddress}</Title>
{submitting ? (
<>
<Loader size="md" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from 'styled-components';
import { theme } from '@gnosis.pm/safe-react-components';
import { Loader, Title } from '@gnosis.pm/safe-react-components';
import SafeProvider from '@rmeissner/safe-apps-react-sdk';
import { theme, Loader, Title } from '@gnosis.pm/safe-react-components';
import SafeProvider from '@gnosis.pm/safe-apps-react-sdk';

import GlobalStyle from './GlobalStyle';
import App from './App';
Expand All @@ -13,7 +12,7 @@ ReactDOM.render(
<ThemeProvider theme={theme}>
<GlobalStyle />
<SafeProvider
loading={
loader={
<>
<Title size="md">Waiting for Safe...</Title>
<Loader size="md" />
Expand Down
38 changes: 24 additions & 14 deletions packages/safe-apps-react-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ This sdk should provide a simple way to write a React.js [Safe app](https://docs
### How to use

- Add npm package

```bash
yarn add @rmeissner/safe-apps-react-sdk
```

- Add `SafeProvider`
- Add `SafeProvider`
Safe provider accepts `loader` and `options` props

```js
// ... other imports
import SafeProvider from '@rmeissner/safe-apps-react-sdk';
Expand All @@ -22,38 +25,45 @@ ReactDOM.render(
<App /> // Your app
</SafeProvider>
</React.StrictMode>,
document.getElementById('root')
document.getElementById('root'),
);
```

- Use Safe
- Use Safe Apps SDK Hook

```js
// ... other imports
import { useSafe } from '@rmeissner/safe-apps-react-sdk';
import { useSafeAppsSDK } from '@rmeissner/safe-apps-react-sdk';

const App = () => {
const safe = useSafe()
return (<div>{safe.info.safeAddress}</div>)
}
const { sdk, connected, safe } = useSafeAppsSDK();
return <div>{safe.safeAddress}</div>;
};
```

### Usages

#### Send transactions

```js
const txs: Transaction[] = [
{
"to": "0x31415629...",
"value": "0",
"data": "0xbaddad"
to: '0x31415629...',
value: '0',
data: '0xbaddad',
},
//...
]
];
// Returns a hash to identify the Safe transaction
const safeTxHash: string = await safe.sendTransactions(txs)
const safeTxHash: string = await sdk.txs.send({ txs });
```

#### Load Safe transaction information

```js
const safeTx: SafeTransaction = await safe.loadSafeTransaction(safeTxHash)
```
const safeTx: SafeTransaction = await sdk.txs.getBySafeTxHash(safeTxHash);
```

#### More scenarios

For all available sdk methods, please refer to the [safe-apps-sdk](https://github.com/gnosis/safe-apps-sdk/tree/master/packages/safe-apps-sdk) documentation
8 changes: 3 additions & 5 deletions packages/safe-apps-react-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@gnosis.pm/safe-apps-react-sdk",
"private": false,
"version": "0.4.0",
"version": "1.0.0-beta.1",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
Expand All @@ -11,10 +11,8 @@
],
"author": "Gnosis (https://gnosis.pm)",
"dependencies": {
"@gnosis.pm/safe-apps-sdk": "0.4.1",
"@types/jest": "^24.0.0",
"@types/uuid": "^8.3.0",
"uuid": "^8.3.0"
"@gnosis.pm/safe-apps-sdk": "1.0.0-beta.5",
"@types/jest": "^26.0.19"
},
"peerDependencies": {
"@types/node": "^12.0.0",
Expand Down
64 changes: 42 additions & 22 deletions packages/safe-apps-react-sdk/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,54 @@
import React, { ReactNode } from 'react';
import connectSafe, { Safe } from './safe';
import { createContext, useState, useEffect, useContext, useMemo, ReactElement } from 'react';
import SafeAppsSDK, { Opts as SDKOpts, SafeInfo } from '@gnosis.pm/safe-apps-sdk';

const SafeContext = React.createContext<Safe | undefined>(undefined);
type SafeReactSDKContext = {
sdk: SafeAppsSDK;
connected: boolean;
safe: SafeInfo;
};

const SafeContext = createContext<SafeReactSDKContext | undefined>(undefined);

interface Props {
loading?: ReactNode;
loader?: ReactElement;
opts?: SDKOpts;
}

export const SafeProvider: React.FC<Props> = ({ loading, children }) => {
const [safe] = React.useState(connectSafe());
const [connected, setConnected] = React.useState(false);
React.useEffect(() => {
safe.activate(() => {
setConnected(safe.isConnected());
});

return () => safe.deactivate();
}, [safe]);

return (
<div className="App">
{connected ? <SafeContext.Provider value={safe}>{children}</SafeContext.Provider> : loading}
</div>
);
export const SafeProvider: React.FC<Props> = ({ loader = null, opts, children }) => {
const [sdk] = useState(new SafeAppsSDK(opts));
const [connected, setConnected] = useState(false);
const [safe, setSafe] = useState<SafeInfo>({ safeAddress: '', network: 'rinkeby' });
const contextValue = useMemo(() => ({ sdk, connected, safe }), [sdk, connected, safe]);

useEffect(() => {
const fetchSafeInfo = async () => {
try {
const safeInfo = await sdk.getSafeInfo();

setSafe(safeInfo);
mmv08 marked this conversation as resolved.
Show resolved Hide resolved
setConnected(true);
} catch (err) {
setConnected(false);
}
};

fetchSafeInfo();
}, [sdk]);

if (!connected && loader) {
return loader;
}

return <SafeContext.Provider value={contextValue}>{children}</SafeContext.Provider>;
};
export const useSafe = (): Safe => {
const value = React.useContext(SafeContext);

export const useSafeAppsSDK = (): SafeReactSDKContext => {
const value = useContext(SafeContext);

if (value === undefined) {
throw new Error('You probably forgot to put <SafeProvider>.');
}

return value;
};

Expand Down
Loading