Polkassembly Logo

Head 1
Head 2
Head 3
Head 4
Create Pencil IconCreate
TRACKS
ORIGINS
Report an issueNeed help with something?
Foot 1
Foot 2
Foot 3
Foot 4
OpenGov
View All Medium Spender
Requested:15.38K DOT
Executed

Reactive DOT: funding request for continuation of development

inMedium Spender
10 months ago
substrate
development
opensource
api
BeneficiaryBeneficiary:

(15.38K DOT)

**NOTE:** Polkassembly doesn't do code highlighting, so a much easier to read version can be found [here](https://hackmd.io/mf2A0eAXTAugALbWt3vajQ?view) instead. ## Introduction This proposal seeks continued funding for the development and refinement of the Reactive DOT library, building upon the progress made in proposal [#812](https://polkadot.polkassembly.io/referenda/812). Reactive DOT is a library designed to: - **Simplify development:** Provide a set of intuitive front-end functions and utilities to facilitate Substrate chain interactions, making development accessible for developers of all skill levels. - **Enhance developer experience:** Reduce boilerplate code and complexity involved in integrating DApps with Substrate chains, allowing developers to focus on building robust applications. - **Promote adoption:** Lower the entry barrier for developers through improved tooling and familiar patterns, encouraging the adoption of Polkadot. The initial phase successfully achieved all outlined goals and stretch objectives, significantly enhancing the development experience for Substrate DApps. ## Achievements ### Main goals The library was developed to work with [Polkadot-API](https://polkadot-api.github.io/polkadot-api-docs/) instead of [Polkadot.js](https://polkadot.js.org/docs/), achieving the following main goals: - **[Reading](https://reactivedot.dev/docs/getting-started/query) chain constants, API calls, and storages:** - Strong TypeScript IntelliSense and autocompletion. - Caching, persistent storage, and de-duplication of read states. - Async and error handling via React concurrency primitives (Suspense & Error Boundary). - **[Multichain support](https://reactivedot.dev/docs/getting-started/multichain).\*\* - **Documentation and walkthroughs:** - A [website](https://reactivedot.dev/) for documentation. - Dynamically generated [API definitions](https://reactivedot.dev/api). - **Community engagement:** - Announcement post and feedback gathering [here](https://forum.polkadot.network/t/reactive-dot-a-reactive-library-for-building-substrate-front-ends/8655). ### Stretch goals Leveraging the extremely well-built and lean core provided by [Polkadot-API](https://polkadot-api.github.io/polkadot-api-docs/), multiple stretch goals were achieved within the first development phase: - **[Transaction submission](https://reactivedot.dev/docs/getting-started/mutation):\*\* - Fully typed, utilising return type from PAPI typed API tx. - Overridable signer via [context](https://reactivedot.dev/docs/getting-started/mutation#1-via-context), [hook](https://reactivedot.dev/docs/getting-started/mutation#2-passing-signer-to-the-hook), and [callback](https://reactivedot.dev/docs/getting-started/mutation#2-passing-signer-to-the-final-submission) options. - **[Wallet management](https://reactivedot.dev/docs/getting-started/connect-wallets):\*\* - Support for all browser-injected wallets (Talisman, Nova, Polkadot.js, SubWallet). - Support WalletConnect via QR code scanning (Nova, SubWallet). - Developed an accompanying drop-in UI library (WIP) for wallet connection management: [dot-connect](https://github.com/tien/dot-connect). - Customisable UI solution out of the box. - Designed to work alongside Reactive DOT. - Wallets and accounts accessible via Reactive DOT hooks: [`useAccounts`](https://reactivedot.dev/api/react/function/useAccounts), [`useWallets`](https://reactivedot.dev/api/react/function/useWallets), and [`useConnectedWallets`](https://reactivedot.dev/api/react/function/useConnectedWallets). - Built using [Web Component](https://developer.mozilla.org/en-US/docs/Web/API/Web\_components) technology, making it framework-agnostic. - **[Account management](https://reactivedot.dev/docs/getting-started/connect-wallets#display-available-accounts):\*\* - Dynamic retrieval from all connected wallets. - Multichain support with automatic filtering based on the chain each account can submit transactions to. - Unique signer attached to each account, supporting multiple sources and allowing signer selection for transactions. - **[Utility](https://reactivedot.dev/docs/getting-started/number-utility) to handle planck units:** - Compatible with native number locale string conversion. - Uses monadic transformation for arithmetic, supporting both `BigInt` and `Number`. ### Summary of achievements Reactive DOT now provides all the essential building blocks for developing a Substrate DApp, with walkthroughs guiding developers on: - Connecting wallets. - Displaying connected accounts. - Reading states from the chain. - Submitting transactions. This is achieved with complete type safety, autocompletion from TypeScript, centralised async/error handling (set once and forget), and behind-the-scenes caching, de-duplication, and persistence management. #### Demonstration The following tutorial demonstrates how quickly a simple DApp can be set up. The DApp will: - Have a UI dialog for managing wallet connections from injected wallets (extensions) and WalletConnect wallets (mobile). - Display all accounts' free balances. - Include a button to submit a simple remark extrinsic. ##### Install dependencies and sync metadata ```sh yarn add @reactive-dot/react dot-connect polkadot-api npx papi add dot -n polkadot npx papi ``` ##### Configure chains and wallets ```ts import type { polkadot } from "@polkadot-api/descriptors"; declare module "@reactive-dot/core" { export interface Chains { polkadot: typeof polkadot; } } const config: Config = { chains: { polkadot: { descriptor: polkadot, provider: WebSocketProvider("wss://polkadot-rpc.publicnode.com"), }, }, wallets: [ new InjectedWalletAggregator(), new WalletConnect({ projectId: "WALLET_CONNECT_PROJECT_ID", providerOptions: { metadata: { name: "APP_NAME", description: "APP_DESCRIPTION", url: "APP_URL", icons: ["APP_ICON"], }, }, chainIds: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], }), ], }; export default config; ``` ##### Add top-level context providers ```tsx // Register dot-connect custom elements and configure supported wallets // this is the companion UI library for managing wallet connections registerDotConnect({ wallets: config.wallets, }); function App() { return ( (

Sorry, something went wrong!

)} > }> ); } ``` ##### Implement DApp logic ```tsx function FreeBalance(props: { address: string }) { const chainSpec = useChainSpecData(); const { data: { free }, } = useLazyLoadQuery((builder) => builder.readStorage("System", "Account", [props.address]), ); const freeBalance = new DenominatedNumber( free, chainSpec.properties.tokenDecimals, chainSpec.properties.tokenSymbol, ); return (

{props.address}: {freeBalance.toLocaleString()}

); } function Remark() { const accounts = useAccounts(); const [selectedAccountIndex, setSelectedAccountIndex] = useState(0); const selectedAccount = accounts.at(selectedAccountIndex); const [remarkState, remark] = useMutation( (tx) => tx.System.remark({ remark: Binary.fromText("Hello from reactive-dot!") }), { signer: selectedAccount.signer }, ); return (

setSelectedAccountIndex(Number(event.target.value)) } > {accounts.map((account, index) => ( {account.address} ))} remark()} disabled={remarkState === PENDING}> Hello{remarkState === PENDING ? "..." : ""}

); } function DApp() { const accounts = useAccounts(); return (

{/* Button for managing wallet connection from `dot-connect` */} {/* it will pop up a modal for you to connect and disconnect wallets */} {accounts.map((account, index) => ( ))} {accounts.length > 0 and }

); } ``` ##### Walkthrough recap Achieving the same outcome without this library would require substantially more code, while being much harder to maintain and reason with. ## Next steps This proposal requests continued funding for Reactive DOT development, focusing on: ### Refining existing features - More documentation. - Improvements and optimisations based on user feedback. - Increased testing and refactoring to maintain development velocity and smooth integration of future features. - Implementation of an automated versioning and publishing strategy. ### Adding new features #### React 19 support React 19 will introduce the [`use`](https://react.dev/reference/react/use) API, enabling components to conditionally consume promise results. Reactive DOT currently lazy loads queries (`fetch-on-render`) and will need to expose a promise-centric API to fully utilise React 19 features. #### Additional framework support The library's goal is to support building Substrate front-ends beyond just React. Based on the latest [State of JavaScript](https://2023.stateofjs.com/en-US) figures, the next frameworks for support, in order of importance, are: 1. Vue 2. Angular 3. Svelte Existing work has accounted for this by splitting primitives and functionalities into [`@reactive-dot/core`](https://reactivedot.dev/api/core) and [`@reactive-dot/react`](https://reactivedot.dev/api/react) to prepare for future integrations. #### Research on server-side rendering (SSR) Server-side rendering (SSR) is increasingly important, with applications like [Polkassembly](https://polkassembly.io/) and [SubSquare](https://www.subsquare.io/) both built using [Next.js](https://nextjs.org/). However, SSR traditionally presents challenges for Substrate DApps, which rely heavily on live WebSocket data. Potential strategies include: - Fully opt-in SSR: Faster initial load (`render-as-you-fetch`) but static values. - Client-side Substrate requests: Live data but potential request waterfalls due to the `fetch-on-render` pattern. ![image](https://hackmd.io/\_uploads/HyGl9wzIC.png) A hybrid approach is proposed, fetching initial values server-side to hydrate the client cache, which then updates with live chain data: ```tsx async function ServerComponent() { const preparedQuery = await prepareQuery((builder) => builder .readStorage("SomePallet", "SomeStorage") .readStorage("SomeOtherPallet", "SomeOtherStorage"), ); return ; } ``` ```tsx "use client"; function ClientComponent(props: { query: PreparedQuery }) { const resultThatIsInstantAndLive = usePreparedQuery(props.query); // ... } ``` Note: The above example illustrates the internal workings of the idea. Ideally, a logic split isn't explicitly required by developers. #### Community-driven features In addition to the concrete goals above, feedback is welcomed to determine the focus of future work. ## Summary #### Build upon - Maintenance. - Improvements of existing features pending feedback. #### Expand upon - React 19 support. - Support for additional frameworks, starting with Vue. - Research and development into hybrid SSR and client updates. - Features requested by the community. Fuelled by positive feedback and a clearly defined path forward, I am confident that we can not only match but surpass the frontend developer experience of other ecosystems (i.e. EVM), setting a new industry standard. ## Timeline and budget The initial [proposal](https://polkadot.polkassembly.io/referenda/812) requested funding for 2 months, which proved inadequate as a buffer due to the proposal process itself taking 1-2 months to conclude. During this time, I continued working without knowing the outcome. Based on that experience, I am now requesting a budget for 4 months, enabling me to fully dedicate my attention to research and development. - Period: August to November 2024. - Duration: 4 months / 87 workdays / 696 hours. - Requested amount: 15,378 DOT (based on Subscan's [EMA7](https://polkadot.subscan.io/tools/charts?type=price) of $6.11 USD per DOT). - Estimated rate: ~22.09 DOT or ~$134.96 USD per hour.

Comments

Proposal Passed

3

of 3

Summary

0%

Aye

AyeNay

0%

Nay

Aye (63)0.0 DOT

Support0.0 DOT

Nay (5)0.0 DOT

Voting Data

Approval%

Support%

Threshold0.00%

Threshold0.00%

Help Center

Report an Issue
Feedback
Terms and Conditions
Github

Our Services

Docs
Terms of Website
Privacy Policy

A House of Commons Initiative.

Polka Labs Private Limited 2025

All rights reserved.

Terms and ConditionsTerms of Website
Privacy Policy