-
Notifications
You must be signed in to change notification settings - Fork 248
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
Add usage examples to the guide #920
Comments
Another really useful example (and something I'm currently struggling with) is showing how to sign partial extrinsics with something like polkadot.js in the browser |
Noted, thanks! The new guide will actually have one example of building a partial extrinsic, getting the signer payload and then getting an extrinsic ready to submit with the final signature. It doesn't look at how to sign the payload though and assumes some external thing will do it. A full e2e example of this is something that's on my mind :) |
Also added #942; let's make sure we cover configuring and using Subxt for some parachain (this might be: how to create custom config (ie look in metadata / runtime definition of chain and see if types/extra params line up for instance). |
@boyswan just FYI, we did eventually work out how to use a browser extension to sign partial extrinsics produced by Subxt; we're working on the example at #1067 incase it helps! It's somewhat tedious because browser extensions expect a SignerPayloadJSON type that has a bunch of things in, and don't accept a raw signer payload at the moment. Over time I hope that browser extensions will improve this interface since metadata is available to help decoding etc nowadays. |
Thanks for this! I actually ended up going down a similar route and constructing the payload in JS, but it's great to see a more rust-y example |
Ooh, I'd love to see what approach you took; do you have any code you can link to? |
This is pretty much the approach I took: ...
let nonce = client.rpc().system_account_next_index(&account_id).await?;
let js_signature = sign_message(self.account.into(), call_bytes, nonce).await;
let ext_bytes: Vec<u8> = serde_wasm_bindgen::from_value(js_signature).unwrap_or_default();
let extrinsic = SubmittableExtrinsic::from_bytes(client, ext_bytes);
let mut tx = extrinsic.submit_and_watch().await?; Then calling via wasm-bindgen: export let sign_message = async (address: string, method_u8: Uint8Array, nonce_u32: number) => {
return new Promise(async (res, rej) => {
let injector = await web3FromAddress(address);
let api = await ApiPromise.create({
provider: new WsProvider('ws://127.0.0.1:9944'),
signer: injector.signer,
});
let genesisHash = api.genesisHash;
let lastHeader = await api.rpc.chain.getHeader();
let blockHash = await api.rpc.chain.getBlockHash();
let method = u8aToHex(method_u8);
let nonce = api.createType("u32", nonce_u32);
let specVersion = api.createType("u32", api.runtimeVersion.specVersion);
let blocknumber = api.createType("BlockNumber", lastHeader.number);
let transactionVersion = api.createType("u32", api.runtimeVersion.transactionVersion)
let era = api.createType("ExtrinsicEra", {
current: lastHeader.number.toNumber(),
period: ONE_SECOND * VALIDITY_PERIOD,
});
if (!!injector.signer.signPayload) {
let payload = {
address,
blockHash: blockHash.toHex(),
blockNumber: blocknumber.toHex(),
era: era.toHex(),
genesisHash: genesisHash.toHex(),
method,
nonce: nonce.toHex(),
specVersion: specVersion.toHex(),
transactionVersion: transactionVersion.toHex(),
tip: "0x0",
signedExtensions: api.registry.signedExtensions,
version: 4,
};
let { signature } = await injector.signer.signPayload(payload);
let extrinsic = api.registry.createType(
'Extrinsic',
{ method: payload.method },
{ version: payload.version }
);
extrinsic.addSignature(payload.address, signature, payload);
res(extrinsic.toU8a())
} else {
rej()
}
})
} Trying to figure out the magic combination of types via polkadot.js was... painful! |
Ah brilliant, thankyou! Yeah, we tried that sort of approach first, though we were trying to get PJS to decode the entire signer payload and it sortof half worked but didn't. Your approach of encoding the specific values is def cleaner :) Maybe there's a way we can show both approaches in an example; will have to think about that! I think depending on what you're trying to do, either could be good to know about! |
This is a follow-up to #898, because I wanted to break the work down a little.
Add something a bit like this to the end of the main page of the guide:
(actual use cases we want to show need to be thought through)
And then add the corresponding sections and examples etc as needed.
The text was updated successfully, but these errors were encountered: