Skip to content

Commit

Permalink
feat(light-client-ext-helpers): tx-helper
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanleecode committed Jul 12, 2024
1 parent ce5ae05 commit 8e5365a
Show file tree
Hide file tree
Showing 32 changed files with 152 additions and 60 deletions.
7 changes: 7 additions & 0 deletions .changeset/fluffy-pigs-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@substrate/light-client-extension-helpers": minor
"@substrate/wallet-template": patch
---

- Add `tx-helper` package to light client extension helpers
- Replace usage of internal tx-helper with added package in wallet-template
4 changes: 4 additions & 0 deletions packages/light-client-extension-helpers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,7 @@ supervise(client, { onError: console.error })
// Supervise the client
client.supervise()
```

### tx-helper

TODO: write usage guide
15 changes: 12 additions & 3 deletions packages/light-client-extension-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"./extension-page": "./dist/extension-page/extension-page-helper.mjs",
"./web-page": "./dist/web-page/web-page-helper.mjs",
"./utils": "./dist/utils/index.mjs",
"./tx-helper": "./dist/tx-helper/index.mjs",
"./known-chain-specs": "./dist/known-chain-specs/index.mjs",
"./known-chain-specs/polkadot": "./dist/known-chain-specs/polkadot.mjs",
"./known-chain-specs/ksmcc3": "./dist/known-chain-specs/ksmcc3.mjs",
Expand All @@ -24,7 +25,7 @@
"dist"
],
"scripts": {
"build": "tsc --noEmit && tsup-node src/background/background-helper.ts src/content-script/content-script-helper.ts src/extension-page/extension-page-helper.ts src/web-page/web-page-helper.ts src/known-chain-specs/index.ts src/known-chain-specs/polkadot.ts src/known-chain-specs/ksmcc3.ts src/known-chain-specs/westend2.ts src/known-chain-specs/rococo_v2_2.ts src/utils/index.ts src/smoldot/index.ts --clean --sourcemap --platform neutral --target=es2020 --format esm --dts",
"build": "tsc --noEmit && tsup-node src/background/background-helper.ts src/content-script/content-script-helper.ts src/extension-page/extension-page-helper.ts src/web-page/web-page-helper.ts src/known-chain-specs/index.ts src/known-chain-specs/polkadot.ts src/known-chain-specs/ksmcc3.ts src/known-chain-specs/westend2.ts src/known-chain-specs/rococo_v2_2.ts src/utils/index.ts src/smoldot/index.ts src/tx-helper/index.ts --clean --sourcemap --platform neutral --target=es2020 --format esm --dts",
"dev": "pnpm build --watch",
"lint": "prettier --check README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\""
},
Expand All @@ -34,16 +35,24 @@
"trailingComma": "all"
},
"devDependencies": {
"@polkadot-api/json-rpc-provider": "~0.0.1",
"@polkadot-api/polkadot-signer": "~0.0.2",
"@types/chrome": "^0.0.268"
},
"peerDependencies": {
"@polkadot-api/json-rpc-provider": "~0.0",
"@polkadot-api/polkadot-signer": "~0.0",
"smoldot": "2.x"
},
"dependencies": {
"@polkadot-api/observable-client": "^0.3.1",
"@polkadot-api/json-rpc-provider": "^0.0.1",
"@polkadot-api/codegen": "^0.6.0",
"@polkadot-api/json-rpc-provider-proxy": "^0.1.0",
"@polkadot-api/metadata-builders": "^0.3.0",
"@polkadot-api/observable-client": "^0.3.1",
"@polkadot-api/signer": "~0.0.2",
"@polkadot-api/substrate-bindings": "^0.6.0",
"@polkadot-api/substrate-client": "^0.1.4",
"@polkadot-api/utils": "^0.1.0",
"@substrate/connect-extension-protocol": "workspace:^",
"@substrate/connect-known-chains": "workspace:^",
"rxjs": "^7.8.1"
Expand Down
76 changes: 76 additions & 0 deletions packages/light-client-extension-helpers/src/tx-helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { getObservableClient } from "@polkadot-api/observable-client"
import { createClient } from "@polkadot-api/substrate-client"
import { CreateTxOptions, JsonRpcProvider } from "./types"
import { filter, firstValueFrom, map, mergeMap, take } from "rxjs"
import * as polkadotAPI from "./polkadot-api"

type UserSignedExtensions = {
CheckMortality?:
| {
mortal: false
}
| {
mortal: true
period: number
}
ChargeTransactionPayment: bigint
ChargeAssetTxPayment: {
tip: bigint
asset?: Uint8Array
}
}

type UserSignedExtensionName = keyof UserSignedExtensions

const isUserSignedExtensionName = (s: string): s is UserSignedExtensionName => {
return (
s === "CheckMortality" ||
s === "ChargeTransactionPayment" ||
s === "ChargeAssetTxPayment"
)
}

export const createTx =
(jsonRpcProvider: JsonRpcProvider) =>
async (options: CreateTxOptions): Promise<Uint8Array> => {
const client = getObservableClient(createClient(jsonRpcProvider))
const chainHead$ = client.chainHead$()

const { best: atBlock } = await firstValueFrom(
chainHead$.best$.pipe(
mergeMap((blockInfo) =>
chainHead$.getRuntimeContext$(blockInfo.hash).pipe(
take(1),
map(({ metadata }) =>
metadata.extrinsic.signedExtensions
.map(({ identifier }) => identifier)
.filter(isUserSignedExtensionName),
),
map((userSignedExtensionNames) => ({
best: blockInfo,
userSignedExtensionNames,
})),
),
),
filter(Boolean),
),
)

const tx = await firstValueFrom(
polkadotAPI
.createTx(
chainHead$,
options.signer,
options.callData,
atBlock,
options.hinted,
)
.pipe(filter(Boolean)),
)

client.destroy()

return tx
}

export type * from "./types"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { createTx } from "./tx-helper/create-tx"
17 changes: 17 additions & 0 deletions packages/light-client-extension-helpers/src/tx-helper/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { JsonRpcProvider } from "@polkadot-api/json-rpc-provider"
import type { PolkadotSigner } from "@polkadot-api/polkadot-signer"

export type HintedSignedExtensions = Partial<{
readonly tip: bigint
readonly mortality: { mortal: false } | { mortal: true; period: number }
readonly asset: Uint8Array
readonly nonce: number
}>

export type CreateTxOptions = {
readonly signer: PolkadotSigner
readonly callData: Uint8Array
readonly hinted?: HintedSignedExtensions
}

export type { JsonRpcProvider, PolkadotSigner }
70 changes: 25 additions & 45 deletions pnpm-lock.yaml

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

4 changes: 2 additions & 2 deletions projects/wallet-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
"@polkadot-api/json-rpc-provider": "^0.0.1",
"@polkadot-api/metadata-builders": "^0.3.0",
"@polkadot-api/observable-client": "^0.3.1",
"@polkadot-api/polkadot-signer": "^0.0.1",
"@polkadot-api/signer": "^0.0.1",
"@polkadot-api/polkadot-signer": "~0.0.2",
"@polkadot-api/signer": "~0.0.2",
"@polkadot-api/substrate-bindings": "^0.6.0",
"@polkadot-api/substrate-client": "^0.1.4",
"@polkadot-api/utils": "^0.1.0",
Expand Down
18 changes: 8 additions & 10 deletions projects/wallet-template/src/background/createBackgroundRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createRpc,
RpcError,
} from "@substrate/light-client-extension-helpers/utils"
import { createTx } from "@substrate/light-client-extension-helpers/tx-helper"
import { ss58Address, ss58Decode } from "@polkadot-labs/hdkd-helpers"
import { toHex, fromHex } from "@polkadot-api/utils"
import { getPolkadotSigner } from "@polkadot-api/signer"
Expand All @@ -15,7 +16,6 @@ import { UserSignedExtensionName } from "../types/UserSignedExtension"
import { createClient } from "@polkadot-api/substrate-client"
import { getObservableClient } from "@polkadot-api/observable-client"
import { filter, firstValueFrom, map, mergeMap, take } from "rxjs"
import { createTx } from "./tx-helper/create-tx"
import * as pjs from "./pjs"
import { Bytes, Variant } from "@polkadot-api/substrate-bindings"
import { InPageRpcSpec } from "../inpage/types"
Expand Down Expand Up @@ -86,7 +86,7 @@ export const createBackgroundRpc = (
const client = getObservableClient(createClient(chain.provider))
const chainHead$ = client.chainHead$()

const { best: atBlock, userSignedExtensionNames } = await firstValueFrom(
const userSignedExtensionNames = await firstValueFrom(
chainHead$.best$.pipe(
mergeMap((blockInfo) =>
chainHead$.getRuntimeContext$(blockInfo.hash).pipe(
Expand All @@ -96,10 +96,6 @@ export const createBackgroundRpc = (
.map(({ identifier }) => identifier)
.filter(isUserSignedExtensionName),
),
map((userSignedExtensionNames) => ({
best: blockInfo,
userSignedExtensionNames,
})),
),
),
filter(Boolean),
Expand Down Expand Up @@ -166,13 +162,15 @@ export const createBackgroundRpc = (
? userSignedExtensions.ChargeAssetTxPayment?.tip
: userSignedExtensions.ChargeTransactionPayment) ?? 0n

const tx = await firstValueFrom(
createTx(chainHead$, signer, fromHex(callData), atBlock, {
const tx = await createTx(chain.provider)({
signer,
callData: fromHex(callData),
hinted: {
mortality,
asset,
tip,
}).pipe(filter(Boolean)),
)
},
})

return toHex(tx)
} finally {
Expand Down

0 comments on commit 8e5365a

Please sign in to comment.