Skip to content

Commit

Permalink
Merge pull request #83 from gnosisguild/safe-apps-sdk
Browse files Browse the repository at this point in the history
Connect via Safe Apps SDK
  • Loading branch information
jfschwarz authored Feb 12, 2024
2 parents 6153e30 + 0dc53ea commit 4c014ea
Show file tree
Hide file tree
Showing 50 changed files with 1,014 additions and 222 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ When the simulator iframe opens any page, we inject the build/inject.js script a
The injected script then runs in the context of the Dapp and injects an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compatible API at `window.ethereum`.
The injected provider forwards all `request` calls to the parent extension page via `window.postMessage` where they are recorded and executed in a fork of the connected network.

We also subscribe to messages sent via the [safe-apps-sdk](https://github.com/safe-global/safe-apps-sdk).
This enables instant and smart-account optimized connections to Safe-compatible apps.

### Simulating transaction in a fork

When the provider we inject into the Dapp iframe receives a transaction request, we record it and simulate the transaction in a fork of the target network, impersonating the Safe.
Expand Down
1 change: 1 addition & 0 deletions extension/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"blockies",
"borderless",
"Bytecode",
"ccip",
"cowswap",
"Delegatecall",
"delegatecalls",
Expand Down
10 changes: 9 additions & 1 deletion extension/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@
"@typescript-eslint/no-non-null-assertion": "off",
"react/prop-types": "off", // we are not exporting any components so this rule is not super relevant, in tests we don't want to be forced to define prop types
"jsx-a11y/no-onchange": "off", // this rule is deprecated, but somehow still part of jsx-a11y/recommended
"jsx-a11y/label-has-associated-control": "off" // this rule gives false positives when the control lives in the component of a child element
"jsx-a11y/label-has-associated-control": "off", // this rule gives false positives when the control lives in the component of a child element
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
]
},
"settings": {
"react": {
Expand Down
165 changes: 165 additions & 0 deletions extension/.pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions extension/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
"typescript.tsdk": ".yarn/sdks/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"jest.jestCommandLine": "yarn test",
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
},
"eslint.nodePath": ".yarn/sdks",
"prettier.prettierPath": ".yarn/sdks/prettier/index.js"
"prettier.prettierPath": ".yarn/sdks/prettier/index.js",
"mdx-preview.preview.useVscodeMarkdownStyles": false
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"@gnosis.pm/zodiac": "^3.4.2",
"@safe-global/api-kit": "^1.3.1",
"@safe-global/protocol-kit": "^1.3.0",
"@safe-global/safe-apps-sdk": "^9.0.0",
"@safe-global/safe-core-sdk-types": "^2.3.0",
"@safe-global/safe-gateway-typescript-sdk": "^3.14.0",
"@shazow/whatsabi": "^0.2.1",
"@testing-library/jest-dom": "^5.16.1",
"@typechain/ethers-v5": "^10.2.1",
Expand Down Expand Up @@ -85,4 +87,4 @@
"typescript-plugin-css-modules": "^3.4.0"
},
"packageManager": "[email protected]"
}
}
19 changes: 1 addition & 18 deletions extension/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { validateAddress } from './utils'
const Routes: React.FC = () => {
const connectionsRouteMatch = useMatchConnectionsRoute()
const pushConnectionsRoute = usePushConnectionsRoute()
const { connection, connected } = useConnection()
const { connection } = useConnection()

const isConnectionsRoute = connectionsRouteMatch.isMatch
const connectionChangeRequired =
Expand All @@ -35,9 +35,6 @@ const Routes: React.FC = () => {
const connectionToEdit =
connections.length === 1 ? connections[0].id : undefined

const waitForWallet =
!isConnectionsRoute && !connectionChangeRequired && !connected

useUpdateLastUsedConnection()

// open connections drawer if a valid connection is not available
Expand All @@ -52,21 +49,7 @@ const Routes: React.FC = () => {
connectionChangeRequired,
])

// open connections drawer if wallet is not connected, but only after a small delay to give the wallet time to connect when initially loading the page
useEffect(() => {
let timeout: number
if (waitForWallet) {
timeout = window.setTimeout(() => {
pushConnectionsRoute()
}, 200)
}
return () => {
window.clearTimeout(timeout)
}
}, [waitForWallet, pushConnectionsRoute])

if (!isConnectionsRoute && connectionChangeRequired) return null
if (!isConnectionsRoute && waitForWallet) return null

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface Request {
params?: Array<any>
}

export default class BridgeHost {
export default class Eip1193Bridge {
private provider: Eip1193Provider
private connection: Connection
private source: WindowProxy | undefined
Expand All @@ -15,11 +15,11 @@ export default class BridgeHost {
this.connection = connection
}

setProvider(provider: Eip1193Provider) {
setProvider = (provider: Eip1193Provider) => {
this.provider = provider
}

setConnection(connection: Connection) {
setConnection = (connection: Connection) => {
if (connection.avatarAddress !== this.connection.avatarAddress) {
this.emitBridgeEvent('accountsChanged', [[connection.avatarAddress]])
}
Expand Down
Loading

0 comments on commit 4c014ea

Please sign in to comment.