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

Browser extension signing example #1067

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d4c8158
routing and signing example
tadeohepperle May 26, 2023
e2ffe65
cliipy fix
tadeohepperle May 26, 2023
0efc233
submitting extrinsics
tadeohepperle May 30, 2023
b40026d
change order of lines
tadeohepperle May 30, 2023
526803c
Skip call variants if there aren't any (#980)
jsdw May 26, 2023
b5ae185
Tidy up some metadata accessing (#978)
jsdw May 26, 2023
58813bf
Bump tokio from 1.28.1 to 1.28.2 (#984)
dependabot[bot] May 29, 2023
cb223d7
Bump regex from 1.8.2 to 1.8.3 (#986)
dependabot[bot] May 29, 2023
5e58805
Bump quote from 1.0.27 to 1.0.28 (#983)
dependabot[bot] May 29, 2023
a493369
Bump proc-macro2 from 1.0.58 to 1.0.59 (#985)
dependabot[bot] May 29, 2023
add2339
restrict sign_with_address_and_signature interface (#988)
tadeohepperle May 30, 2023
bd1f29d
changing js bridge
tadeohepperle Jun 1, 2023
2f54934
dryrunresult ok
tadeohepperle Jul 13, 2023
a7b3433
submitting extrinsic working
tadeohepperle Jul 13, 2023
37be177
tiny up code and ui
tadeohepperle Jul 13, 2023
a0a1cc6
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 13, 2023
4e5c107
formatting
tadeohepperle Jul 13, 2023
ef9d739
remove todos
tadeohepperle Jul 13, 2023
8f6658b
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 19, 2023
9f0de42
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 19, 2023
66dd32d
support tip and mortality
tadeohepperle Jul 19, 2023
402db95
Prevent bug when reusing type ids in hashing (#1075)
tadeohepperle Jul 19, 2023
953d7c0
small adjustment
tadeohepperle Jul 20, 2023
c0a63ef
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 20, 2023
d5c969a
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 20, 2023
1c6e248
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 21, 2023
b0a8bd1
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 24, 2023
23ac08b
fix lock file
tadeohepperle Jul 24, 2023
32cb9b7
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 25, 2023
99abc29
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Jul 25, 2023
b776032
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
jsdw Jul 31, 2023
1fbb0f9
tell users how to add Alice account to run signing example
jsdw Jul 31, 2023
ea6f8be
adjust to PR comments
tadeohepperle Aug 1, 2023
eb01971
Merge branch 'master' into tadeo-hepperle-browser-extension-signing-e…
tadeohepperle Aug 1, 2023
0e64607
fmt
tadeohepperle Aug 1, 2023
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
498 changes: 246 additions & 252 deletions examples/wasm-example/Cargo.lock

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion examples/wasm-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ edition = "2021"
[dependencies]
futures = "0.3.28"
subxt = { path = "../../subxt", default-features = false, features = ["jsonrpsee", "web"], target_arch = "wasm32" }
yew = {version = "0.20.0", features = ["csr"] }
yew = { version = "0.20.0", features = ["csr"] }
web-sys = "0.3.63"
hex = "0.4.3"
yew-router = "0.17.0"
js-sys = "0.3.63"
wasm-bindgen = "0.2.86"
wasm-bindgen-futures = "0.4.36"
anyhow = "1.0.71"
serde = "1.0.163"
serde_json = "1.0.96"
3 changes: 3 additions & 0 deletions examples/wasm-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ Then, in another terminal, run the app locally with:
trunk serve --open
```

# signing example

For the signing example, we use the `@polkadot/extension-dapp` NPM package to talk to wallets loaded as browser extensions. In order to sign and submit the transaction using the `polkadot --dev` node we spawned above, you'll need to create a dev account in your wallet of choice. Use the recovery phrase `bottom drive obey lake curtain smoke basket hold race lonely fit walk` and the derivation path `//Alice` to create a dev account that can be used.
5 changes: 3 additions & 2 deletions examples/wasm-example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<link data-trunk rel="scss" href="index.scss" />
<title>Yew App</title>
<link data-trunk rel="inline" href="index.js" />
<title>Subxt Examples Yew App</title>
</head>
</html>
</html>
89 changes: 89 additions & 0 deletions examples/wasm-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* The `@polkadot/extension-dapp` package can be dynamically imported.
* Usually it is wise to use a package manager like npm or yarn to install it as a dependency.
*
* The `getPolkadotJsExtensionMod` closure returns the `@polkadot/extension-dapp` module on demand.
*/
let getPolkadotJsExtensionMod = (() => {
let mod = null;

// initialize `@polkadot/extension-dapp` module on page load
let initPromise = (async () => {
mod = await import(
"https://cdn.jsdelivr.net/npm/@polkadot/extension-dapp@0.46.3/+esm"
);
})();

// return a function that waits for initialization to be finished, in case mod is not initialized yet.
return async () => {
if (mod == null) {
await initPromise;
}
return mod;
};
})();

/**
* Queries wallets from browser extensions like Talisman and the Polkadot.js extension for user accounts.
*
* @returns a json string that contains all the accounts that were found.
*/
async function getAccounts() {
const extensionMod = await getPolkadotJsExtensionMod();
await extensionMod.web3Enable("Subxt Example App");
const allAccounts = await extensionMod.web3Accounts();
const accountObjects = allAccounts.map((account) => ({
name: account.meta.name, // e.g. "Alice"
source: account.meta.source, // e.g. "talisman", "polkadot-js"
ty: account.type, // e.g. "sr25519"
address: account.address // e.g. "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
}));
console.log(accountObjects);
return JSON.stringify(accountObjects);
}

/**
* Signs a payload via browser extension
*
* @param payloadAsStr a string representing a JSON object like this:
* let payload = {
* "specVersion": "0x000024d6",
* "transactionVersion": "0x00000018",
* "address": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
* "blockHash": "0xd7aad6185db012b7ffbce710b55234d6c9589170566b925ee50cfa3d7f1e6f8f",
* "blockNumber": "0x00000000",
* "era": "0x0000",
* "genesisHash": "0xd7aad6185db012b7ffbce710b55234d6c9589170566b925ee50cfa3d7f1e6f8f",
* "method": "0x0503001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0b00c465f14670",
* "nonce": "0x00000000",
* "signedExtensions": [
* "CheckNonZeroSender",
* "CheckSpecVersion",
* "CheckTxVersion",
* "CheckGenesis",
* "CheckMortality",
* "CheckNonce",
* "CheckWeight",
* "ChargeTransactionPayment",
* "PrevalidateAttests"
* ],
* "tip": "0x00000000000000000000000000000000",
* "version": 4
* };
* @param source the extension used for signing as a string
* @param address the ss58 encoded address as a string
* @returns {Promise<*>}
*/
async function signPayload(payloadAsStr, source, address) {
let payload = JSON.parse(payloadAsStr);
const extensionMod = await getPolkadotJsExtensionMod();
const injector = await extensionMod.web3FromSource(source);
const signPayload = injector?.signer?.signPayload;
if (!!signPayload) {
const {signature} = await signPayload(payload);
console.log("signature js:", signature)
return signature;
} else {
throw "The extension's injector does not have a `signPayload` function on its `signer`";
}
}
151 changes: 98 additions & 53 deletions examples/wasm-example/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,101 @@ $primary: #24cc85;
$secondary: #1f624a;
$dark: #242a35;

*{
font-family: monospace;
color: $dark;

}

html{
background-color: $dark;
display: flex;
justify-content: center;
height: 100%;
}

h1{
font-weight: bolder;
color: $dark;
}

body{
width: 800px;
max-width: 100%;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
height: 100%;
margin: 0px;
padding: 16px;
background-color: $primary;
}


p{
white-space: pre-wrap;
border-radius: 8px;
padding: 8px;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
background-color: $dark;
color: white;
}
button{
font-size: large;
padding: 8px 16px;
font-weight: bold;
background-color: $dark;
border: none;
border-radius: 8px;
color: white;
cursor: pointer;
display: block;
margin-top: 8px;
}

button:hover{
background-color: $secondary;
}
* {
font-family: monospace;
color: $dark;
}

html {
background-color: $dark;
display: flex;
justify-content: center;
height: 100%;
}

h1 {
font-weight: bolder;
color: $dark;
}

body {
width: 800px;
max-width: 100%;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
min-height: 100%;
margin: 0px;
padding: 16px;
background-color: $primary;
}

p {
white-space: pre-wrap;
border-radius: 8px;
padding: 8px;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
background-color: $dark;
color: white;
}

button {
font-size: large;
padding: 8px 16px;
font-weight: bold;
background-color: $dark;
border: none;
border-radius: 8px;
color: white;
cursor: pointer;
display: block;
margin-top: 8px;
}

a {
text-decoration: none;
}

button:hover {
background-color: $secondary;
}

input {
font-size: large;
background-color: white;
color: $dark;
border-radius: 8px;
padding: 8px;
}

.mb {
margin-bottom: 12px;
}

small {
color: #24cc85;
}

.error {
color: red;
background: black;
padding: 8px;
border-radius: 8px;
}

@keyframes loading {
0% {
transform: translateX(0);
opacity: 1;
}
50% {
transform: translateX(20px);
opacity: 0.5;
}
100% {
transform: translateX(0);
opacity: 1;
}
}

.loading {
animation: loading 0.7s infinite;
}
Loading
Loading