From eec4e6deb0042b2ee007da2b807551187c1da8b9 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 30 Aug 2022 12:41:45 +0000 Subject: [PATCH 01/26] init dapps-extensions doc --- PSPs/drafts/psp-dapps-exentions.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 PSPs/drafts/psp-dapps-exentions.md diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md new file mode 100644 index 0000000..3b66331 --- /dev/null +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -0,0 +1,27 @@ +# DApp Extension API + +- **PSP Number:** [To be assigned (=number of the initial PR to the PSPs repo)] +- **Authors:** Fabio Lama +- **Status:** Draft +- **Created:** [2022-08-30] +- **Reference Implementation** https://github.com/polkadot-js/extension/tree/master/packages/extension-dapp + +## Summary + +... + +## Motivation + +... + +## Specification + +... + +## Tests + +... + +## Copyright + +This document is placed in the [public domain](https://creativecommons.org/publicdomain/zero/1.0/). From 80d87bab23507983bc31275becb038e6698b5171 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 30 Aug 2022 13:14:48 +0000 Subject: [PATCH 02/26] list top level function --- PSPs/drafts/psp-dapps-exentions.md | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 3b66331..8f0ba87 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -17,6 +17,70 @@ ## Specification ... +### Top Level Function + +export { packageInfo } from './packageInfo'; +export { unwrapBytes, wrapBytes } from './wrapBytes'; +declare let isWeb3Injected: boolean; +declare let web3EnablePromise: Promise | null; + + +#### web3Enable + +Declaration: + +```typescript +function web3Enable(originName: string, compatInits?: (() => Promise)[]): Promise +``` + +#### web3Accounts + +Declaration: + +```typescript +function web3Accounts({ accountType, extensions, ss58Format }?: Web3AccountsOptions): Promise +``` + +#### web3AccountsSubscribe + +Declaration: + +```typescript +function web3AccountsSubscribe(cb: (accounts: InjectedAccountWithMeta[]) => void | Promise, { extensions, ss58Format }?: Web3AccountsOptions): Promise +``` + +#### web3FromSource + +Declaration: + +```typescript +function web3FromSource(source: string): Promise +``` + +#### web3FromAddress + +Declaration: + +```typescript +function web3FromAddress(address: string): Promise +``` + +#### web3ListRpcProviders + +Declaration + +```typescript +function web3ListRpcProviders(source: string): Promise +``` + +#### web3UseRpcProvider + +Declaration + +```typescript +function web3UseRpcProvider(source: string, key: string): Promise +``` + ## Tests From a0fede7861312cc7225ebfe744df448b201687de Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 30 Aug 2022 14:37:29 +0000 Subject: [PATCH 03/26] add list of exposed types --- PSPs/drafts/psp-dapps-exentions.md | 119 +++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 5 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 8f0ba87..4f54dbb 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -17,13 +17,41 @@ ## Specification ... -### Top Level Function -export { packageInfo } from './packageInfo'; -export { unwrapBytes, wrapBytes } from './wrapBytes'; -declare let isWeb3Injected: boolean; -declare let web3EnablePromise: Promise | null; +### Top Level Variables + +#### isWeb3Injected +Declaration: + +```typescript +let isWeb3Injected: boolean; +``` + +#### web3EnablePromise + +Declaration: + +```typescript +let web3EnablePromise: Promise | null; +``` + +#### packageInfo + +Declaration: + +```typescript +const packageInfo: { + name: string; + path: string; + type: string; + version: string; +}; +``` + +### Top Level Function + +> TODO: Should `export { unwrapBytes, wrapBytes } from './wrapBytes';` be documented? #### web3Enable @@ -81,6 +109,87 @@ Declaration function web3UseRpcProvider(source: string, key: string): Promise ``` +### Types + +```typescript +export declare type InjectedExtension = InjectedExtensionInfo & Injected; + +export interface InjectedExtensionInfo { + name: string; + version: string; +} + +export interface Injected { + accounts: InjectedAccounts; + metadata?: InjectedMetadata; + provider?: InjectedProvider; + signer: InjectedSigner; +} +``` + +```typescript +export interface InjectedAccountWithMeta { + address: string; + meta: { + genesisHash?: string | null; + name?: string; + source: string; + }; + type?: KeypairType; +} +``` + +```typescript +export declare type ProviderList = Record; + +export interface ProviderMeta { + network: string; + node: 'full' | 'light'; + source: string; + transport: string; +} +``` + +```typescript +export interface InjectedProviderWithMeta { + provider: InjectedProvider; + meta: ProviderMeta; +} + +export interface InjectedProvider extends ProviderInterface { + listProviders: () => Promise; + startProvider: (key: string) => Promise; +} + +export interface ProviderInterface { + readonly hasSubscriptions: boolean; + readonly isConnected: boolean; + readonly stats?: ProviderStats; + clone(): ProviderInterface; + connect(): Promise; + disconnect(): Promise; + on(type: 'connected' | 'disconnected' | 'error', sub: (value?: any) => any): () => void; + send(method: string, params: unknown[], isCacheable?: boolean): Promise; + subscribe(type: string, method: string, params: unknown[], cb: (error: Error | null, result: any) => void): Promise; + unsubscribe(type: string, method: string, id: number | string): Promise; +} + +export interface ProviderStats { + active: { + requests: number; + subscriptions: number; + }; + total: { + bytesRecv: number; + bytesSent: number; + cached: number; + errors: number; + requests: number; + subscriptions: number; + timeout: number; + }; +} +``` ## Tests From ec39df4e2d99095fc859bf8abbeb36f4ff15a85e Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 05:54:39 +0000 Subject: [PATCH 04/26] deprecated unrelated types --- PSPs/drafts/psp-dapps-exentions.md | 154 ++--------------------------- 1 file changed, 9 insertions(+), 145 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 4f54dbb..afb9374 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -18,108 +18,15 @@ ... -### Top Level Variables +### Communication -#### isWeb3Injected - -Declaration: - -```typescript -let isWeb3Injected: boolean; -``` - -#### web3EnablePromise - -Declaration: - -```typescript -let web3EnablePromise: Promise | null; -``` - -#### packageInfo - -Declaration: - -```typescript -const packageInfo: { - name: string; - path: string; - type: string; - version: string; -}; -``` - -### Top Level Function - -> TODO: Should `export { unwrapBytes, wrapBytes } from './wrapBytes';` be documented? - -#### web3Enable - -Declaration: - -```typescript -function web3Enable(originName: string, compatInits?: (() => Promise)[]): Promise -``` - -#### web3Accounts - -Declaration: - -```typescript -function web3Accounts({ accountType, extensions, ss58Format }?: Web3AccountsOptions): Promise -``` - -#### web3AccountsSubscribe - -Declaration: - -```typescript -function web3AccountsSubscribe(cb: (accounts: InjectedAccountWithMeta[]) => void | Promise, { extensions, ss58Format }?: Web3AccountsOptions): Promise -``` - -#### web3FromSource - -Declaration: - -```typescript -function web3FromSource(source: string): Promise -``` - -#### web3FromAddress - -Declaration: - -```typescript -function web3FromAddress(address: string): Promise -``` - -#### web3ListRpcProviders - -Declaration - -```typescript -function web3ListRpcProviders(source: string): Promise -``` - -#### web3UseRpcProvider - -Declaration - -```typescript -function web3UseRpcProvider(source: string, key: string): Promise -``` ### Types ```typescript -export declare type InjectedExtension = InjectedExtensionInfo & Injected; - -export interface InjectedExtensionInfo { +export interface InjectedExtension { name: string; version: string; -} - -export interface Injected { accounts: InjectedAccounts; metadata?: InjectedMetadata; provider?: InjectedProvider; @@ -128,69 +35,26 @@ export interface Injected { ``` ```typescript -export interface InjectedAccountWithMeta { - address: string; - meta: { - genesisHash?: string | null; - name?: string; - source: string; - }; - type?: KeypairType; +export interface InjectedAccounts { } ``` ```typescript -export declare type ProviderList = Record; - -export interface ProviderMeta { - network: string; - node: 'full' | 'light'; - source: string; - transport: string; +export interface InjectedMetadata { } ``` ```typescript -export interface InjectedProviderWithMeta { - provider: InjectedProvider; - meta: ProviderMeta; -} - -export interface InjectedProvider extends ProviderInterface { - listProviders: () => Promise; - startProvider: (key: string) => Promise; -} - -export interface ProviderInterface { - readonly hasSubscriptions: boolean; - readonly isConnected: boolean; - readonly stats?: ProviderStats; - clone(): ProviderInterface; - connect(): Promise; - disconnect(): Promise; - on(type: 'connected' | 'disconnected' | 'error', sub: (value?: any) => any): () => void; - send(method: string, params: unknown[], isCacheable?: boolean): Promise; - subscribe(type: string, method: string, params: unknown[], cb: (error: Error | null, result: any) => void): Promise; - unsubscribe(type: string, method: string, id: number | string): Promise; +export interface InjectedProvider { } +``` -export interface ProviderStats { - active: { - requests: number; - subscriptions: number; - }; - total: { - bytesRecv: number; - bytesSent: number; - cached: number; - errors: number; - requests: number; - subscriptions: number; - timeout: number; - }; +```typescript +export interface InjectedSigner { } ``` + ## Tests ... From 74e4fbf12b682f25802362d3bab40874308515e3 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 06:04:19 +0000 Subject: [PATCH 05/26] add note on communication --- PSPs/drafts/psp-dapps-exentions.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index afb9374..f7d4452 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -20,6 +20,18 @@ ### Communication +Extensions inject a `injectedWeb3` field with a specific structure into the +`window` entry in the DOM. Dapps can then interspect that field, search for the +desired extension and then interact with the extension by calling the defined +functions. + +`window.injectedWeb` is defined as TODO + +The datastucture contains (meta)data about the extension and offers some +functions such as the ability to retrieve accounts and sign messages. The +extension itself does not create any sort of transactions and does not submit +anything to any network, the dapps is responsible for that. Ultimately, the +extension primarily manages accounts and creates signatures of messages. ### Types From 1f4e670b8cabe1db461fdd87506c675ebda1f64d Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 06:15:45 +0000 Subject: [PATCH 06/26] expand interfaces --- PSPs/drafts/psp-dapps-exentions.md | 31 ++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index f7d4452..11c9769 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -20,8 +20,8 @@ ### Communication -Extensions inject a `injectedWeb3` field with a specific structure into the -`window` entry in the DOM. Dapps can then interspect that field, search for the +Extensions inject a specific structure into the `injectedWeb3` field in the main +`window` object of the DOM. Dapps can then interspect that field, search for the desired extension and then interact with the extension by calling the defined functions. @@ -48,21 +48,44 @@ export interface InjectedExtension { ```typescript export interface InjectedAccounts { + get: (anyType?: boolean) => Promise; + subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise) => Unsubcall; } ``` ```typescript export interface InjectedMetadata { + get: () => Promise; + provide: (definition: MetadataDef) => Promise; } ``` ```typescript -export interface InjectedProvider { +export interface InjectedProvider extends ProviderInterface { + listProviders: () => Promise; + startProvider: (key: string) => Promise; +} + +export interface ProviderInterface { + readonly hasSubscriptions: boolean; + readonly isConnected: boolean; + readonly stats?: ProviderStats; + + clone (): ProviderInterface; + connect (): Promise; + disconnect (): Promise; + on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void; + send (method: string, params: unknown[], isCacheable?: boolean): Promise; + subscribe (type: string, method: string, params: unknown[], cb: ProviderInterfaceCallback): Promise; + unsubscribe (type: string, method: string, id: number | string): Promise; } ``` ```typescript -export interface InjectedSigner { +export interface Signer { + signPayload?: (payload: SignerPayloadJSON) => Promise; + signRaw?: (raw: SignerPayloadRaw) => Promise; + update?: (id: number, status: H256 | ISubmittableResult) => void; } ``` From 60a7f9465457fe5ba7e6117c70e754e8fb6e5013 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 06:27:55 +0000 Subject: [PATCH 07/26] expand types for ProviderInterface --- PSPs/drafts/psp-dapps-exentions.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 11c9769..01fcfeb 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -74,11 +74,27 @@ export interface ProviderInterface { clone (): ProviderInterface; connect (): Promise; disconnect (): Promise; - on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void; + on (type: 'connected' | 'disconnected' | 'error', sub: (value?: any) => any): () => void; send (method: string, params: unknown[], isCacheable?: boolean): Promise; - subscribe (type: string, method: string, params: unknown[], cb: ProviderInterfaceCallback): Promise; + subscribe (type: string, method: string, params: unknown[], cb: (error: Error | null, result: any) => void): Promise; unsubscribe (type: string, method: string, id: number | string): Promise; } + +export interface ProviderStats { + active: { + requests: number; + subscriptions: number; + }; + total: { + bytesRecv: number; + bytesSent: number; + cached: number; + errors: number; + requests: number; + subscriptions: number; + timeout: number; + }; +} ``` ```typescript @@ -89,7 +105,6 @@ export interface Signer { } ``` - ## Tests ... From ede0be39596515b956c2ad872ccd94183a9f70eb Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 06:37:35 +0000 Subject: [PATCH 08/26] expand types --- PSPs/drafts/psp-dapps-exentions.md | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 01fcfeb..776a4c8 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -35,6 +35,8 @@ extension primarily manages accounts and creates signatures of messages. ### Types +#### Extension + ```typescript export interface InjectedExtension { name: string; @@ -46,26 +48,60 @@ export interface InjectedExtension { } ``` +#### Accounts + ```typescript export interface InjectedAccounts { get: (anyType?: boolean) => Promise; subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise) => Unsubcall; } + +export interface InjectedAccount { + address: string; + genesisHash?: string | null; + name?: string; + type?: KeypairType; +} + +export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; ``` +#### Metadata + ```typescript export interface InjectedMetadata { get: () => Promise; provide: (definition: MetadataDef) => Promise; } + +export interface InjectedMetadataKnown { + genesisHash: string; + specVersion: number; +} ``` +#### RPC Provider + ```typescript export interface InjectedProvider extends ProviderInterface { listProviders: () => Promise; startProvider: (key: string) => Promise; } +export type ProviderList = Record + +// Metadata about a provider +export interface ProviderMeta { + // Network of the provider + network: string; + // Light or full node + node: 'full' | 'light'; + // The extension source + source: string; + // Provider transport: 'WsProvider' etc. + transport: string; +} + export interface ProviderInterface { readonly hasSubscriptions: boolean; readonly isConnected: boolean; @@ -95,8 +131,54 @@ export interface ProviderStats { timeout: number; }; } + +export interface SignerPayloadJSON { + address: string; + blockHash: string; + blockNumber: string; + era: string; + genesisHash: string; + method: string; + nonce: string; + specVersion: string; + tip: string; + transactionVersion: string; + signedExtensions: string[]; + version: number; +} + +export interface SignerPayloadRaw extends SignerPayloadRawBase { + address: string; + type: 'bytes' | 'payload'; +} + +export interface SignerResult { + id: number; + signature: HexString; +} + +export interface ISubmittableResult { + readonly dispatchError?: DispatchError; + readonly dispatchInfo?: DispatchInfo; + readonly events: EventRecord[]; + readonly internalError?: Error; + readonly status: ExtrinsicStatus; + readonly isCompleted: boolean; + readonly isError: boolean; + readonly isFinalized: boolean; + readonly isInBlock: boolean; + readonly isWarning: boolean; + readonly txHash: Hash; + readonly txIndex?: number; + + filterRecords (section: string, method: string): EventRecord[]; + findRecord (section: string, method: string): EventRecord | undefined; + toHuman (isExtended?: boolean): AnyJson; +} ``` +#### Signer + ```typescript export interface Signer { signPayload?: (payload: SignerPayloadJSON) => Promise; From 28feff06a24098d52188f8107f1b2c2aea56da2e Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 08:03:15 +0000 Subject: [PATCH 09/26] describe fields of Extension and Accounts --- PSPs/drafts/psp-dapps-exentions.md | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 776a4c8..01acbe1 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -25,7 +25,17 @@ Extensions inject a specific structure into the `injectedWeb3` field in the main desired extension and then interact with the extension by calling the defined functions. -`window.injectedWeb` is defined as TODO +`window.injectedWeb` is of type `Record` + +where + +```type +export interface InjectedWindowProvider { + enable: (origin: string) => Promise; + version: string; +} +``` + The datastucture contains (meta)data about the extension and offers some functions such as the ability to retrieve accounts and sign messages. The @@ -37,6 +47,8 @@ extension primarily manages accounts and creates signatures of messages. #### Extension +This structure is the primary way to interact with the Extension. + ```typescript export interface InjectedExtension { name: string; @@ -48,6 +60,14 @@ export interface InjectedExtension { } ``` +* `name`: the name of the extension, e.g. `"polkadot-js"`. +* `version`: the version of the extension, e.g. `"0.44.1"`. +* `accounts`: an [Accounts](#accounts) structure to retrieve accounts. +* `metadata`: a [Metadata](#metadata) structure containing metadata (optional). +* `provider`: a [Provider](#rpc-provider) structure to allow the Dapp to submit + RPC request to the network (optional). +* `signer`: a [Signer](#signer) structure to sign messages with a given account. + #### Accounts ```typescript @@ -56,6 +76,17 @@ export interface InjectedAccounts { subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise) => Unsubcall; } +export type Unsubcall = () => void; +``` + +* `get`: returns a list of accounts. +* `subscribe`: subscribers to the list of accounts, useful for detecting account + changes. The returns value of type `Unsubcall` will stop the subscription if + called. + +The account structure is defined as follows: + +```typescript export interface InjectedAccount { address: string; genesisHash?: string | null; @@ -66,6 +97,11 @@ export interface InjectedAccount { export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; ``` +* `address`: the address of the account. +* `genesisHash`: the genesis hash of the chain (optional). +* `name`: the custom name of the account (optional). +* `type`: the cryptographic type of the account (optional). + #### Metadata ```typescript From 02da92fcf3c626a1d60b813d3c3f9928eab8e674 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 10:39:47 +0000 Subject: [PATCH 10/26] expand docs of type fields --- PSPs/drafts/psp-dapps-exentions.md | 252 ++++++++++++++++++----------- 1 file changed, 160 insertions(+), 92 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 01acbe1..43ac120 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -51,93 +51,196 @@ This structure is the primary way to interact with the Extension. ```typescript export interface InjectedExtension { + // The name of the extension, e.g. `"polkadot-js"` name: string; + // The version of the extension, e.g. `"0.44.1"` version: string; + // A structure to retrieve accounts. accounts: InjectedAccounts; + // A structure containing metadata (optional) metadata?: InjectedMetadata; + // A structure to allow the Dapp to submit + // RPC request to the network (optional). provider?: InjectedProvider; + // A structure to sign messages with a given account. signer: InjectedSigner; } ``` -* `name`: the name of the extension, e.g. `"polkadot-js"`. -* `version`: the version of the extension, e.g. `"0.44.1"`. -* `accounts`: an [Accounts](#accounts) structure to retrieve accounts. -* `metadata`: a [Metadata](#metadata) structure containing metadata (optional). -* `provider`: a [Provider](#rpc-provider) structure to allow the Dapp to submit - RPC request to the network (optional). -* `signer`: a [Signer](#signer) structure to sign messages with a given account. - #### Accounts +The accounts structure allows the Dapps to retrieve a list of accounts, +including listening for account changes. The extension is responsible for +handling permissions accordingly. + ```typescript export interface InjectedAccounts { - get: (anyType?: boolean) => Promise; - subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise) => Unsubcall; + // Returns a list of accounts. + get: (anyType?: boolean) => Promise; + // Subscribers to the list of accounts, useful for + // detecting account changes. + subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise) => Unsubcall; } +// Stops the subscription if called. export type Unsubcall = () => void; -``` - -* `get`: returns a list of accounts. -* `subscribe`: subscribers to the list of accounts, useful for detecting account - changes. The returns value of type `Unsubcall` will stop the subscription if - called. - -The account structure is defined as follows: -```typescript export interface InjectedAccount { +// The address of the account. address: string; + // The genesis hash of the blockchain (optional). genesisHash?: string | null; + // The custom name of the account (optional). name?: string; + // The cryptographic type of the account (optional). type?: KeypairType; } export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; ``` -* `address`: the address of the account. -* `genesisHash`: the genesis hash of the chain (optional). -* `name`: the custom name of the account (optional). -* `type`: the cryptographic type of the account (optional). - #### Metadata +The metadata stucture allows Dapps to retrieve information about known +blockchain, but also allows to register new blockchains with the extension. The +extension is responsible for handling permissions accordingly. + ```typescript export interface InjectedMetadata { - get: () => Promise; - provide: (definition: MetadataDef) => Promise; + // Retuns a list of know parameters about the blockchain. + get: () => Promise; + // Provide the extension with information about a blockchain. + provide: (definition: MetadataDef) => Promise; } export interface InjectedMetadataKnown { - genesisHash: string; - specVersion: number; + // The genesis hash of the blockchain. + genesisHash: string; + // The chain spec version of the blockchain + // (https://docs.substrate.io/build/chain-spec/). + specVersion: number; +} + +export interface MetadataDef { + // The name of the blockchain. + chain: string; + // The genesis hash of the blockchain. + genesisHash: string; + // HEX-encoded icon of the blockchain. + icon: string; + // The SS58-encoding prefix of the blockchain + // (https://docs.substrate.io/fundamentals/accounts-addresses-keys/). + ss58Format: number; + // The chain type. + chainType?: 'substrate' | 'ethereum' + // A chosen color for the blockchain (optional). + color?: string; + // The chain specification version of the blockchain + // (https://docs.substrate.io/build/chain-spec/). + specVersion: number; + // The number of decimals the token supports. + tokenDecimals: number; + // The name of the token. + tokenSymbol: string; + // TODO: Unclear + types: Record | string>; + // TODO: Unclear + metaCalls?: string; + // TODO: Unclear + userExtensions?: Record; +} + +// TODO: Unclear +export type ExtInfo = { + extrinsic: ExtTypes; + payload: ExtTypes; } ``` -#### RPC Provider +#### Signer + +The signer datastructure allows Dapps to sign messages with a given account. The +extension is responsible for handling permissions accordingly. ```typescript -export interface InjectedProvider extends ProviderInterface { - listProviders: () => Promise; - startProvider: (key: string) => Promise; +export interface Signer { + // Signs the given JSON payload and returns the result. + signPayload?: (payload: SignerPayloadJSON) => Promise; + // Signs the given raw payload and returns the result. + signRaw?: (raw: SignerPayloadRaw) => Promise; + // TODO: Unclear + update?: (id: number, status: H256 | ISubmittableResult) => void; } -export type ProviderList = Record +export interface SignerPayloadJSON { + // The address of the account that should sign the message. + address: string; + // The HEX-encoded block hash. + blockHash: string; + // The block number. + blockNumber: string; + // The era of the blockchain. + era: string; + // The gensis hash + genesisHash: string; + // TODO: Unclear + method: string; + // The lastest nonce for the given account. + nonce: string; + // The chain spec version of the blockchain + // (https://docs.substrate.io/build/chain-spec/). + specVersion: string; + // The tip for the block author. + // TODO: As decimals? + tip: string; + // The transaction version. + transactionVersion: string; + // TODO: Unclear (the extra data to be signed for the transaction?) + signedExtensions: string[]; + // TODO: Unclear + version: number; +} -// Metadata about a provider -export interface ProviderMeta { - // Network of the provider - network: string; - // Light or full node - node: 'full' | 'light'; - // The extension source - source: string; - // Provider transport: 'WsProvider' etc. - transport: string; +export interface SignerPayloadRaw { + address: string; + type: 'bytes' | 'payload'; +} + +export interface SignerResult { + id: number; + // The HEX-encoded signature. + signature: string; } +// TODO: Clear +export interface ISubmittableResult { + readonly dispatchError?: DispatchError; + readonly dispatchInfo?: DispatchInfo; + readonly events: EventRecord[]; + readonly internalError?: Error; + readonly status: ExtrinsicStatus; + readonly isCompleted: boolean; + readonly isError: boolean; + readonly isFinalized: boolean; + readonly isInBlock: boolean; + readonly isWarning: boolean; + readonly txHash: Hash; + readonly txIndex?: number; + + filterRecords (section: string, method: string): EventRecord[]; + findRecord (section: string, method: string): EventRecord | undefined; + toHuman (isExtended?: boolean): AnyJson; +} +``` + +#### RPC Provider + +The RPC provider structure allows Dapps to communicate with an RPC server, such +as submitting transactions. The extension is responsible for initiating and +maintaining the connection to the RPC server, including handling all requests +and forwarding responses to the Dapp. + +```typescript export interface ProviderInterface { readonly hasSubscriptions: boolean; readonly isConnected: boolean; @@ -168,58 +271,23 @@ export interface ProviderStats { }; } -export interface SignerPayloadJSON { - address: string; - blockHash: string; - blockNumber: string; - era: string; - genesisHash: string; - method: string; - nonce: string; - specVersion: string; - tip: string; - transactionVersion: string; - signedExtensions: string[]; - version: number; -} - -export interface SignerPayloadRaw extends SignerPayloadRawBase { - address: string; - type: 'bytes' | 'payload'; -} - -export interface SignerResult { - id: number; - signature: HexString; -} - -export interface ISubmittableResult { - readonly dispatchError?: DispatchError; - readonly dispatchInfo?: DispatchInfo; - readonly events: EventRecord[]; - readonly internalError?: Error; - readonly status: ExtrinsicStatus; - readonly isCompleted: boolean; - readonly isError: boolean; - readonly isFinalized: boolean; - readonly isInBlock: boolean; - readonly isWarning: boolean; - readonly txHash: Hash; - readonly txIndex?: number; - - filterRecords (section: string, method: string): EventRecord[]; - findRecord (section: string, method: string): EventRecord | undefined; - toHuman (isExtended?: boolean): AnyJson; +export interface InjectedProvider extends ProviderInterface { + listProviders: () => Promise; + startProvider: (key: string) => Promise; } -``` -#### Signer +export type ProviderList = Record -```typescript -export interface Signer { - signPayload?: (payload: SignerPayloadJSON) => Promise; - signRaw?: (raw: SignerPayloadRaw) => Promise; - update?: (id: number, status: H256 | ISubmittableResult) => void; +// Metadata about a provider +export interface ProviderMeta { + // Network of the provider + network: string; + // Light or full node + node: 'full' | 'light'; + // The extension source + source: string; + // Provider transport: 'WsProvider' etc. + transport: string; } ``` From 3dd43a3e5c5b9d15158fdc91579ac712bf93a8c0 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 10:58:40 +0000 Subject: [PATCH 11/26] update communication section --- PSPs/drafts/psp-dapps-exentions.md | 34 ++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 43ac120..0b27b2c 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -16,32 +16,48 @@ ## Specification -... +NOTE: All types are expresses in Typescript and are therefore also accessible in +javascript. ### Communication Extensions inject a specific structure into the `injectedWeb3` field in the main `window` object of the DOM. Dapps can then interspect that field, search for the desired extension and then interact with the extension by calling the defined -functions. +functions. Implementers of extension can decide for themselves on how the +functions are implemented, as long as the standardized structures are defined +correctly. -`window.injectedWeb` is of type `Record` +The `window.injectedWeb` is of type: -where +```typescript +Record +``` -```type +The key identifies the name of the extension (e.g. `polkadot-js`), which the +Dapp can use to identify the correct extension. Its corresponding value is a +datastructure of the following format: + +```typescript export interface InjectedWindowProvider { + // Start communication process. enable: (origin: string) => Promise; + // Version of the extension. version: string; } ``` +To start the communication with the extension, the Dapp calls the `enable` +function, passing the `origin` parameter indicating the arbitrary name of the +Dapp, where the resulting action is then executed by the extension. Normally, +this is where the extension asks the user for permission on whehter the Dapp +should be allowed to access the extension. -The datastucture contains (meta)data about the extension and offers some +The returned value contains (meta)data about the extension and offers some functions such as the ability to retrieve accounts and sign messages. The -extension itself does not create any sort of transactions and does not submit -anything to any network, the dapps is responsible for that. Ultimately, the -extension primarily manages accounts and creates signatures of messages. +extension itself does not create any sort of transactions, the dapps is +responsible for that. Ultimately, the extension primarily manages accounts, +creates signatures of messages and communicates with RPC servers. ### Types From 33a11608601995bd01a9d30426e9ea62c5d56710 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:10:39 +0000 Subject: [PATCH 12/26] rewrite parts of the communcation section --- PSPs/drafts/psp-dapps-exentions.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 0b27b2c..1814099 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -21,12 +21,12 @@ javascript. ### Communication -Extensions inject a specific structure into the `injectedWeb3` field in the main -`window` object of the DOM. Dapps can then interspect that field, search for the -desired extension and then interact with the extension by calling the defined -functions. Implementers of extension can decide for themselves on how the -functions are implemented, as long as the standardized structures are defined -correctly. +Extensions inject an `injectedWeb3` attribute with a specific datastructure in +the [`window` object](https://developer.mozilla.org/en-US/docs/Web/API/Window). +Dapps can then interspect that attribute, search for the desired extension and +then interact with the extension by calling the defined functions. Implementers +of extension can decide for themselves on how the functions are implemented, as +long as the standardized structures are defined correctly. The `window.injectedWeb` is of type: @@ -49,15 +49,14 @@ export interface InjectedWindowProvider { To start the communication with the extension, the Dapp calls the `enable` function, passing the `origin` parameter indicating the arbitrary name of the -Dapp, where the resulting action is then executed by the extension. Normally, -this is where the extension asks the user for permission on whehter the Dapp -should be allowed to access the extension. +Dapp, where an action is then executed by the extension. Normally, this is where +the extension asks the user for permission on whehter the Dapp should be allowed +to access the extension. The returned value contains (meta)data about the extension and offers some -functions such as the ability to retrieve accounts and sign messages. The -extension itself does not create any sort of transactions, the dapps is -responsible for that. Ultimately, the extension primarily manages accounts, -creates signatures of messages and communicates with RPC servers. +functions such as the ability to retrieve accounts, sign messages and interact +with RPC servers. The extension itself does not create any sort of transactions +itself, the dapps is responsible for that. ### Types From 267a20472695096d3feba70c09bcf81d6fcbe0ed Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:17:57 +0000 Subject: [PATCH 13/26] add Summary and Motivation section --- PSPs/drafts/psp-dapps-exentions.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 1814099..6389ba1 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -8,16 +8,22 @@ ## Summary -... +This PSP describes how browser applications ("apps") and Extensions can interact +with each other. Essentially, Dapps should be able to interact with any +extension that implements this standard and vice-versa. ## Motivation -... +This standard unifies the Polkadot and Kusama network by allowing apps to +interact with commonly used extensions, such as wallets, and makes it easy to +develop new extensions that are compatible with existing apps. ## Specification -NOTE: All types are expresses in Typescript and are therefore also accessible in -javascript. +This specification only describes the interface for how apps and extensions +should interact with each other. Everything else is implementation specific. +Addtionally, all types are expresses in Typescript and are therefore also +accessible in javascript. ### Communication From d42b7f0e23178b07c070c8600bf8f9bf098a4f88 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:22:23 +0000 Subject: [PATCH 14/26] update type name --- PSPs/drafts/psp-dapps-exentions.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 6389ba1..eb73128 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -8,15 +8,15 @@ ## Summary -This PSP describes how browser applications ("apps") and Extensions can interact -with each other. Essentially, Dapps should be able to interact with any -extension that implements this standard and vice-versa. +This PSP describes how browser applications ("apps") and extensions, such as +wallets, can interact with each other. Essentially, Dapps should be able to +interact with any extension that implements this standard and vice-versa. ## Motivation This standard unifies the Polkadot and Kusama network by allowing apps to -interact with commonly used extensions, such as wallets, and makes it easy to -develop new extensions that are compatible with existing apps. +interact with commonly used extensions and makes it easy to develop new +extensions that are compatible with existing apps. ## Specification @@ -47,7 +47,7 @@ datastructure of the following format: ```typescript export interface InjectedWindowProvider { // Start communication process. - enable: (origin: string) => Promise; + enable: (origin: string) => Promise; // Version of the extension. version: string; } @@ -312,10 +312,6 @@ export interface ProviderMeta { } ``` -## Tests - -... - ## Copyright This document is placed in the [public domain](https://creativecommons.org/publicdomain/zero/1.0/). From 27874de61952efd90dceecb5eb54bb12fa8dee45 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:40:13 +0000 Subject: [PATCH 15/26] rename dapp to app --- PSPs/drafts/psp-dapps-exentions.md | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index eb73128..88cdd54 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -1,15 +1,15 @@ -# DApp Extension API +# app Extension API - **PSP Number:** [To be assigned (=number of the initial PR to the PSPs repo)] - **Authors:** Fabio Lama - **Status:** Draft - **Created:** [2022-08-30] -- **Reference Implementation** https://github.com/polkadot-js/extension/tree/master/packages/extension-dapp +- **Reference Implementation** https://github.com/polkadot-js/extension/tree/master/packages/extension-app ## Summary This PSP describes how browser applications ("apps") and extensions, such as -wallets, can interact with each other. Essentially, Dapps should be able to +wallets, can interact with each other. Essentially, apps should be able to interact with any extension that implements this standard and vice-versa. ## Motivation @@ -29,7 +29,7 @@ accessible in javascript. Extensions inject an `injectedWeb3` attribute with a specific datastructure in the [`window` object](https://developer.mozilla.org/en-US/docs/Web/API/Window). -Dapps can then interspect that attribute, search for the desired extension and +apps can then interspect that attribute, search for the desired extension and then interact with the extension by calling the defined functions. Implementers of extension can decide for themselves on how the functions are implemented, as long as the standardized structures are defined correctly. @@ -41,7 +41,7 @@ Record ``` The key identifies the name of the extension (e.g. `polkadot-js`), which the -Dapp can use to identify the correct extension. Its corresponding value is a +app can use to identify the correct extension. Its corresponding value is a datastructure of the following format: ```typescript @@ -53,16 +53,16 @@ export interface InjectedWindowProvider { } ``` -To start the communication with the extension, the Dapp calls the `enable` +To start the communication with the extension, the app calls the `enable` function, passing the `origin` parameter indicating the arbitrary name of the -Dapp, where an action is then executed by the extension. Normally, this is where -the extension asks the user for permission on whehter the Dapp should be allowed -to access the extension. +app, where an action is then executed by the extension. Normally, this is where +the extension asks the user for permission on whehter the app should be allowed +to access the extension or throws an exception if not. The returned value contains (meta)data about the extension and offers some functions such as the ability to retrieve accounts, sign messages and interact with RPC servers. The extension itself does not create any sort of transactions -itself, the dapps is responsible for that. +itself, the apps is responsible for that. ### Types @@ -80,7 +80,7 @@ export interface InjectedExtension { accounts: InjectedAccounts; // A structure containing metadata (optional) metadata?: InjectedMetadata; - // A structure to allow the Dapp to submit + // A structure to allow the app to submit // RPC request to the network (optional). provider?: InjectedProvider; // A structure to sign messages with a given account. @@ -90,7 +90,7 @@ export interface InjectedExtension { #### Accounts -The accounts structure allows the Dapps to retrieve a list of accounts, +The accounts structure allows the apps to retrieve a list of accounts, including listening for account changes. The extension is responsible for handling permissions accordingly. @@ -122,7 +122,7 @@ export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; #### Metadata -The metadata stucture allows Dapps to retrieve information about known +The metadata stucture allows apps to retrieve information about known blockchain, but also allows to register new blockchains with the extension. The extension is responsible for handling permissions accordingly. @@ -180,7 +180,7 @@ export type ExtInfo = { #### Signer -The signer datastructure allows Dapps to sign messages with a given account. The +The signer datastructure allows apps to sign messages with a given account. The extension is responsible for handling permissions accordingly. ```typescript @@ -256,10 +256,10 @@ export interface ISubmittableResult { #### RPC Provider -The RPC provider structure allows Dapps to communicate with an RPC server, such +The RPC provider structure allows apps to communicate with an RPC server, such as submitting transactions. The extension is responsible for initiating and maintaining the connection to the RPC server, including handling all requests -and forwarding responses to the Dapp. +and forwarding responses to the app. ```typescript export interface ProviderInterface { From a713be14d90bf7ccad229ed96bf4644757ad0b21 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:41:47 +0000 Subject: [PATCH 16/26] update title --- PSPs/drafts/psp-dapps-exentions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-dapps-exentions.md index 88cdd54..88a6439 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-dapps-exentions.md @@ -1,4 +1,4 @@ -# app Extension API +# App Extension API - **PSP Number:** [To be assigned (=number of the initial PR to the PSPs repo)] - **Authors:** Fabio Lama @@ -68,7 +68,7 @@ itself, the apps is responsible for that. #### Extension -This structure is the primary way to interact with the Extension. +This structure is the primary way to interact with the extension. ```typescript export interface InjectedExtension { From 102066ca7d052b595625a3a8138a9e46ccebe177 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:52:48 +0000 Subject: [PATCH 17/26] assigned PSP number --- PSPs/drafts/{psp-dapps-exentions.md => psp-52.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename PSPs/drafts/{psp-dapps-exentions.md => psp-52.md} (99%) diff --git a/PSPs/drafts/psp-dapps-exentions.md b/PSPs/drafts/psp-52.md similarity index 99% rename from PSPs/drafts/psp-dapps-exentions.md rename to PSPs/drafts/psp-52.md index 88a6439..4949a09 100644 --- a/PSPs/drafts/psp-dapps-exentions.md +++ b/PSPs/drafts/psp-52.md @@ -1,6 +1,6 @@ # App Extension API -- **PSP Number:** [To be assigned (=number of the initial PR to the PSPs repo)] +- **PSP Number:** 52 - **Authors:** Fabio Lama - **Status:** Draft - **Created:** [2022-08-30] From 67d95878b1f1af97cf9ab327e8e94646ef6955a7 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Wed, 7 Sep 2022 07:27:55 +0000 Subject: [PATCH 18/26] update sentencing --- PSPs/drafts/psp-52.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 4949a09..c0959c8 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -8,28 +8,29 @@ ## Summary -This PSP describes how browser applications ("apps") and extensions, such as -wallets, can interact with each other. Essentially, apps should be able to -interact with any extension that implements this standard and vice-versa. +This PSP describes how web applications ("apps") and browser extensions, such as +wallets like the [polkadot{.js} extensions](https://polkadot.js.org/extension/), +can interact with each other. Essentially, apps should be able to interact with +any extension that implements this standard and vice-versa. ## Motivation This standard unifies the Polkadot and Kusama network by allowing apps to -interact with commonly used extensions and makes it easy to develop new +interact with commonly used extensions and makes it easier to develop new extensions that are compatible with existing apps. ## Specification This specification only describes the interface for how apps and extensions should interact with each other. Everything else is implementation specific. -Addtionally, all types are expresses in Typescript and are therefore also -accessible in javascript. +Addtionally, all types are expressed in Typescript and are therefore also +accessible with javascript. ### Communication -Extensions inject an `injectedWeb3` attribute with a specific datastructure in +Extensions inject an `injectedWeb3` attribute with a specific datastructure into the [`window` object](https://developer.mozilla.org/en-US/docs/Web/API/Window). -apps can then interspect that attribute, search for the desired extension and +Apps can then interspect that attribute, search for the desired extension and then interact with the extension by calling the defined functions. Implementers of extension can decide for themselves on how the functions are implemented, as long as the standardized structures are defined correctly. From 776bd6b09d2263e7574533545d2ecd252ae01e14 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Wed, 7 Sep 2022 07:28:22 +0000 Subject: [PATCH 19/26] update date format --- PSPs/drafts/psp-52.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index c0959c8..72ba2fc 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -3,7 +3,7 @@ - **PSP Number:** 52 - **Authors:** Fabio Lama - **Status:** Draft -- **Created:** [2022-08-30] +- **Created:** 2022-08-30 - **Reference Implementation** https://github.com/polkadot-js/extension/tree/master/packages/extension-app ## Summary From 680cf4a9c6d8aa9ef4372bba8083295e49afdca7 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Wed, 7 Sep 2022 07:32:03 +0000 Subject: [PATCH 20/26] fix window.injectedWeb3 typo --- PSPs/drafts/psp-52.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 72ba2fc..0e3eeac 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -35,7 +35,7 @@ then interact with the extension by calling the defined functions. Implementers of extension can decide for themselves on how the functions are implemented, as long as the standardized structures are defined correctly. -The `window.injectedWeb` is of type: +The `window.injectedWeb3` is of type: ```typescript Record From 005b1fd3b173b325c2265a04228fffcbdd9b8b86 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:04:02 +0000 Subject: [PATCH 21/26] remove TODO of unclear fields --- PSPs/drafts/psp-52.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 0e3eeac..77ded8d 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -164,15 +164,11 @@ export interface MetadataDef { tokenDecimals: number; // The name of the token. tokenSymbol: string; - // TODO: Unclear types: Record | string>; - // TODO: Unclear metaCalls?: string; - // TODO: Unclear userExtensions?: Record; } -// TODO: Unclear export type ExtInfo = { extrinsic: ExtTypes; payload: ExtTypes; @@ -190,7 +186,6 @@ export interface Signer { signPayload?: (payload: SignerPayloadJSON) => Promise; // Signs the given raw payload and returns the result. signRaw?: (raw: SignerPayloadRaw) => Promise; - // TODO: Unclear update?: (id: number, status: H256 | ISubmittableResult) => void; } @@ -205,7 +200,6 @@ export interface SignerPayloadJSON { era: string; // The gensis hash genesisHash: string; - // TODO: Unclear method: string; // The lastest nonce for the given account. nonce: string; @@ -217,9 +211,7 @@ export interface SignerPayloadJSON { tip: string; // The transaction version. transactionVersion: string; - // TODO: Unclear (the extra data to be signed for the transaction?) signedExtensions: string[]; - // TODO: Unclear version: number; } @@ -234,7 +226,6 @@ export interface SignerResult { signature: string; } -// TODO: Clear export interface ISubmittableResult { readonly dispatchError?: DispatchError; readonly dispatchInfo?: DispatchInfo; From 195371413a489f60a492728700020ee7c079b823 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:31:15 +0000 Subject: [PATCH 22/26] add Error types for ISubmittableResult --- PSPs/drafts/psp-52.md | 97 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 20 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 77ded8d..80fca0d 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -46,7 +46,7 @@ app can use to identify the correct extension. Its corresponding value is a datastructure of the following format: ```typescript -export interface InjectedWindowProvider { +interface InjectedWindowProvider { // Start communication process. enable: (origin: string) => Promise; // Version of the extension. @@ -72,7 +72,7 @@ itself, the apps is responsible for that. This structure is the primary way to interact with the extension. ```typescript -export interface InjectedExtension { +interface InjectedExtension { // The name of the extension, e.g. `"polkadot-js"` name: string; // The version of the extension, e.g. `"0.44.1"` @@ -96,7 +96,7 @@ including listening for account changes. The extension is responsible for handling permissions accordingly. ```typescript -export interface InjectedAccounts { +interface InjectedAccounts { // Returns a list of accounts. get: (anyType?: boolean) => Promise; // Subscribers to the list of accounts, useful for @@ -105,9 +105,9 @@ export interface InjectedAccounts { } // Stops the subscription if called. -export type Unsubcall = () => void; +type Unsubcall = () => void; -export interface InjectedAccount { +interface InjectedAccount { // The address of the account. address: string; // The genesis hash of the blockchain (optional). @@ -118,7 +118,7 @@ export interface InjectedAccount { type?: KeypairType; } -export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; +type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum'; ``` #### Metadata @@ -128,14 +128,14 @@ blockchain, but also allows to register new blockchains with the extension. The extension is responsible for handling permissions accordingly. ```typescript -export interface InjectedMetadata { +interface InjectedMetadata { // Retuns a list of know parameters about the blockchain. get: () => Promise; // Provide the extension with information about a blockchain. provide: (definition: MetadataDef) => Promise; } -export interface InjectedMetadataKnown { +interface InjectedMetadataKnown { // The genesis hash of the blockchain. genesisHash: string; // The chain spec version of the blockchain @@ -143,7 +143,7 @@ export interface InjectedMetadataKnown { specVersion: number; } -export interface MetadataDef { +interface MetadataDef { // The name of the blockchain. chain: string; // The genesis hash of the blockchain. @@ -169,7 +169,7 @@ export interface MetadataDef { userExtensions?: Record; } -export type ExtInfo = { +type ExtInfo = { extrinsic: ExtTypes; payload: ExtTypes; } @@ -181,7 +181,7 @@ The signer datastructure allows apps to sign messages with a given account. The extension is responsible for handling permissions accordingly. ```typescript -export interface Signer { +interface Signer { // Signs the given JSON payload and returns the result. signPayload?: (payload: SignerPayloadJSON) => Promise; // Signs the given raw payload and returns the result. @@ -189,7 +189,7 @@ export interface Signer { update?: (id: number, status: H256 | ISubmittableResult) => void; } -export interface SignerPayloadJSON { +interface SignerPayloadJSON { // The address of the account that should sign the message. address: string; // The HEX-encoded block hash. @@ -215,18 +215,18 @@ export interface SignerPayloadJSON { version: number; } -export interface SignerPayloadRaw { +interface SignerPayloadRaw { address: string; type: 'bytes' | 'payload'; } -export interface SignerResult { +interface SignerResult { id: number; // The HEX-encoded signature. signature: string; } -export interface ISubmittableResult { +interface ISubmittableResult { readonly dispatchError?: DispatchError; readonly dispatchInfo?: DispatchInfo; readonly events: EventRecord[]; @@ -254,7 +254,7 @@ maintaining the connection to the RPC server, including handling all requests and forwarding responses to the app. ```typescript -export interface ProviderInterface { +interface ProviderInterface { readonly hasSubscriptions: boolean; readonly isConnected: boolean; readonly stats?: ProviderStats; @@ -268,7 +268,7 @@ export interface ProviderInterface { unsubscribe (type: string, method: string, id: number | string): Promise; } -export interface ProviderStats { +interface ProviderStats { active: { requests: number; subscriptions: number; @@ -284,15 +284,15 @@ export interface ProviderStats { }; } -export interface InjectedProvider extends ProviderInterface { +interface InjectedProvider extends ProviderInterface { listProviders: () => Promise; startProvider: (key: string) => Promise; } -export type ProviderList = Record +type ProviderList = Record // Metadata about a provider -export interface ProviderMeta { +interface ProviderMeta { // Network of the provider network: string; // Light or full node @@ -304,6 +304,63 @@ export interface ProviderMeta { } ``` +##### Error Types + +```typescript +interface DispatchError { + readonly isOther: boolean; + readonly isCannotLookup: boolean; + readonly isBadOrigin: boolean; + readonly isModule: boolean; + readonly asModule: DispatchErrorModule; + readonly isConsumerRemaining: boolean; + readonly isNoProviders: boolean; + readonly isTooManyConsumers: boolean; + readonly isToken: boolean; + readonly asToken: TokenError; + readonly isArithmetic: boolean; + readonly asArithmetic: ArithmeticError; + readonly isTransactional: boolean; + readonly asTransactional: TransactionalError; + readonly isExhausted: boolean; + readonly isCorruption: boolean; + readonly isUnavailable: boolean; + readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional' | 'Exhausted' | 'Corruption' | 'Unavailable'; +} + +interface DispatchErrorModule { + readonly index: u8; + // TODO + readonly error: U8aFixed; +} + +interface TokenError { + readonly isNoFunds: boolean; + readonly isWouldDie: boolean; + readonly isBelowMinimum: boolean; + readonly isCannotCreate: boolean; + readonly isUnknownAsset: boolean; + readonly isFrozen: boolean; + readonly isUnsupported: boolean; + readonly isUnderflow: boolean; + readonly isOverflow: boolean; + readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported' | 'Underflow' | 'Overflow'; +} + +interface ArithmeticError { + readonly isUnderflow: boolean; + readonly isOverflow: boolean; + readonly isDivisionByZero: boolean; + readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero'; +} + +interface TransactionalError extends Enum { + readonly isLimitReached: boolean; + readonly isNoLayer: boolean; + readonly type: 'LimitReached' | 'NoLayer'; +} +``` + ## Copyright This document is placed in the [public domain](https://creativecommons.org/publicdomain/zero/1.0/). From 6afcd0545ba4d14f8f780d7e6a52815584870e33 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:46:34 +0000 Subject: [PATCH 23/26] expand on addiitonal RPC Provider types --- PSPs/drafts/psp-52.md | 74 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 80fca0d..07cd8a5 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -304,7 +304,7 @@ interface ProviderMeta { } ``` -##### Error Types +##### Dispatch Error ```typescript interface DispatchError { @@ -354,13 +354,83 @@ interface ArithmeticError { readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero'; } -interface TransactionalError extends Enum { +interface TransactionalError { readonly isLimitReached: boolean; readonly isNoLayer: boolean; readonly type: 'LimitReached' | 'NoLayer'; } ``` +##### Dispatch Info + +```typescript +interface DispatchInfo { + readonly weight: number; + readonly class: DispatchClass; + readonly paysFee: Pays; +} + +interface DispatchClass { + readonly isNormal: boolean; + readonly isOperational: boolean; + readonly isMandatory: boolean; + readonly type: 'Normal' | 'Operational' | 'Mandatory'; +} + +interface Pays { + readonly isYes: boolean; + readonly isNo: boolean; + readonly type: 'Yes' | 'No'; +} +``` + +##### Event Record + +```typescript +export interface EventRecord { + readonly phase: Phase; + // TODO + readonly event: Event; + // TODO + readonly topics: Vec; +} +``` + +##### Error + +```typescript +interface Error { + name: string; + message: string; + stack?: string; +} +``` + +##### Extrinsic Status + +```typescript +/** @name ExtrinsicStatus */ +export interface ExtrinsicStatus { + readonly isFuture: boolean; + readonly isReady: boolean; + readonly isBroadcast: boolean; + readonly asBroadcast: Vec; + readonly isInBlock: boolean; + readonly asInBlock: Hash; + readonly isRetracted: boolean; + readonly asRetracted: Hash; + readonly isFinalityTimeout: boolean; + readonly asFinalityTimeout: Hash; + readonly isFinalized: boolean; + readonly asFinalized: Hash; + readonly isUsurped: boolean; + readonly asUsurped: Hash; + readonly isDropped: boolean; + readonly isInvalid: boolean; + readonly type: 'Future' | 'Ready' | 'Broadcast' | 'InBlock' | 'Retracted' | 'FinalityTimeout' | 'Finalized' | 'Usurped' | 'Dropped' | 'Invalid'; +} +``` + ## Copyright This document is placed in the [public domain](https://creativecommons.org/publicdomain/zero/1.0/). From 29bfd4ccd5a74e37d6ca100cf861169a3be08522 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:49:01 +0000 Subject: [PATCH 24/26] remove exports --- PSPs/drafts/psp-52.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 07cd8a5..19dcb5c 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -387,7 +387,7 @@ interface Pays { ##### Event Record ```typescript -export interface EventRecord { +interface EventRecord { readonly phase: Phase; // TODO readonly event: Event; @@ -410,7 +410,7 @@ interface Error { ```typescript /** @name ExtrinsicStatus */ -export interface ExtrinsicStatus { +interface ExtrinsicStatus { readonly isFuture: boolean; readonly isReady: boolean; readonly isBroadcast: boolean; From 524b718de106af3cf674bbdf9c2c87210b54ed7b Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:07:00 +0000 Subject: [PATCH 25/26] expand on some types --- PSPs/drafts/psp-52.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 19dcb5c..1553253 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -329,9 +329,8 @@ interface DispatchError { } interface DispatchErrorModule { - readonly index: u8; - // TODO - readonly error: U8aFixed; + readonly index: number; + readonly error: Uint8Array; } interface TokenError { @@ -389,10 +388,21 @@ interface Pays { ```typescript interface EventRecord { readonly phase: Phase; - // TODO + // Events. readonly event: Event; - // TODO - readonly topics: Vec; + // An array of hashes. + readonly topics: Uint8Array[]; +} + +interface Event { + // SCALE encoded events. + readonly data: Record; + // The event Id + readonly index: Uint8Array; + // The Runtime method name. + readonly method: string; + // The Runtime section name. + readonly section: string; } ``` @@ -409,22 +419,21 @@ interface Error { ##### Extrinsic Status ```typescript -/** @name ExtrinsicStatus */ interface ExtrinsicStatus { readonly isFuture: boolean; readonly isReady: boolean; readonly isBroadcast: boolean; - readonly asBroadcast: Vec; + readonly asBroadcast: string[]; readonly isInBlock: boolean; - readonly asInBlock: Hash; + readonly asInBlock: Uint8Array; readonly isRetracted: boolean; - readonly asRetracted: Hash; + readonly asRetracted: Uint8Array; readonly isFinalityTimeout: boolean; - readonly asFinalityTimeout: Hash; + readonly asFinalityTimeout: Uint8Array; readonly isFinalized: boolean; - readonly asFinalized: Hash; + readonly asFinalized: Uint8Array; readonly isUsurped: boolean; - readonly asUsurped: Hash; + readonly asUsurped: Uint8Array; readonly isDropped: boolean; readonly isInvalid: boolean; readonly type: 'Future' | 'Ready' | 'Broadcast' | 'InBlock' | 'Retracted' | 'FinalityTimeout' | 'Finalized' | 'Usurped' | 'Dropped' | 'Invalid'; From b4e446cbfe135a714eda795052533f5cfc5a0457 Mon Sep 17 00:00:00 2001 From: lamafab <42901763+lamafab@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:10:04 +0000 Subject: [PATCH 26/26] add explicit Array --- PSPs/drafts/psp-52.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PSPs/drafts/psp-52.md b/PSPs/drafts/psp-52.md index 1553253..08c29fb 100644 --- a/PSPs/drafts/psp-52.md +++ b/PSPs/drafts/psp-52.md @@ -391,7 +391,7 @@ interface EventRecord { // Events. readonly event: Event; // An array of hashes. - readonly topics: Uint8Array[]; + readonly topics: Array; } interface Event { @@ -423,7 +423,7 @@ interface ExtrinsicStatus { readonly isFuture: boolean; readonly isReady: boolean; readonly isBroadcast: boolean; - readonly asBroadcast: string[]; + readonly asBroadcast: Array; readonly isInBlock: boolean; readonly asInBlock: Uint8Array; readonly isRetracted: boolean;