diff --git a/README.md b/README.md index 2bba9b33..db231888 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,14 @@ Currently is not packaged since it is under heavy development. As such you need Once added, you can create an account (via a generated seed) or import via an existing seed. The UI, when loaded, will show these accounts as ` (extension)` +# Development + +The repo is split into a number of packages - + +- [extension](packages/extension/) - All the injection and background processing logic (the main entry) +- [extension-ui](packages/extension-ui/) - The UI components for the extension +- [extension-dapp](packages/extension-dapp/) - A convenience wrapper to work with the injected objects, simplifying data extraction for any dapp that wishes to integrate the extension (or any extension that supports the interface) + ## Technical The extension injects `injectedWeb3` into the global `window` object, exposing the following: diff --git a/packages/extension-dapp/README.md b/packages/extension-dapp/README.md index 1e6e9b02..78a3903e 100644 --- a/packages/extension-dapp/README.md +++ b/packages/extension-dapp/README.md @@ -1,6 +1,13 @@ # @polkadot/extension-dapp -A basic injected that manipulates the `window.injectedWeb3` to extract all the providers added to the page. +A basic extractor that manipulates the `window.injectedWeb3` to retrieve all the providers added to the page. It has a number of utilities - + +- `web3Enable(dappName: string)` - to be called before anything else, retrieves the list of all injected extensions/providers +- `web3Accounts()` - returns alist of all the injected accounts, accross all extensions (source in meta) +- `web3FromAddress(address: string)` - Retrieves a provider for a specific address +- `web3FromSource(name: string)` - Retriebes a provider identified by the name +- `isWeb3Injected` - boolean to indicate if `injectedWeb3` was found on the page +- `web3EnablePromise` - `null` or the value of the last call to `web3Enable` ## Usage @@ -9,11 +16,13 @@ import { web3Accounts, web3Enable, web3FromAddress } from '@polkadot/extension-d // returns an array of all the injected sources // (this needs to be called first, before other requests) -const allInjected = await web3Enable(...my dapp name...); +const allInjected = await web3Enable('my cool dapp'); // returns an array of { address, meta: { name, source } } const allAccounts = await web3Accounts(); // finds an injector for an address -const injector = await web3FromAddress(...address...) +const injector = await web3FromAddress('5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE'); +// sets the signer for the address on the @polkadot/api +api.setSigner(injector.signer); ``` diff --git a/packages/extension-dapp/src/index.ts b/packages/extension-dapp/src/index.ts index 1935ee02..51bb56ce 100644 --- a/packages/extension-dapp/src/index.ts +++ b/packages/extension-dapp/src/index.ts @@ -7,8 +7,8 @@ import { InjectedAccountWithMeta, InjectedExtension, InjectedExtensionInfo, Inje // just a helper (otherwise we cast all-over, so shorter and more readable) const injectedWeb3 = (window as InjectedWindow).injectedWeb3 || {}; -// have we found the window.injectedWeb3 -const isWeb3Injected = !!injectedWeb3 && Object.keys(injectedWeb3).length !== 0; +// have we found a properly constructed window.injectedWeb3 +const isWeb3Injected = Object.keys(injectedWeb3).length !== 0; // we keep the last promise created around (for queries) let web3EnablePromise: Promise> | null = null; diff --git a/packages/extension-ui/package.json b/packages/extension-ui/package.json index 09aadf10..953f45d9 100644 --- a/packages/extension-ui/package.json +++ b/packages/extension-ui/package.json @@ -5,7 +5,7 @@ "author": "Jaco Greeff ", "license": "Apache-2", "dependencies": { - "@polkadot/ui-identicon": "^0.39.1", + "@polkadot/ui-identicon": "^0.40.0-beta.1", "@types/react-router": "^5.0.0", "@types/react-router-dom": "^4.3.3", "react-router": "^5.0.0", diff --git a/packages/extension/package.json b/packages/extension/package.json index 9e8c6d75..9cbeb68c 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -7,7 +7,7 @@ "dependencies": { "@polkadot/api": "^0.80.0-beta.2", "@polkadot/extension-ui": "^0.1.1-beta.5", - "@polkadot/ui-keyring": "^0.39.1" + "@polkadot/ui-keyring": "^0.40.0-beta.1" }, "devDependencies": { "@types/chrome": "^0.0.86", diff --git a/packages/extension/src/events.ts b/packages/extension/src/events.ts index 8c54d078..b3499cc8 100644 --- a/packages/extension/src/events.ts +++ b/packages/extension/src/events.ts @@ -2,11 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -// for FireFox, we need to listent here to allow origin restrictions to not -// be an issue (otherwise we cannot read the properties on the created events) -// const contentDocument = typeof gBrowser !== 'undefined' -// ? gBrowser.selectedBrowser.contentDocument -// : document; const eventTarget = document; const events = { diff --git a/packages/extension/src/inject/index.ts b/packages/extension/src/inject/index.ts index 63afe16d..e63f68a7 100644 --- a/packages/extension/src/inject/index.ts +++ b/packages/extension/src/inject/index.ts @@ -22,6 +22,8 @@ type Callbacks = { } }; +// small helper with the typescript types, just cast window +const windowInject = window as InjectedWindow; const callbacks: Callbacks = {}; let idCounter = 0; @@ -33,12 +35,19 @@ function sendMessage (message: MessageTypes, request: any = null): Promise callbacks[id] = { resolve, reject }; - document.dispatchEvent( + eventTarget.dispatchEvent( new CustomEvent(events.request, { detail: { id, message, request } }) ); }); } +// the enable function, called by the dapp to allow access +async function enable (origin: string): Promise { + await sendMessage('authorize.tab', { origin }); + + return new Injected(sendMessage); +} + // setup a response listener (events created by the loader for extension responses) eventTarget.addEventListener(events.response, (event) => { const response = (event as CustomEvent).detail; @@ -58,16 +67,11 @@ eventTarget.addEventListener(events.response, (event) => { } }); -// small helper with the typescript types, just cast window -const windowInject = window as InjectedWindow; - // don't clobber the existing object, we will add it it (or create as needed) windowInject.injectedWeb3 = windowInject.injectedWeb3 || {}; // add our enable function windowInject.injectedWeb3['polkadot-js'] = { - enable: (origin: string): Promise => - sendMessage('authorize.tab', { origin }).then(() => new Injected(sendMessage)), - name: 'polkadot-js', // process.env.PKG_NAME as string, + enable, version: process.env.PKG_VERSION as string -} as any; // FIXME For now, the name attribute is required by old +}; diff --git a/yarn.lock b/yarn.lock index 68581795..37bdfd71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1940,13 +1940,13 @@ "@polkadot/keyring" "^0.91.1" "@polkadot/util" "^0.91.1" -"@polkadot/ui-identicon@^0.39.1": - version "0.39.1" - resolved "https://registry.yarnpkg.com/@polkadot/ui-identicon/-/ui-identicon-0.39.1.tgz#c0080a180940d23810d8b757785dee2e1ac451a1" - integrity sha512-mioETuDdfomLCGIF59SLflqgVsuUGczL414+VzlpMQbeo80Xq+UZkHBUZA47IGcUWokWzNuYvw6unFfXg/08Fw== +"@polkadot/ui-identicon@^0.40.0-beta.1": + version "0.40.0-beta.1" + resolved "https://registry.yarnpkg.com/@polkadot/ui-identicon/-/ui-identicon-0.40.0-beta.1.tgz#890a6f6dd4f20efa44bca805872bca4227bd6220" + integrity sha512-uvC+jWz+tv8NBEMeUxu5M4HGCoL1uzbKRKq9XqZevJMLpbAnmqa50/NT6HdNdYEyHNM7HM0rb/XSCcxnatzL0g== dependencies: "@babel/runtime" "^7.4.5" - "@polkadot/ui-settings" "^0.39.1" + "@polkadot/ui-settings" "^0.40.0-beta.1" "@types/color" "^3.0.0" "@types/react-copy-to-clipboard" "^4.2.6" color "^3.0.0" @@ -1954,20 +1954,20 @@ react-copy-to-clipboard "^5.0.1" styled-components "^4.2.0" -"@polkadot/ui-keyring@^0.39.1": - version "0.39.1" - resolved "https://registry.yarnpkg.com/@polkadot/ui-keyring/-/ui-keyring-0.39.1.tgz#8c0d2093bba67f5a3c350a20e4c6eda4acecf13f" - integrity sha512-+RBd6x9M6JGLNiDlx44fB4+e+5jAif5wn/4aYYWsVSHV+dmQNBl7TbNRWtAn6c3+GN3C+aJudWBLWbtFOafRrA== +"@polkadot/ui-keyring@^0.40.0-beta.1": + version "0.40.0-beta.1" + resolved "https://registry.yarnpkg.com/@polkadot/ui-keyring/-/ui-keyring-0.40.0-beta.1.tgz#0c59bf99668e4518b6b00ffa9b4781afc06a723e" + integrity sha512-T0vnRTKOHAFwqN1e5lQ8Gx2MWb2CMopR/hnuKJTBOsDUMGgS7rxWvnWgACdAGeVnD9/C+05aKt6NVY9ADqeGCw== dependencies: "@babel/runtime" "^7.4.5" "@types/store" "^2.0.1" store "^2.0.12" styled-components "^4.2.0" -"@polkadot/ui-settings@^0.39.1": - version "0.39.1" - resolved "https://registry.yarnpkg.com/@polkadot/ui-settings/-/ui-settings-0.39.1.tgz#174b076b282b3becf6cdcab70be8965cecedf710" - integrity sha512-HjtxJiRCVH0eQ4HH+d24J/XFNtwaAbTskKPRMN+qptLZWghqFrXi4F6JWIBzdTKdSnzvgjQckHr41rYkbrb8oQ== +"@polkadot/ui-settings@^0.40.0-beta.1": + version "0.40.0-beta.1" + resolved "https://registry.yarnpkg.com/@polkadot/ui-settings/-/ui-settings-0.40.0-beta.1.tgz#793c17942acabd958fb7b7e3fee2ba6807397a71" + integrity sha512-Vq35tiBICI1WeLgAFmY8mNry1PV53wQBIy2RbPH3DrfvFG8D7QeFeJ9yY2P79l+CoyKyvU8Uly08QhxXIfOeXw== dependencies: "@babel/runtime" "^7.4.5" "@types/store" "^2.0.1"