Open Keith-CY opened 2 years ago
Please do some technical investigation about native messaging(such as custom protocol of electron, native messaging of web extension) between web app and electron app, which enables a web app to communicate with neuron via IPC.
With native messaging, we can empower a web app to track user's assets in watch wallet mode and request a sign for transactions.
Ref: https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app Ref: https://www.electronjs.org/docs/latest/api/protocol Ref: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging
sequenceDiagram
participant web app
participant neuron
participant ckb explorer
web app->>neuron: request xpub key[native messaging]
neuron->>web app: xpub key[opening url]
web app->>ckb explorer: all derived addresses
ckb explorer->>web app: balances, live cells, tx history
web app->>web app: feature-rich UI
sequenceDiagram
participant web app
participant neuron
participant ckb explorer
web app->>ckb explorer: all derived addresses
ckb explorer->>web app: live cells
web app->>web app: generate a tx
web app->>neuron: request a sign and submit[native messaging]
neuron->>web app: tx hash[opening url]
web app->>ckb explorer: tx hash
ckb explorer->>web app: tx status
Workflow of neuron, dapp, and explorer is appended above.
With this workflow, we can provide a powerful web wallet as
The key problem here is the protocol between dapp and neuron, namely, have to transfer message from dapp and neuron.
For now, I get two
nativeMessage
of web extension, which proxy messages from web app to native application, a bit complex but an extra web extension can be delivered together.custom protocol
of electron, seems to be easy, more investigation is needed.How do you think about them @yanguoyu @qiweiii
https://github.com/nervosnetwork/keypering support sign DApp, can we refer to it?
nativeMessage
is really complex, I have no experience with web extension
. But it may support more features. If we want to explore more with web extension, I think it's a good idea. Or should we only use custom protocol
or HTTP protocol
?
nervosnetwork/keypering support sign DApp, can we refer to it?
nativeMessage
is really complex, I have no experience withweb extension
. But it may support more features. If we want to explore more with web extension, I think it's a good idea. Or should we only usecustom protocol
orHTTP protocol
?
Keypering uses RPC for communication because it allows bidirectional messaging and less consideration on safety. But neuron won't expose an endpoint of RPC so native messaging is required.
I also prefer custom protocol
since it's unidirectional natively for safety and custom protocol is supported by the operating system so there is potential to communicate with other applications.
send the witnesses to web app via url
Should change to send the tx_hash to web app via url
?
In addition, how can we cooperate to finish this task?
Should change to send the tx_hash to web app via url?
Yes, tx hash
should be sent back as an index, witnesses
could be sent back when neuron only does the signing work but doesn't commit the tx to ckb node(neuron could disconnect to a node).
In addition, how can we cooperate to finish this task?
We'd better finish research first, including
Once the technical design and product design are done, tasks will be split into chunks, maybe as follows,
handle-custom-protocol controller/service
UI of signing tx from dapp
Until then we can estimate how many works to do and how to cooperate with each other
For protocol between dapp and neuron, limited transaction types
is preferred personally, and I expect other teams to propose their transaction type to enrich neuron.
Use custom protocol like this? It uses https://www.electronjs.org/docs/latest/api/app#appsetasdefaultprotocolclientprotocol-path-args. I found the protocol defined by https://www.electronjs.org/docs/latest/api/protocol seem only use in electron app, but not on the website.
reference: https://shipshape.io/blog/launch-electron-app-from-browser-custom-protocol/
Use custom protocol like this? It uses electronjs.org/docs/latest/api/app#appsetasdefaultprotocolclientprotocol-path-args. I found the protocol defined by electronjs.org/docs/latest/api/protocol seem only use in electron app, but not on the website.
setAsDefaultProtocolClient
protocol.mov
registerFileProtocol
file-protocol.mov reference: shipshape.io/blog/launch-electron-app-from-browser-custom-protocol
The first looks good to me.
After reading the docs I got that protocol module
in electron works within BrowserWindow
and has no effect outside the electron app.
Protocols to have a look at:
APIs required:
APIs:
APIs:
- registerDapp: let the user know how many Dapp has registered and avoid unregistering requests.
good point
APIs:
- registerDapp: let the user know how many Dapp has registered and avoid unregistering requests.
Can setAsDefaultProtocolClient
verify source of requests?
APIs:
- registerDapp: let the user know how many Dapp has registered and avoid unregistering requests.
Can
setAsDefaultProtocolClient
verify source of requests?
We can add verification when opening the app by the default protocol with some parameters.
APIs:
- registerDapp: let the user know how many Dapp has registered and avoid unregistering requests.
Can
setAsDefaultProtocolClient
verify source of requests?We can add verification when opening the app by the default protocol with some parameters.
The source can be fabricated if it's specified by dapps but not by their hosts, say, website A sends a request with a declaration that it's website B, we cannot verify it.
Maybe we can avoid a verification before handling the request, instead, we display the declared source with the request to users, and send the response to the declared source. By this way, the website A disguises itself as website B cannot get the response.
Also, we don't need an extra API registerDapp
to know which dapps are allowed, we can do the registration on their requests' arrival.
The register should be a simple operation to check. Then when calling other APIs, users know it must be from safety Dapp. Or else the user needs to check the current transaction or message is correct, and check them is complex.
And maybe we can't get the host information. we can only get the request URL from the source.
The register should be a simple operation to check. Then when calling other APIs, users know it must be from safety Dapp. Or else the user needs to check the current transaction or message is correct, and check them is complex.
We can check dapp's registration automatically before displaying the tx on their first request of data
sequenceDiagram
autonumber
participant DApp
participant Neuron
DApp->>Neuron: Request data
Neuron->>Neuron: Register DApp
Neuron->>DApp: Respond data
instead of sending register dapp
before request data
sequenceDiagram
autonumber
participant DApp
participant Neuron
DApp->>Neuron: Register DApp
Neuron->>DApp: Registered
DApp->>Neuron: Request data
Neuron->>DApp: Respond data
And maybe we can't get the host information. we can only get the request URL from the source.
It would be enough if the request URL is in event
object provided by the system.
We can check dapp's registration automatically before displaying the tx on their first request of data
How do we check dapp's registration automatically?
we can only get the request URL from the source.
Maybe my description is mistake. I mean we can only get the URL that includes customer protocol and parameters.
eg: <a href="protocol-test://a=1&b=2&c=4">open with neuron</a>
, href is the URL we can get in neuron.
How do we check dapp's registration automatically?
Neuron will have a table recording interacted DApps and marks them registered | blocked
. Once DApp A sends a message to Neuron first time, it cannot be found in the table and Neuron will prompt a registration request to user. If registration is done, Neuron marks the DApp registered
and shows the message to the user. Next time the DApp sends a message to Neuron, it could be found in the table and the message can be handled directly.
Maybe my description is mistake. I mean we can only get the URL that includes customer protocol and parameters. eg: open with neuron, href is the URL we can get in neuron.
The href
can be any data specified by the DApp so it is not a trustful dapp source. Similar to phishing emails, the email sender can declare itself as a well-known organization without validation and requires you to respond with sensitive information, like, a verification code. So almost all confirmation emails include a login URL with authentication for user to check if the URL is correct.
We can do it similarly, with a source URL displaying to the user and sends a response to the URL user has checked, instead of verifying the source of the message.
We can do it similarly, with a source URL displaying to the user and sends a response to the URL user has checked, instead of verifying the source of the message.
yeah, href
is not a trustful Dapp source. And source URL is a good display for the user. But we seem can't to get the source URL.
We can do it similarly, with a source URL displaying to the user and sends a response to the URL user has checked, instead of verifying the source of the message.
yeah,
href
is not a trustful Dapp source. And source URL is a good display for the user. But we seem can't to get the source URL.
I didn't make it clear.
Similar to handling authentication URL in emails, users don't have to care about the email senders.
Neuron accepts the URLs declared in messages, even that they are not consistent with the sources, and sends responses to the declared URLs, instead of verifying the sources of messages.
It's a reply to add verification when opening the app
in https://github.com/Magickbase/neuron-public-issues/issues/23#issuecomment-1151008739 and I may misunderstand the verification
in the comment. I thought it was related to checking if the message source is trustful, but the real purpose may be checking if the declared URL is in the whitelist.
Keypering uses RPC for communication because it allows bidirectional messaging and less consideration on safety. But neuron won't expose an endpoint of RPC so native messaging is required.
I also prefer
custom protocol
since it's unidirectional natively for safety and custom protocol is supported by the operating system so there is potential to communicate with other applications.
keypering
start a local server to accept Dapp request, And it also uses auth for authentication and authorization.
I don't know what do you means bidirectional messaging
. I reconsider a local rpc or HTTP server because it can make API easy. setAsDefaultProtocolClient
can only open Neuron and receive messages from DApp, but it can't send message to DApp.
I have created a repository to test DApp sign with Neuron. I found it seems to have no length limit for open custom protocol. So I think we can send more detailed information to Neuron. And we only send added property back to DApp by callback URL. Then we can start discussing the definition of the interface.
I have written a simple definition of it, it will be perfect later.
request params
{
requestId: uuid
appName: string
type: 'sign_message' | 'sign_transaction'
params: tx | message
callback: string
}
result
{
code: number
err: string
requestId: uuid
result: any
hash: string // for validation message is not lost
}
I have created a repository to test DApp sign with Neuron. I found it seems to have no length limit for open custom protocol. So I think we can send more detailed information to Neuron. And we only send added property back to DApp by callback URL. Then we can start discussing the definition of the interface.
I have written a simple definition of it, it will be perfect later.
request params
{ requestId: uuid appName: string type: 'sign_message' | 'sign_transaction' params: tx | message callback: string }
result
{ code: number err: string requestId: uuid result: any hash: string // for validation message is not lost }
version
field could facilitate API migration;chain type
field for additional verification so users will be told explicitly the signed tx is going to be submitted to the mainnet or testnet. What's more, when the user clicks on sign and send
, it will be stopped if target chain is not the connected one.encodeURIComponent
{
requestId: uuid
appName: string
type: 'sign_message' | 'sign_transaction'
tx?: {
cell_deps: {
out_point: {
tx_hash: string
index: string
}
dep_type: string
}[]
header_deps: string[]
inputs: {
previous_output: {
index: string
tx_hash: string
}
since: string
}[]
outputs: {
capacity: string
lock: {
args: string
code_hash: string
hash_type: 'type' | 'data'
},
type: string | null
}[]
outputs_data: string[]
version: string
}
message?: string
callback: string
version: string
chain: 'mainnet' | 'testnet'
}
encodeURIComponent
{
code: number
err: string
requestId: uuid
result: {
witnesses: string[]
}
hash: string // for validation message is not lost
}
We may work with Nexus team to promote the protocol, but Nexus is not ready yet in the protocol level, this issue will be re-activated later.
Please ping us when you're ready @homura
Reactivate this issue and expand the scope to
blockchain reference/id: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md
account reference: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-10.md
asset reference(sudt/cota…): https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-19.md
sign-in-with-x: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-122.md
Tracked by 3 individual issues: