I see a difference in:
1) Method permissions
- Each method must have a unique identifier - in our case, this is the method name.
2) Method argument type check and validation
- Each argument type should be defined in the global scope and must have a unique identifier, so they can be reused across methods, with a custom
label
(instantiation name). Then, validation rules can also be reused in wallets, web3 libs etc. And custom type UIs can also be reused.
Example
1) eth_sendTransaction
permission:
{
method: 'wallet_requestPermissions',
params: [{
method: 'eth_sendTransaction',
}]
}
2) eth_sendTransaction
permission + argument validation:
First, eth_sendTransaction
has the following interface:
{
type: 'function',
label: 'eth_sendTransaction',
inputs: [
{
type: 'address',
label: 'from'
},
{
type: 'address',
label: 'to'
},
{
type: 'bytes',
label: 'data'
},
],
optionalInputs: [
{
type: 'uint256',
label: 'gas'
},
{
type: 'uint256',
label: 'gasPrice'
},
{
type: 'uint256',
label: 'value'
},
{
type: 'uint256',
label: 'nonce'
}
],
outputs: [
{
type: 'bytes32',
label: 'transactionHash'
},
]
}
If we have standardized interface types, we can have automatic type validation rules & UI components for each method argument on the Wallet UI.
So, the JSON-RPC method can look something like this:
(no need to define types, because they are known by both web3 lib & wallet)
{
method: 'wallet_requestPermissions',
params: [{
method: 'eth_sendTransaction',
params: [
{
name: 'from',
required: true,
customizable: true,
selection: ['0x0001'],
},
{
name: 'to',
required: true,
customizable: false,
selection: ['0x0003', '0x0004'],
},
{
name: 'gas',
required: true,
customizable: false,
selection: [0, 2000000],
},
{
name: 'gasPrice',
required: true,
customizable: true,
selection: [1, 5],
},
{
name: 'value',
required: true,
customizable: true,
selection: [0, 100000000000],
},
{
name: 'data',
required: true,
customizable: false,
},
{
name: 'nonce', // can be used for expiration of permissions
required: false,
customizable: true,
selection: [5, 10],
},
]
}]
}
Where:
-
name
: argument name inside the method -
required
:true
if without it, the entire permission fails. -
customizable
: the user can change type validation rules (increase a range, select another account etc.) -
selection
: the argument value range / selection list (depends on each type; the wallet will show the appropriate UI for the type)
Note:
Permissions on data
(e.g. how many tokens to approve, etc.) are tricky right now. If the above general mechanism (or similar) will be considered, I have some ideas about how to tackle the data
problem in a general way, if people are interested.
Conclusion
I am suggesting:
- general permissions + argument validation based on types for any web3 method; not just on handpicked ones
- a dApp should expose all web3 methods that it will use (calls & transactions)
- the wallet should be able to show the user all the web3 methods that the dApp uses/has used (it can be in the Advanced section, because this can be overwhelming); transparency + the above Infura DDoS example
Very good topic.